How to tell if an email sent via Gmail REST API has bounced?

Messages that gets bounced when sent through the Gmail API gets a response from the mailer deamon ([email protected]). You could continually check the user's messages to see if a new message from the daemon has been received.

Make sure to store the timestamp in seconds since your last check, so you don't get any nasty duplicates next time around.

query = from:[email protected] after:<TIME_SINCE_EPOCH_IN_SECONDS>

GET https://www.googleapis.com/gmail/v1/users/me/messages?q=from%3Amailer-daemon%40googlemail.com+after%3A1437055051&access_token={YOUR_API_KEY}

Response:

{
 "messages": [
  {
   "id": "14e97f7ed03b7e88",
   "threadId": "14e97f7ea9b794a4"
  },
 ]
}

I got a bounce! Let's fetch the entire mail and decode it and get the Message-ID you were alluding too.

GET https://www.googleapis.com/gmail/v1/users/me/messages/14e97f7ed03b7e88?fields=payload%2Fbody%2Fdata&access_token={YOUR_API_KEY}

Response:

{
 "payload": {
  "body": {
   "data": "RGVsA0K..."
  }
 }
}

Converting the mail to regular base64 from its URL safe version (replace all "-" with "+" and "_" with "/"), and base64-decoding it we get:

atob("RGVsA0K...".replace(/\-/g, '+').replace(/\_/g, '/'));

Decoded mail:

"Delivery to the following recipient failed permanently:

     [email protected]

Technical details of permanent failure: 
DNS Error: Address resolution of sadsads.asdsad. failed: Domain name not found

----- Original message -----

.
.
.

Received: from 292824132082.apps.googleusercontent.com named unknown by
 gmailapi.google.com with HTTPREST; Thu, 16 Jul 2015 13:44:43 -0400
from: [email protected]
Date: Thu, 16 Jul 2015 13:44:43 -0400
Message-ID: <[email protected]>
Subject: Subject Text
To: [email protected]
Content-Type: text/plain; charset=UTF-8

The actual message text goes here

Here we have the Message-ID! Let's get the bounced email!

query = rfc822msgid:<[email protected]>;

GET https://www.googleapis.com/gmail/v1/users/me/messages?q=rfc822msgid%3A%3CCADsZLRzOs1wT4B5pgR7oHHdbjkQhuaCQQs8CEckhLwVw73QFEQ%40mail.gmail.com%3E&key={YOUR_API_KEY}

Response:

{
 "messages": [
  {
   "id": "14e97f7ea9b794a4", // <-- Here is the message that bounced!
   "threadId": "14e97f7ea9b794a4"
  }
 ],
}

When you send a message via

service.users().messages().send(userId, message).execute();

It will return a Message. You can use its threadId to check if you got any reply to that message.

Here's an easy way of checking if it bounced (give a 1 second delay after sending):

public static boolean isBounced(Gmail service, String threadId) throws IOException {
    List<Message> list = service.users().messages().list("me")
                        .setQ("[email protected]")
                       .execute().getMessages();

    return list.stream().anyMatch(msg -> msg.getThreadId().equals(threadId));
}