Issue:
The only filter you can apply to Gmail Push Notifications is which label/s to retrieve notifications from, as can be seen here. Because of this, the filtering of messages depending on (1) who sent the message, (2) the email subject and (3) whether the email has a certain PDF attachment cannot be done at this stage, but after receiving the notifications. Luckily, though, there is no need to look for these messages manually, you can code your application to do that for you.
Workflow:
- Step #1. Set notifications for all INBOX and retrieve startHistoryId: As was said before, you have to receive notifications for all INBOX, since there is no more specific filter available. A call to Users: watch, providing INBOX
in the labelIds
field and the topic you created in topicName
, will effectively configure the notifications. The response to watch
has this shape:
{
historyId: 1234567890
expiration: 1431990098200
}
Where historyId
refers to the mailbox’s current state. Let’s store it somewhere, and call it startHistoryId
.
- Step #2. Get INBOX changes: After completing step 1, whenever there is a change in your INBOX
, your application will receive a notification message describing the change. Whenever a notification is received, you want to get information about the specific changes made to the INBOX
, and to achieve that, you should call history.list().
That is to say, your application should call history.list()
every time a notification is received. Now, you want to get changes since last time, and that’s why you should provide the historyId
retrieved in step 1 as the parameter startHistoryId
. If you want to only retrieve new messages (and not deletions, or label edition/removal), you can set historyTypes
to messageAdded
. The request could be like this:
{
userId: “your-email-address”,
historyTypes: “messageAdded”,
startHistoryId: “your-start-history-id”
}
As a response, you’ll get something like this:
{
"history": [
{
"id": unsigned long,
"messages": [
users.messages Resource
],
"messagesAdded": [
{
"message": users.messages Resource
}
]
}
],
"nextPageToken": string,
"historyId": unsigned long
}
Here, you should retrieve historyId, which will be used as startHistoryId
the next time history.list()
is called, and messagesAdded, which contains the IDs
of the new messages you want to look for (only ID
and threadId
seem to be populated).
- Step 3. Filtering messages: Now you have the list of message IDs
that have changed since last time (messagesAdded
), and you want to know which of them match your criteria. To know that, you’ll have to iterate through all IDs
in messagesAdded
and call Users.messages: get for each ID
. This will return the corresponding message resource. For each message, you’ll have to check whether the criteria are met:
Sender email: inside the resource, access the headers
(message[“payload”][“headers”]), and loop through them, looking for the one whose name
is From
. You have to check whether the corresponding value
is the email you’re looking for.
Subject: as in step (a), access the headers
and look for the header whose name
is Subject
. The corresponding value
is the email subject. Check whether it starts with [Important]
.
Attachment: you’ll have to look for the email attachments in message[“payload”][“parts”]
. The process is a bit more complicated, but see, for example, this related question.
Reference:
Gmail API: Push Notifications