Sendgrid-csharp: Is it safe to rely on the matching of X-Message-Id and sg_message_id prefix

Created on 15 Jun 2021  路  3Comments  路  Source: sendgrid/sendgrid-csharp

Hello,

When sending an email through SendGrid api, we get in the response headers an X-Message-Id, let's say for example : "R14554qsAGSkiKYYviJN34DGA". I store this ID somewhere, let's say for example in a database. Then when an event is fired to my Webhook i don't have any X-Message-Id to make the link between the mail i have sent and the event source email. But i have noticed that i have "sg_message_id" and a "smtp-id" that always (?) start with my X-Message-Id.

So the question i have for you is : Is it safe to rely on that matching ? So in my endpoint, when an event is fired, i would check if the sg_message_id (or smtp-id) field starts with the X-Message-Id i have saved just before ?

If not, what's the best practice to go with so i can associate an Email i have sent to a given Event.

Thanks.

waiting for feedback question

Most helpful comment

@shiglet I wrote a .NET client for SendGrid's API called StrongGrid which contains, among other things, a parser for webhook events.

My parser returns an enumeration of strongly typed "Event" objects, each with a so called "internal" identifier which is only meaningful to SendGrid, and a "MessageId" property which can be used to correlate the email associated with the event. Here's a code sample that shows how you can use StrongGrid to parse your events:

namespace WebApplication1.Controllers
{
    [Route("api/SendGridWebhooks")]
    public class SendGridController : Controller
    {
        [HttpPost]
        [Route("Events")]
        public async Task<IActionResult> ReceiveEvents()
        {
            var parser = new WebhookParser();
            var events = await parser.ParseWebhookEventsAsync(Request.Body).ConfigureAwait(false);

            foreach (var event in events)
            {
                // This "internal" identifier is useful to SendGrid for debugging and troubleshooting purposes.
                // It contains the message Id and information about where the mail was processed concatenated together.
                // However, developers should NOT use this value to correlate a webhook event with the email that triggered this event.
                var internalMessageId = event.InternalMessageId;

                // This is the value that developers should use to identify the email associated with this event.
                var messageId = event.MessageId
            }

            return Ok();
        }
    }
}

My (humble) recommendation would be that you should use this ready-made library to parse the webhook events rather than reinvent the wheel and parse it manually but in case you're curious, the logic to extract the message identifier is actually quite simple:

A typical "internal" id looks like this: 14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.000000000000000000000 (this example is taken straight from SendGrid's documentation). Anything before .filter is the value you are looking for and everything after .filter is only meaningful to SendGrid's engineering (evidently it contains details about how their system processed your email).

Hope this helps.

All 3 comments

@shiglet I wrote a .NET client for SendGrid's API called StrongGrid which contains, among other things, a parser for webhook events.

My parser returns an enumeration of strongly typed "Event" objects, each with a so called "internal" identifier which is only meaningful to SendGrid, and a "MessageId" property which can be used to correlate the email associated with the event. Here's a code sample that shows how you can use StrongGrid to parse your events:

namespace WebApplication1.Controllers
{
    [Route("api/SendGridWebhooks")]
    public class SendGridController : Controller
    {
        [HttpPost]
        [Route("Events")]
        public async Task<IActionResult> ReceiveEvents()
        {
            var parser = new WebhookParser();
            var events = await parser.ParseWebhookEventsAsync(Request.Body).ConfigureAwait(false);

            foreach (var event in events)
            {
                // This "internal" identifier is useful to SendGrid for debugging and troubleshooting purposes.
                // It contains the message Id and information about where the mail was processed concatenated together.
                // However, developers should NOT use this value to correlate a webhook event with the email that triggered this event.
                var internalMessageId = event.InternalMessageId;

                // This is the value that developers should use to identify the email associated with this event.
                var messageId = event.MessageId
            }

            return Ok();
        }
    }
}

My (humble) recommendation would be that you should use this ready-made library to parse the webhook events rather than reinvent the wheel and parse it manually but in case you're curious, the logic to extract the message identifier is actually quite simple:

A typical "internal" id looks like this: 14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.000000000000000000000 (this example is taken straight from SendGrid's documentation). Anything before .filter is the value you are looking for and everything after .filter is only meaningful to SendGrid's engineering (evidently it contains details about how their system processed your email).

Hope this helps.

Thank you @Jericho!

@shiglet,

Please let us know if you require further assistance, additionally, here is an example based on Jericho's work.

With best regards,

Elmer

Thank you guys !

Gonna look for that, it seems to do what i need.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

clairernovotny picture clairernovotny  路  4Comments

mhagesfeld picture mhagesfeld  路  3Comments

loganwasif005 picture loganwasif005  路  3Comments

thinkingserious picture thinkingserious  路  4Comments

ivivanov picture ivivanov  路  3Comments