i have provided webhook.site url in google cloud pub/sub to receive gmail box changes. While receiving the post request from pubsub, it is not including the history which has changed in mailbox.
I have implemented google watch to track history changes in my node app :
const watchGmail = async (tenantUserId) => {
try {
const tenantUser = await setOAuth2Credentials(tenantUserId);
const gmail = google.gmail({ version: "v1", auth: oAuth2Client });
const watchResponse = await gmail.users.watch({
userId: tenantUser.googleData.profile_id,
requestBody: {
topicName: "projects/nodeauth-429506/topics/pubsubtopic",
},
});
logger.info("Gmail API watch request response:", watchResponse.data);
return watchResponse.data;
} catch (error) {
logger.error("Error setting up Gmail watch:", error);
throw new ApiError(
httpStatus.INTERNAL_SERVER_ERROR,
"Error setting up Gmail watch"
);
}
};```
after pubsub push notification data encode base64, this function is to receive pubsub push notification will process the data like this:
const handleEmailReplies = async (emailAddress, historyId) => {
try {
const db = new Db("tenantusers");
const tenantUserRecord = await db.findOne({ email: emailAddress, });
if (!tenantUserRecord) { throw new ApiError(httpStatus.NOT_FOUND, "User not found"); }
const tenantUser = await setOAuth2Credentials(tenantUserRecord._id);
const gmail = google.gmail({ version: "v1", auth: oAuth2Client });
const historyResponse = await gmail.users.history.list({
userId: tenantUser.googleData.profile_id,
startHistoryId: historyId,
}); //arayy of history
// logger.info("historyResponse:" + JSON.stringify(historyResponse.data, null, 6))
if (!historyResponse.data.history) {
logger.info("No history is there to update from this push notification")
return "No history is there to update from this push notification";
}
const histories = historyResponse.data.history || [];
const savedReplies = [];
for (const history of histories) {
const historyMessages = history.messages || [];
for (const message of historyMessages) {
const messageDetails = await gmail.users.messages.get({
userId: tenantUser.googleData.profile_id,
id: message.id,
});
// logger.info("histories:"+ JSON.stringify(messageDetails, null, 6))
// Extract In-Reply-To header
const inReplyToHeader = extractHeader(
messageDetails.data.payload.headers,
"In-Reply-To"
);
if (inReplyToHeader == undefined || inReplyToHeader == null) return "This push notification was for new mail initiated!";
// Map In-Reply-To header to messageId
const emailDb = new Db("emails");
const originalEmail = await emailDb.findOne({
tenantUserId: new ObjectId(tenantUser._id),
messages: {
$elemMatch: {
messageIdHeader: inReplyToHeader,
},
},
});
if (originalEmail) {
// Check if the reply message is already saved
const isReplyAlreadySaved = originalEmail.messages.some(
(msg) => msg.messageId === messageDetails.data.id
);
if (!isReplyAlreadySaved) {
const emailData = {
messageId: messageDetails.data.id,
messageIdHeader: extractHeader(
messageDetails.data.payload.headers,
"Message-ID"
),
from: extractEmailAddress(extractHeader(messageDetails.data.payload.headers, "From")),
to: extractAddressHeaders(
messageDetails.data.payload.headers,
"To"
),
cc: extractAddressHeaders(
messageDetails.data.payload.headers,
"Cc"
),
bcc: extractAddressHeaders(
messageDetails.data.payload.headers,
"Bcc"
),
subject: extractHeader(
messageDetails.data.payload.headers,
"Subject"
),
message: extractBody(messageDetails.data.payload),
labelId: messageDetails.data.labelIds,
timestamp: getTimestamp(),
inReplyTo: inReplyToHeader || null,
};
await emailDb.updateOne(
{
threadId: messageDetails.data.threadId,
tenantUserId: new ObjectId(tenantUser._id),
},
{
$push: { messages: emailData },
},
{ upsert: true }
);
savedReplies.push(emailData);
logger.info(
`Reply with messageId ${emailData.messageId} inserted into database.`
);
} else {
logger.info(
`Skipping duplicate reply with messageId ${messageDetails.data.id}.`
);
}
} else {
logger.info(
`Skipping message with threadId ${messageDetails.data.threadId} as it does not exist in the database.`
);
}
}
}
return savedReplies;
}
catch (error) {
logger.error("Error saving email replies history:", error);
throw new ApiError( httpStatus.INTERNAL_SERVER_ERROR, "Error saving email replies history" ); } };```
While debugging the first notification receiving after any changes in mail box is not contains the history within it and when another change happens the previous push notification includes the history data.
I want to achieve if any push notification comes it should includes the recent history.
Preetam Singh is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.