Webhooks

Using webhooks with EmailEngine

Event list

These are the available events that EmailEngine sends webhooks for.

Type Name Description
messageNew New Email A new email is found from a folder (new email)
messageDeleted Deleted Message A previously present email is not found from a folder (deleted email)
messageUpdated Flag Change Email flags are changed (flag change)
messageMissing Missing Message A message that should exist, was not found. Indicates syncing errors.
messageSent Message Accepted Queued email is accepted by the MTA server (message accepted)
messageDeliveryError SMTP error EmailEngine failed to send an email to the SMTP server. This action might be retried. (SMTP error)
messageFailed Message Bounced EmailEngine fails to deliver a queued email to the MTA server (message bounced)
messageBounce Bounce Received Bounce response email is received (bounce received)
messageComplaint Complaint received FBL complaint was detected
mailboxReset Mailbox Reset UIDValidity for a folder changes (mailbox reset)
mailboxDeleted Folder Deleted A previously present folder is not found (folder deleted)
mailboxNew New Folder A new folder is found (new folder)
authenticationError Authentication Failure EmailEngine fails to authenticate an email account
authenticationSuccess Authentication Success An email account is successfully authenticated
connectError Connection Failure EmailEngine fails to establish a connection to an email server
accountAdded Account added a new email account was registered with EmailEngine
accountInitialized Account initialized Account has been connected and the first sync is completed
accountDeleted Account deleted an email account was removed from EmailEngine
trackOpen Email open tracked recipient opened an email
trackClick Link click tracked recipient clicked on a link

messageNew

A new message was added to the folder. Both new/received messages and messages moved from one folder another generate this event.

To distinguish new messages from copied messages, check if the path value is INBOX or, in case of Gmail/GSuite accounts, data.labels array includes \Inbox.

The following example has extra options turned on:

  • MIME-Headers header is included in the response. Default would be not to include extra headers.
  • Content text is enabled and the max text size is set to 1024 bytes. Default would be to not include content text in the payload.
{
  "account": "pangalink",
  "date": "2022-01-17T11:44:46.934Z",
  "path": "[Gmail]/All Mail",
  "specialUse": "\\All",
  "event": "messageNew",
  "data": {
    "id": "AAAAAQAANJc",
    "uid": 13463,
    "emailId": "1722202068227089305",
    "threadId": "1722202068227089305",
    "date": "2022-01-17T11:44:28.000Z",
    "unseen": true,
    "size": 35795,
    "subject": "Test message 🤔",
    "from": {
      "name": "Andris Reinman",
      "address": "andris.reinman@gmail.com"
    },
    "replyTo": {
      "name": "Andris Reinman",
      "address": "andris.reinman@gmail.com"
    },
    "sender": {
      "name": "Andris Reinman",
      "address": "andris.reinman@gmail.com"
    },
    "to": [
      {
        "name": "",
        "address": "no-reply@pangalink.net"
      }
    ],
    "attachments": [
      {
        "id": "AAAAAQAANJcy",
        "contentType": "image/png",
        "encodedSize": 30436,
        "filename": "grinning-face_1f600.png",
        "embedded": false,
        "inline": false,
        "contentId": "<f_kyimd6xt0>"
      }
    ],
    "messageId": "<CAPacwgwFgoB=XWR=V9i2AjYgdhrEG6C5e6PtGGDYmVvm8inxJA@mail.gmail.com>",
    "labels": [
      "\\Important",
      "\\Inbox"
    ],
    "headers": {
      "mime-version": [
        "1.0"
      ]
    },
    "text": {
      "id": "AAAAAQAANJeTkaMxLjGRozEuMpA",
      "encodedSize": {
        "plain": 88,
        "html": 136
      },
      "plain": "This is a test message that should generate a *webhook*.\n\nIt also has an attachment.\n",
      "html": "<div dir=\"ltr\">This is a test message that should generate a <i>webhook</i>.<div><br></div><div>It also has an attachment.</div></div>\n",
      "hasMore": false
    },
    "seemsLikeNew": false
  }
}
  • seemsLikeNew indicates if EmailEngine has seen this message before or not. If you receive a new message, it's set to true. If you move that message to Trash and then move it back to Inbox, the value will be reported as false. NB! false positives and negatives might occur as seemsLikeNew is a derived estimate.

Gmail tab category

Gmail sorts incoming emails into different categories like promotions, social, and primary and displays emails under these category tabs. For IMAP, all these emails still look like regular INBOX folder emails. EmailEngine can resolve the category of incoming emails and include this information in the payload of the messageNew webhook.

Category resolving is not enabled by default. To enable it, navigate to Configuration -> Service, and then to the Labs section. Mark the "Resolve Gmail categories" checkbox, and save the settings.

Now, whenever an email lands in the Inbox of an email account that EmailEngine tracks, the messageNew webhook for that email will include a property called category, and the value is one of the following: social, promotions, updates, forums, and primary.

messageDeleted

A message was deleted from a folder. This happens when a message was either deleted or moved to another folder.

{
  "account": "pangalink",
  "date": "2022-01-17T11:54:02.089Z",
  "path": "[Gmail]/All Mail",
  "specialUse": "\\All",
  "event": "messageDeleted",
  "data": {
    "id": "AAAAAQAANJc",
    "uid": 13463
  }
}

messageUpdated

This event is fired when a change is detected with a message. Most commonly, when the user marks a message as read or unread.

