Reputation: 59
I want to get live SendGrid webhook events in .NET 4.8, how to do that in C# .NET?
[HttpPost("Sendgridwh")]
public async Task<ActionResult> Sendgridwh([FromBody] object[] eventList)
{
var json = JsonConvert.SerializeObject(eventList);
var parser = new WebhookParser();
var events = parser.ParseEvents(json);
// this is my custom method
await IEmailTrackingService.EmailActivityFromWebhook(events);
return new OkResult();
}
I have use EmailActivityFromWebhook(events) method in my controller & it was declared in my service file which gets/post data on/from SendGrid webhook & now I was blocked at EmailActivityFromWebhook(events) method that I don't know how exactly do code to post/get data on/from webhook in this EmailActivityFromWebhook(events) method. I want to get live events like Engagement events & Delivery events of last sent mail. Does anyone know how this could be done? Thanks for your time.
Upvotes: 3
Views: 2707
Reputation: 7164
I'm not sure what you're doing inside of EmailActivityFromWebhook
, so I can't help you with that.
Here's a sample to receive the SendGrid events, and then use JSON.NET to parse the JSON Array, and extract the values you want.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Web.Mvc;
namespace SendGridEvents.Controllers
{
public class SendGridController : Controller
{
[HttpPost()]
[Route("SendGridEvent")]
public async Task<ActionResult> Event()
{
JArray events;
using (var jsonReader = new JsonTextReader(new StreamReader(Request.InputStream)))
{
var serializer = new JsonSerializer();
events = serializer.Deserialize<JArray>(jsonReader);
}
foreach (JObject sendGridEvent in events){
var eventId = sendGridEvent["sg_event_id"];
var eventType = sendGridEvent["event"];
var email = sendGridEvent["email"];
Debug.WriteLine($"Event ID: {eventId}");
Debug.WriteLine($"Event Type: {eventType}");
Debug.WriteLine($"Email: {email}");
}
return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
}
}
}
You could also use strongly-typed objects and have MVC bind the JSON to objects, but it gets a little complicated because depending on the event
JSON property, there may be more or less properties in the JSON object. (See Event Webhook docs for different event type JSON)
By using JSON.NET with a JArray
and then inspecting individual JObject
's, you can extract the event
property and use different logic as necessary by your requirements.
If this doesn't help, let us know what you're looking for.
Update 1: OP clarified they use ASP.NET Core
Here's the ASP.NET Core equivalent using System.Text.Json
instead of JSON.NET:
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
namespace SendGridEvents.Controllers;
public class SendGridController : Controller
{
private readonly ILogger<SendGridController> logger;
public SendGridController(ILogger<SendGridController> logger)
{
this.logger = logger;
}
[HttpPost("SendGridEvent")]
public async Task<ActionResult> Event()
{
using (JsonDocument document = await JsonDocument.ParseAsync(Request.Body))
{
foreach (JsonElement sendGridEvent in document.RootElement.EnumerateArray())
{
var eventId = sendGridEvent.GetProperty("sg_event_id").GetString();
var eventType = sendGridEvent.GetProperty("event").GetString();
var email = sendGridEvent.GetProperty("email").GetString();
logger.LogInformation("Event ID: {EventId}", eventId);
logger.LogInformation("Event Type: {EventType}", eventType);
logger.LogInformation("Email: {Email}", email);
}
}
return Ok();
}
}
With ASP.NET Core you can even use parameter binding which makes this simpler:
[HttpPost("SendGridEvent")]
public ActionResult Event([FromBody]JsonDocument document)
{
foreach (JsonElement sendGridEvent in document.RootElement.EnumerateArray())
{
var eventId = sendGridEvent.GetProperty("sg_event_id").GetString();
var eventType = sendGridEvent.GetProperty("event").GetString();
var email = sendGridEvent.GetProperty("email").GetString();
logger.LogInformation("Event ID: {EventId}", eventId);
logger.LogInformation("Event Type: {EventType}", eventType);
logger.LogInformation("Email: {Email}", email);
}
return Ok();
}
You can still bind this JSON to an array or list of strongly-typed objects if you'd like, but with the same caveats as mentioned before.
Upvotes: 4