gauri's software engineering portfolio

CSV Generation Closest Date Algorithm Example Report Engine Standardizing Error Messages Text Message Notifications Download as Markdown

code sample 5

Text Message Notifications
Click here to view the source code on GitHub.

about this sample

This code chunk utilizes Twilio to send SMS messages to users when an automatic payment is coming up.

using System.Diagnostics;
    using Core.Accessors;
    using Core.Models;
    using Twilio;
    using Twilio.Exceptions;
    using Twilio.Rest.Api.V2010.Account;

    namespace Accessors
    {
        public class TextMessageAccessor : ITextMessageAccessor
        {
            public bool Send(PhoneNumber to, string body)
            {
                var accountSid = "AC9e977e44167ba6b169d6884c96a9903c";
                var authToken = "b96004eaed62d0eb9ba571a95048776d";

                TwilioClient.Init(accountSid, authToken);
                try
                {
                    var message = MessageResource.Create(
                        to: new Twilio.Types.PhoneNumber(to.Number),
                        from: "+15312016725",
                        body: body);
                    return true;
                }
                catch (ApiException e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine($"Twilio Error {e.Code} - {e.MoreInfo}");
                    return false;
                }
            }
        }
    }
    

msg & data rates may apply.

This code uses the Twilio API to send automatic text message notifications to users when a payment is coming up. It belongs in the Accessor layer, and it only interacts with the Core layer directly below it. It uses credentials given by my account on Twilio to send a text message to the phone number gathered during registration.

First, this method implements ITextMessageAccessor, and uses a Unity DI container to achieve constructor injection. This code demonstrates adaptation to change. Our initial schema did not account for text message notifications, but it was designed such that this type of notification would be possible. We standardized the representation of PhoneNumber so it could be used by text message notification APIs by accessing a property directly without writing error-prone string manipulation code.

The structure of the workflow made it easy to integrate a third-party API with our home-grown code. It demonstrates good use of the library by researching the custom exceptions that belong to the API and catching these exceptions where the library is used, the most logical place, since this feature is not client-facing in the web app. I chose to not propagate these exceptions to the Engine level so that I could use Twilio's custom exceptions without importing the library again in another spot. ApiException is a custom Twilio exception that provides better error documentation than one a developer using it would have implemented, so it prevents reinventing the wheel.

I avoided reinventing the wheel and stayed consistent with our existing notification workflow by using Twilio's C# NuGet package to call messageResource.Create() instead of formatting my own HTTP request to Twilio's endpoint in the Web layer, which the JavaScript documentation suggests. The final reason I preferred to write this on the C# side relates to volatility-based decomposition - client-facing code tends to change more frequently and more quickly than back-end code, and because this code is not volatile, it should be encapsulated with other non-volatile code. Finally, this code demonstrates consistency with the remainder of the code base. The ITextMessageAccessor and the ISmtpEmailServerAccessor both contain a Send method, and the TextNotificationProcessing Engine and the EmailNotificationProcessingEngine have similar workflows that follow from this acccessor. If a developer at Nelnet were to take on our project after handoff, it would be easy for them to navigate the structure of both notification workflows.