SMS messages can be leveraged for direct communication with users with an open rate up to 98% compared to emails with an open rate up to 20%, ask yourself if you received an SMS message right now, what is the likelihood of you opening the message?
Because we know there is a good possibility the user will read the message, SMS messages can be utilized for notifications like security updates and account activity.
So, in this article, we’ll try to provide an answer to the question of how to send SMS messages using C#.
How SMS works? (in a nutshell)
SMS or Short Message Service, is a text messaging service utilized by devices capable of communicating based on the SMS protocol like mobile phones.
SMS messages are transmitted using a standard cellular connection, and it doesn’t require an internet connection.
when an SMS message is sent from the sender device, it will be delivered to the closest cell tower. The message is sent from that cell tower to an SMS center (SMSC). The SMSC will then deliver the SMS message to a cell tower close to the recipient device. The message is then delivered to the recipient’s device by that tower.
Unlike email, which depends on the SMTP protocol where you can build your own SMTP server and handle your own infrastructure for delivering email messages. you can’t do the same with SMS, you need to leverage the carrier’s infrastructure to deliver your messages.
So how are SMS messages actually sent? (for developers)
as we’ve seen previously, in order to send SMS messages we need a device capable of communicating using SMS Protocol and using Code (C# for example) we need to instruct this device to send the messages.
lucky for us we already have plenty of solutions, one of them is using services like Twilio or MessageBird, which give an API to interact with, where you can send commands to the Twilio or MessageBird service and they will deliver the messages for you.
also, we have solutions for Testing because these services are not generous when it comes to testing, so if you have a phone with a subscription that includes unlimited SMS messages you can use it to deliver the message using RavenSMS.
Show me some code 💻
The method for handling message sending will vary based on the service you choose to use. Typically, you must install the package provided by that provider before using their SDK to send messages. then following the instruction in their documentation you will be able to send the messages.
is this the right way of doing that, No
as we said in the article “How to send emails with C# – the right way” you need to think in a way that will let you abstract this logic so that when you want to change/swap services it should not affect the entire application.
Clean architecture & the SMS sender
The sending of SMS messages has been abstracted three levels deep, as illustrated in the picture above, to ensure a complete decoupling of the sending mechanism from the app logic. so that any adjustments we make won’t have any effect.
1- SmsSender:
The high-level component that you will be working with within the code of your app, it contains the SMS sending commands and it is where we write our SMS messages, such as
if you are using CQRS, it will be the commands, like
– “SendUserAccountActivityNotificationCommand”,
– “SendVerificationCodeCommand”,
– etc,
or if you implement Onion Architecture it will be an interface with functions like
– “SendUserAccountActivityNotification()”,
– “SendVerificationCode()”
– etc
so that you can utilize the user instance, action link, and other inputs inside the command handler or function implementation to create an SMS message with a “To”, “Body,” etc. then we take the message and feed it to the SmsService.
2- SmsService:
the SMS service has a single responsibility, take the SMS message and pass it to the proper SMS channel (Twilio, RavenSMS, etc). it has a single function “Send()” with an input which is the SMS message, and returns the sending result.
also, our SMS service should be configured globally in the app generic host configuration.
SMS.NET
As we’ve seen, this is exactly how I develop all of my applications. Since using the same logic across all applications is bad practice, I’ve developed a package called SMS.Net that carries out this architecture.
Once installed, the “ISmsService” interface, which includes the “Send()” function, gives you access to the SMS service. For comprehensive documentation on how it functions and more information, visit the SMS.Net Github page.
You can find the source code for this blog post on GitHub here. I have developed two ASP Core API projects that utilize SMS.Net; the first use CQRS, and the second uses the Onion Architecture.
the two project samples will process the same case which is sending a security notice to the user requesting a password reset.
1- configuration
Let’s first examine how the package is configured to support the centralized configuration concept.
// add SMS.Net configuration
builder.Services.AddSMSNet(options =>
{
/* used to specify the default from to be used when sending the emails */
options.DefaultFrom = new PhoneNumber("00212606060606");
/* set the default channel to be used for sending the emails */
options.DefaultDeliveryChannel = TwilioSmsDeliveryChannel.Name;
/* to use RavenSMS as the default channel, comment the line above, and uncomment this line*/
// options.DefaultDeliveryChannel = RavenSmsDeliveryChannel.Name;
})
.UseTwilio(username: "", password: "")
.UseRavenSMS(options =>
{
options.UseInMemoryQueue();
options.UseInMemoryStores();
});
SMS.Net allows you to do all the configuration at the service registration level, with the option to register all the SMS channels you want to use, for example here we will be using Twilio, and RavenSMS, and you can add more if you want.
now if you want to change the SMS Channel all you need to do is to set the “options.DefaultDeliveryChannel ” to the name of the channel you are interested in, and that is, you don’t have to change any code anywhere.
2- EmailSender:
as you can see in the code example above, the SMS sender responsibility is to hide the logic of composing the SMS message, so that our code doesn’t have any interaction with the SMS logic.
once we are done composing the message we pass it to the SMS service, which the email sender has a dependency on it. then based on the configuration of SMS.Net it will use the proper SMS channel to send the message.
as I said there is complete documentation on how you can use the package, so check out the GitHub page, and if you like it give it a star ⭐