<commit_before>﻿<%@ WebHandler Language="C#" Class="SendGrid" %>
using System;
using System.Web;
using System.IO;
using System.Text;
using Rock;
using Rock.Model;
using Rock.Workflow.Action;
using Sendgrid.Webhooks.Events;

public class SendGrid : IHttpHandler
{
    private HttpRequest _request;
    private HttpResponse _response;
    private int _transactionCount;

    public void ProcessRequest(HttpContext context)
    {
        _request = context.Request;
        _response = context.Response;

        _response.ContentType = "text/plain";

        if (!(_request.HttpMethod == "POST" && _request.ContentType.Contains("application/json")))
        {
            _response.Write("Invalid request type.");
            return;
        }

        if (_request != null)
        {
            string postedData = GetDocumentContents(_request);

            var rockContext = new Rock.Data.RockContext();
            
            var communicationRecipientService = new CommunicationRecipientService(rockContext);
            var communicationRecipientActivityService = new CommunicationRecipientActivityService(rockContext);

            var timeZoneInfo = RockDateTime.OrgTimeZoneInfo;
            var parser = new Sendgrid.Webhooks.Service.WebhookParser();
            var events = parser.ParseEvents(postedData);

            if (events != null)
            {
                int unsavedCommunicationCount = 0;
                foreach (var item in events)
                {
                    _transactionCount++;
                    unsavedCommunicationCount++;
                    // Process a SendEmailWithEvents workflow action 
                    if (item.UniqueParameters.ContainsKey("workflow_action_guid"))
                    {
                        var actionGuid = item.UniqueParameters["workflow_action_guid"].AsGuidOrNull();
                        string status = string.Empty;
                        switch (item.EventType)
                        {
                            case WebhookEventType.Delivered: status = SendEmailWithEvents.SENT_STATUS; break;
                            case WebhookEventType.Open: status = SendEmailWithEvents.OPENED_STATUS; break;
                            case WebhookEventType.Click: status = SendEmailWithEvents.CLICKED_STATUS; break;
                            case WebhookEventType.Dropped:
                            case WebhookEventType.SpamReport:
                            case WebhookEventType.Unsubscribe:
                            case WebhookEventType.Group_Unsubscribe:
                            case WebhookEventType.Bounce: status = SendEmailWithEvents.FAILED_STATUS; break;

                        }

                        if (actionGuid != null && !string.IsNullOrWhiteSpace(status))
                        {
                            SendEmailWithEvents.UpdateEmailStatus(actionGuid.Value, status, item.EventType.ConvertToString().SplitCase(), rockContext, true);
                        }
                    }

                    // Process a regular communication recipient  
                    if (item.UniqueParameters.ContainsKey("communication_recipient_guid"))
                    {
                        Guid communicationRecipientGuid;
                        if (Guid.TryParse(item.UniqueParameters["communication_recipient_guid"], out communicationRecipientGuid))
                        {
                            var communicationRecipient = communicationRecipientService.Get(communicationRecipientGuid);

                            if (communicationRecipient != null)
                            {
                                item.TimeStamp = TimeZoneInfo.ConvertTime(item.TimeStamp, timeZoneInfo);
                                switch (item.EventType)
                                {
                                    case WebhookEventType.Delivered:
                                        communicationRecipient.Status = CommunicationRecipientStatus.Delivered;
                                        communicationRecipient.StatusNote =
                                            string.Format("Confirmed delivered by SendGrid at {0}",
                                                item.TimeStamp.ToString("o"));
                                        break;
                                    case WebhookEventType.Open:
                                        communicationRecipient.Status = CommunicationRecipientStatus.Opened;
                                        var openEvent = item as OpenEvent;
                                        if (openEvent != null)
                                        {
                                            communicationRecipient.OpenedDateTime = openEvent.TimeStamp;
                                            communicationRecipient.OpenedClient = openEvent.UserAgent.Truncate(200) ??
                                                                                  "Unknown";
                                            var openActivity = new CommunicationRecipientActivity
                                            {
                                                CommunicationRecipientId = communicationRecipient.Id, 
                                                ActivityType = "Opened",
                                                ActivityDateTime = item.TimeStamp,
                                                ActivityDetail =
                                                    string.Format("Opened from {0} ({1})", openEvent.UserAgent ?? "unknown",
                                                        openEvent.Ip).Truncate(2200)
                                            };
                                            communicationRecipientActivityService.Add(openActivity);
                                        }
                                        break;
                                    case WebhookEventType.Click:
                                        var clickActivity = new CommunicationRecipientActivity
                                        {
                                            CommunicationRecipientId = communicationRecipient.Id, 
                                            ActivityType = "Click"
                                        };
                                        var clickEvent = item as ClickEvent;
                                        clickActivity.ActivityDateTime = item.TimeStamp;
                                        if (clickEvent != null)
                                        {
                                            clickActivity.ActivityDetail =
                                                string.Format("Clicked the address {0} from {1} using {2}", clickEvent.Url,
                                                    clickEvent.Ip, clickEvent.UserAgent).Truncate(2200);
                                        }
                                        CommunicationRecipientActivityService.Add(clickActivity);
                                        break;
                                    case WebhookEventType.Dropped:
                                        var dropEvent = item as DroppedEvent;
                                        communicationRecipient.Status = CommunicationRecipientStatus.Failed;
                                        if (dropEvent != null)
                                        {
                                            communicationRecipient.StatusNote = string.Format("{0} by SendGrid at {1}", dropEvent.Reason, dropEvent.TimeStamp.ToString("o"));
                                        }
                                        break;
                                    case WebhookEventType.Bounce:
                                        var bounceEvent = item as BounceEvent;
                                        communicationRecipient.Status = CommunicationRecipientStatus.Failed;
                                        if (bounceEvent != null)
                                        {
                                            communicationRecipient.StatusNote = string.Format("{0} by SendGrid at {1} - {2}", bounceEvent.BounceType, bounceEvent.TimeStamp.ToString("o"), bounceEvent.Reason);
                                        }<commit_msg>Update SendGrid.ashx<commit_after>﻿<%@ WebHandler Language="C#" Class="SendGrid" %>
using System;
using System.Web;
using System.IO;
using System.Text;
using Rock;
using Rock.Model;
using Rock.Workflow.Action;
using Sendgrid.Webhooks.Events;

public class SendGrid : IHttpHandler
{
    private HttpRequest _request;
    private HttpResponse _response;
    private int _transactionCount;

    public void ProcessRequest(HttpContext context)
    {
        _request = context.Request;
        _response = context.Response;

        _response.ContentType = "text/plain";

        if (!(_request.HttpMethod == "POST" && _request.ContentType.Contains("application/json")))
        {
            _response.Write("Invalid request type.");
            return;
        }

        if (_request != null)
        {
            string postedData = GetDocumentContents(_request);

            var rockContext = new Rock.Data.RockContext();
            
            var communicationRecipientService = new CommunicationRecipientService(rockContext);
            var communicationRecipientActivityService = new CommunicationRecipientActivityService(rockContext);

            var timeZoneInfo = RockDateTime.OrgTimeZoneInfo;
            var parser = new Sendgrid.Webhooks.Service.WebhookParser();
            var events = parser.ParseEvents(postedData);

            if (events != null)
            {
                int unsavedCommunicationCount = 0;
                foreach (var item in events)
                {
                    _transactionCount++;
                    unsavedCommunicationCount++;
                    // Process a SendEmailWithEvents workflow action 
                    if (item.UniqueParameters.ContainsKey("workflow_action_guid"))
                    {
                        var actionGuid = item.UniqueParameters["workflow_action_guid"].AsGuidOrNull();
                        string status = string.Empty;
                        switch (item.EventType)
                        {
                            case WebhookEventType.Delivered: status = SendEmailWithEvents.SENT_STATUS; break;
                            case WebhookEventType.Open: status = SendEmailWithEvents.OPENED_STATUS; break;
                            case WebhookEventType.Click: status = SendEmailWithEvents.CLICKED_STATUS; break;
                            case WebhookEventType.Dropped:
                            case WebhookEventType.SpamReport:
                            case WebhookEventType.Unsubscribe:
                            case WebhookEventType.Group_Unsubscribe:
                            case WebhookEventType.Bounce: status = SendEmailWithEvents.FAILED_STATUS; break;

                        }

                        if (actionGuid != null && !string.IsNullOrWhiteSpace(status))
                        {
                            SendEmailWithEvents.UpdateEmailStatus(actionGuid.Value, status, item.EventType.ConvertToString().SplitCase(), rockContext, true);
                        }
                    }

                    // Process a regular communication recipient  
                    if (item.UniqueParameters.ContainsKey("communication_recipient_guid"))
                    {
                        Guid communicationRecipientGuid;
                        if (Guid.TryParse(item.UniqueParameters["communication_recipient_guid"], out communicationRecipientGuid))
                        {
                            var communicationRecipient = communicationRecipientService.Get(communicationRecipientGuid);

                            if (communicationRecipient != null)
                            {
                                item.TimeStamp = TimeZoneInfo.ConvertTime(item.TimeStamp, timeZoneInfo);
                                switch (item.EventType)
                                {
                                    case WebhookEventType.Delivered:
                                        communicationRecipient.Status = CommunicationRecipientStatus.Delivered;
                                        communicationRecipient.StatusNote =
                                            string.Format("Confirmed delivered by SendGrid at {0}",
                                                item.TimeStamp.ToString("o"));
                                        break;
                                    case WebhookEventType.Open:
                                        communicationRecipient.Status = CommunicationRecipientStatus.Opened;
                                        var openEvent = item as OpenEvent;
                                        if (openEvent != null)
                                        {
                                            communicationRecipient.OpenedDateTime = openEvent.TimeStamp;
                                            communicationRecipient.OpenedClient = openEvent.UserAgent.Truncate(200) ??
                                                                                  "Unknown";
                                            var openActivity = new CommunicationRecipientActivity
                                            {
                                                CommunicationRecipientId = communicationRecipient.Id, 
                                                ActivityType = "Opened",
                                                ActivityDateTime = item.TimeStamp,
                                                ActivityDetail =
                                                    string.Format("Opened from {0} ({1})", openEvent.UserAgent ?? "unknown",
                                                        openEvent.Ip).Truncate(2200)
                                            };
                                            communicationRecipientActivityService.Add(openActivity);
                                        }
                                        break;
                                    case WebhookEventType.Click:
                                        var clickActivity = new CommunicationRecipientActivity
                                        {
                                            CommunicationRecipientId = communicationRecipient.Id, 
                                            ActivityType = "Click"
                                        };
                                        var clickEvent = item as ClickEvent;
                                        clickActivity.ActivityDateTime = item.TimeStamp;
                                        if (clickEvent != null)
                                        {
                                            clickActivity.ActivityDetail =
                                                string.Format("Clicked the address {0} from {1} using {2}", clickEvent.Url,
                                                    clickEvent.Ip, clickEvent.UserAgent).Truncate(2200);
                                        }
                                        communicationRecipientActivityService.Add(clickActivity);
                                        break;
                                    case WebhookEventType.Dropped:
                                        var dropEvent = item as DroppedEvent;
                                        communicationRecipient.Status = CommunicationRecipientStatus.Failed;
                                        if (dropEvent != null)
                                        {
                                            communicationRecipient.StatusNote = string.Format("{0} by SendGrid at {1}", dropEvent.Reason, dropEvent.TimeStamp.ToString("o"));
                                        }
                                        break;
                                    case WebhookEventType.Bounce:
                                        var bounceEvent = item as BounceEvent;
                                        communicationRecipient.Status = CommunicationRecipientStatus.Failed;
                                        if (bounceEvent != null)
                                        {
                                            communicationRecipient.StatusNote = string.Format("{0} by SendGrid at {1} - {2}", bounceEvent.BounceType, bounceEvent.TimeStamp.ToString("o"), bounceEvent.Reason);
                                        }
{'fraction_non_alphanumeric': 0.05956037338151159, 'fraction_numerical': 0.0027702499247214693, 'mean_word_length': 1.022408963585434, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 188, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '116476', 'n_tokens_mistral': 3045, 'n_tokens_neox': 2823, 'n_words': 591}