{
  "account": "pangalink",
  "date": "2022-01-17T11:56:13.146Z",
  "path": "[Gmail]/All Mail",
  "specialUse": "\\All",
  "event": "messageUpdated",
  "data": {
    "id": "AAAAAQAANJY",
    "uid": 13462,
    "changes": {
      "flags": {
        "added": [
          "\\Seen"
        ]
      }
    }
  }
}

messageSent

EmailEngine managed to deliver the email to the MTA server. In this case, the webhooks should arrive pretty much immediately.

{
  "account": "example",
  "date": "2021-12-23T10:32:39.499Z",
  "event": "messageSent",
  "data": {
    "messageId": "<a00576bd-f757-10c7-26b8-885d7bbd9e83@ekiri.ee>",
    "response": "250 2.0.0 Ok: queued as 5755482356",
    "envelope": {
      "from": "andris@ekiri.ee",
      "to": [
        "andris@ethereal.email"
      ]
    }
  }
}

messageFailed

EmailEngine retries sending multiple times, so receiving the webhook takes a long time (EmailEngine sends the failure webhook once it has given up retrying the message).

{
  "account": "example",
  "date": "2021-12-23T11:58:50.181Z",
  "event": "messageFailed",
  "data": {
    "messageId": "<97ac5d9a-93c7-104b-8d26-6b25f8d644ec@ekiri.ee>",
    "queueId": "610c2c93e608bd37",
    "error": "Error: Invalid login: 535 5.7.8 Error: authentication failed: "
  }
}

messageComplaint

EmailEngine found an ARF formatted FBL report from the Inbox folder. If such an email is found, then EmailEngine parses it and posts parsed information as the messageComplaint webhook.

{
  "serviceUrl": "http://127.0.0.1:3000",
  "account": "example",
  "date": "2022-09-27T12:33:42.635Z",
  "event": "messageComplaint",
  "data": {
    "complaintMessage": "AAAAAQAABvE",
    "arf": {
      "source": "Hotmail",
      "feedbackType": "abuse",
      "abuseType": "complaint",
      "originalRcptTo": [
        "recipient@hotmail.co.uk"
      ],
      "sourceIp": "1.2.3.4",
      "arrivalDate": "2021-10-22T13:04:36.017Z"
    },
    "headers": {
      "messageId": "<67d3846d-b819-9c54-5053-a81fdc432425@example.com>",
      "from": "user@example.com",
      "to": [
        "recipient@hotmail.co.uk"
      ],
      "subject": "Hello world",
      "date": "2021-10-22T16:04:33.000Z"
    }
  }
}

NB! included fields depend on the reporting server. Sometimes important information like the source email Message-ID value might be missing.

messageDeliveryError

EmailEngine retries sending multiple times. For every failing try a messageDeliveryError is sent.

{
  "serviceUrl": "http://127.0.0.1:3000",
  "account": "example",
  "date": "2022-09-14T15:07:35.832Z",
  "event": "messageDeliveryError",
  "data": {
    "queueId": "1833c8a88a86109a1bf",
    "envelope": {
      "from": "andris@ekiri.ee",
      "to": [
        "andris@ethereal.email"
      ]
    },
    "messageId": "<29e26263-7125-ff56-4f80-83a5cf737d5e@ekiri.ee>",
    "error": "400 Message Not Accepted",
    "errorCode": "EPROTOCOL",
    "smtpResponseCode": 400,
    "job": {
      "attemptsMade": 1,
      "attempts": 10,
      "nextAttempt": "2022-09-14T15:07:45.465Z"
    }
  }
}

messageBounce

A new bounce response message was found from the account. The bounce data includes messageId value but no id value, so you have to look up the bounced message using the Message-ID header value.

If multiple recipients for the same message bounce, you get a separate bounce event for each of these recipients.

{
  "account": "pangalink",
  "date": "2021-11-28T10:17:29.728Z",
  "event": "messageBounce",
  "data": {
    "bounceMessage": "AAAAAQAABWw",
    "recipient": "failed.recipient@example.com",
    "action": "failed",
    "response": {
      "source": "smtp",
      "message": "550 5.1.1 <failed.recipient@example.com>: Recipient address rejected: User unknown in relay recipient table",
      "status": "5.1.1"
    },
    "mta": "mx.example.com",
    "queueId": "BFC608226A",
    "messageId": "<4dbe4a40f37e9c2ba5b25912bc7c8997@example.com>"
  }
}

Some fields might be missing from a bounce webhook depending on how EmailEngine can parse the information out from the bounce.

trackOpen

Email client loaded the open tracking beacon. This only works if the email client loads external images. There might be false positives, for example, when a web-based email client caches linked images.

{
  "account": "example",
  "date": "2022-03-24T08:28:32.992Z",
  "event": "trackOpen",
  "data": {
    "messageId": "<2d4696ea-cb47-7af4-0bc3-81ea7a8008be@example.com>",
    "remoteAddress": "1.2.3.4",
    "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36"
  }
}

trackClick

A tracked link was clicked. False positives might occur when security software scans links in an incoming email.

{
  "account": "example",
  "date": "2022-03-24T08:27:24.572Z",
  "event": "trackClick",
  "data": {
    "messageId": "<49b6cdb1-5d43-e100-0833-bd61867b7bb3@example.com>",
    "url": "https://google.com/",
    "remoteAddress": "1.2.3.4",
    "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36"
  }
}