<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jeremy</title>
    <description>The latest articles on DEV Community by Jeremy (@jeremy_tly).</description>
    <link>https://dev.to/jeremy_tly</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2017768%2Fb75b9084-48e9-492c-beb2-0fbccaa181b1.png</url>
      <title>DEV Community: Jeremy</title>
      <link>https://dev.to/jeremy_tly</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jeremy_tly"/>
    <language>en</language>
    <item>
      <title>Sending Transactional Emails with Transmitly (C#)</title>
      <dc:creator>Jeremy</dc:creator>
      <pubDate>Tue, 29 Oct 2024 18:00:00 +0000</pubDate>
      <link>https://dev.to/jeremy_tly/sending-transactional-emails-with-transmitly-c-ede</link>
      <guid>https://dev.to/jeremy_tly/sending-transactional-emails-with-transmitly-c-ede</guid>
      <description>&lt;p&gt;Whether you’re confirming an order, resetting a password, or sending an account notification, transactional emails are key to ensuring a smooth user experience. However, managing these emails effectively can be complex. That’s where Transmitly comes in — a solution designed to streamline and enhance your transactional email process. In this article, you’ll explore how Transmitly, with its powerful features, can revolutionize the way you handle email communication.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is are Transactional Emails?
&lt;/h2&gt;

&lt;p&gt;Transactional emails are messages sent in response to specific actions or events within your application or service. Unlike marketing emails, which are sent in bulk to promote products or services, transactional emails are integral to your business operations. Common examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Order confirmations&lt;/li&gt;
&lt;li&gt;Password reset requests&lt;/li&gt;
&lt;li&gt;Account notifications&lt;/li&gt;
&lt;li&gt;Shipping updates&lt;/li&gt;
&lt;li&gt;Appointment reminders&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Transmitly?
&lt;/h2&gt;

&lt;p&gt;Transmitly is a robust platform for managing and controlling outgoing transactional communications, including emails, SMS, and push notifications. It centralizes your communication management, offers flexible configuration, and simplifies message composition. Whether you’re a developer or running a business, Transmitly helps you streamline your communication processes. It supports multiple service providers and integrates easily with a variety of tools, making your communications more efficient and reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods of Sending Email
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SMTP: Gmail, Zoho, Custom Mail Servers, SendGrid&lt;/li&gt;
&lt;li&gt;3rd-Party Service Providers: SendGrid, InfoBip, Bandwidth, and more&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Without Transmitly
&lt;/h2&gt;

&lt;p&gt;Typically, your first few email communications might involve using Simple Mail Transfer Protocol (SMTP) servers because it’s the simplest and fastest method to implement.&lt;/p&gt;

&lt;p&gt;A common approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Net&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Net.Mail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IEmailService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SendPasswordReminder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;toEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fromAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MailAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"your-from-email@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Your Name"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;toAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MailAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toEmail&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fromPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"your-email-password"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;smtp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SmtpClient&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;Host&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"smtp.example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;587&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;EnableSsl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;DeliveryMethod&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SmtpDeliveryMethod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Network&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;UseDefaultCredentials&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;Credentials&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NetworkCredential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromAddress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fromPassword&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;

      &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MailMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;toAddress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;Subject&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;smtp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What’s Wrong with This Approach?
&lt;/h2&gt;

&lt;p&gt;While this method works for low-volume emails, it has several limitations if you need to scale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scalability Issues: Handling a high volume of emails can strain your SMTP server, especially if it’s not optimized for large-scale sending.&lt;/li&gt;
&lt;li&gt;Deliverability Concerns: Ensuring your emails land in the recipient’s inbox (and not their spam folder) requires constant monitoring and fine-tuning, often without much insight or tooling.&lt;/li&gt;
&lt;li&gt; Limited Features: Basic SMTP solutions lack advanced features like email templates, scheduling, and automated workflows.&lt;/li&gt;
&lt;li&gt;Security Risks: Directly managing email sending involves handling sensitive credentials and configurations, which increases the risk of security breaches.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Transmitly Way
&lt;/h2&gt;

&lt;p&gt;First, you need to install the nuget package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install the base Transmitly package&lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly

&lt;span class="c"&gt;# We'll need the SMTP Transmitly package&lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly.ChannelProvider.Smtp

&lt;span class="c"&gt;# To make our lives easier, we'll use the optional MS DI extensions &lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly.Microsoft.Extensions.DependencyInjection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to do a little configuration first. In your Startup.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//All usual extensions and properties are located in this root namespace&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Transmitly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;//AddTransmitly comes from MS DI extensions library.&lt;/span&gt;
&lt;span class="c1"&gt;//Without the MS DI library, you can still wire up Transmitly using it's&lt;/span&gt;
&lt;span class="c1"&gt;//fluent builder.&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransmitly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tly&lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;{&lt;/span&gt; 
  &lt;span class="n"&gt;tly&lt;/span&gt;
  &lt;span class="c1"&gt;//AddSmtpSupport comes from the Smtp library&lt;/span&gt;
  &lt;span class="c1"&gt;//This allows us to setup what's needed in a strongly typed and central way&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSmtpSupport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"smtp.example.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;587&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseSsl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"MySMTPUsername"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"MyPassword"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&gt;//The simplest example -- this allows you to quickly move from your &lt;/span&gt;
  &lt;span class="c1"&gt;//existing code into transmitly.&lt;/span&gt;
  &lt;span class="c1"&gt;//Behind the scenes this is actually a Pipeline. Something you can learn&lt;/span&gt;
  &lt;span class="c1"&gt;//more about in the github docs&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddEmailMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SendPasswordReminder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"your-from-email@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Reset your password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;a href=\"url.com/reset-password\"&amp;gt;Click here to reset your password&amp;lt;/a&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, it looks similar to the original SMTP code. You still have credentials and email content, but now everything is centralized. Configuration is placed in your Startup.cs, but as your system grows, you can easily move this into its own class library.&lt;/p&gt;

&lt;p&gt;With Transmitly, you’re also creating a communications pipeline, which gives you centralized control over your communications. You can manage what messages are available and which channel providers are used to send them. In short, you now have a loosely coupled, centralized way of managing your communications.&lt;/p&gt;

&lt;p&gt;Next, let’s modify our original sending code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Transmitly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IEmailService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;EmailService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommunicationsClient&lt;/span&gt; &lt;span class="n"&gt;commsClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_commsClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;commsClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;SendPasswordReminder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;toEmail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_commsClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SendPasswordReminder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;toEmail&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSuccessful&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Email sent successfully!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Failed to send email."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all there is to it! The code may look similar, but these changes open up several new possibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change Channels: While today you might only need email, in the future, you might want to add push notifications or give users communication preferences. Transmitly lets you manage that easily with Pipelines, Channels, and Channel Providers.&lt;/li&gt;
&lt;li&gt;Change Providers: If SMTP gives you issues, you can quickly switch to another provider, like SendGrid, ZeptoMail, or AmazonSES, by adding a new Transmitly library and updating your configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You now have the power and flexibility to grow your communication strategy in a safe, controlled, and testable manner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Benefits of Using Transmitly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Centralized Communication Management: Manage emails, SMS, and push notifications from one platform, reducing complexity and boosting efficiency.&lt;/li&gt;
&lt;li&gt;Flexible Configuration: Switch between service providers like SendGrid, Twilio, or SMTP without altering your code.&lt;/li&gt;
&lt;li&gt;Simplified Message Composition: Externalize message composition, making it easier to modify and manage your communication strategy.&lt;/li&gt;
&lt;li&gt;Scalability and Reliability: Designed for high-volume communications with reliable performance.&lt;/li&gt;
&lt;li&gt;Provider Agnostic: Integrates seamlessly with almost any communication service (e.g., Twilio, Infobip, SMTP).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Transactional emails are vital to modern applications, ensuring timely and effective communication with users. While traditional email-sending methods can be limiting, Transmitly offers a powerful alternative that simplifies the process, improves deliverability, and provides valuable insights. By integrating Transmitly into your app, you can ensure your transactional emails are sent efficiently and reliably, enhancing user experience and engagement.&lt;/p&gt;

&lt;p&gt;For more information check out the &lt;a href="https://github.com/transmitly/transmitly" rel="noopener noreferrer"&gt;Transmitly Github Repo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Sending SMS with Transmitly (C#)</title>
      <dc:creator>Jeremy</dc:creator>
      <pubDate>Wed, 23 Oct 2024 06:00:00 +0000</pubDate>
      <link>https://dev.to/jeremy_tly/sending-sms-with-transmitly-c-13m</link>
      <guid>https://dev.to/jeremy_tly/sending-sms-with-transmitly-c-13m</guid>
      <description>&lt;p&gt;Whether you’re confirming an order, resetting a password, or sending an account notification, SMS messages are key to ensuring a great user experience. However, managing these SMS messages effectively can get complex, fast. That’s where Transmitly comes in — a solution designed to streamline and enhance your SMS message process. In this article, you’ll explore how Transmitly, with its powerful features, can revolutionize the way you handle SMS communications.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a transactional communication?
&lt;/h2&gt;

&lt;p&gt;Transactional communications are sent in response to specific actions or events within your application or service. Unlike marketing communications, which are typically sent in bulk to promote products or services, transactional communications are integral parts of your business operations. Common examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Order confirmations&lt;/li&gt;
&lt;li&gt;Password reset requests&lt;/li&gt;
&lt;li&gt;Account notifications&lt;/li&gt;
&lt;li&gt;One time password (OTP)&lt;/li&gt;
&lt;li&gt;Appointment reminders&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Transmitly?
&lt;/h2&gt;

&lt;p&gt;Transmitly is a robust platform for managing and controlling outgoing transactional communications, including emails, SMS, and push notifications. It centralizes your communication management, offers flexible configuration, and simplifies message composition. Whether you’re a developer or running a business, Transmitly helps you streamline your communication processes. It supports multiple service providers and integrates easily with a variety of tools, making your communications more efficient and reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods of Sending SMS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/SMS_gateway" rel="noopener noreferrer"&gt;SMS Gateway&lt;/a&gt;: Strangely enough, some carriers support sending SMS messages via special email addresses. They are generally not very reliable and you must know which provider your recipient is using.&lt;/li&gt;
&lt;li&gt;3rd-Party Service Providers: Twilio, InfoBip, Plivo, and more&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Without Transmitly
&lt;/h2&gt;

&lt;p&gt;There’s quite a few options out there to choose from for SMS communications. There’s also a lot more restrictions to be allowed to send SMS with any service. We’ll assume you’ve made it through the hoops of getting setup and you’ve chosen Twilio.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Add the Twilio Api:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Twilio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Install the C# / .NET helper library from twilio.com/docs/csharp/install&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Twilio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Twilio.Rest.Api.V2010.Account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SmsService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;OrderProcessed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Find your Account SID and Auth Token at twilio.com/console&lt;/span&gt;
        &lt;span class="c1"&gt;// and set the environment variables. See http://twil.io/secure&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;accountSid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TWILIO_ACCOUNT_SID"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;authToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TWILIO_AUTH_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;TwilioClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountSid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;authToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;MessageResource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Your order is being processed, thanks!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Twilio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PhoneNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"+15017122661"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Twilio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PhoneNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.twilio.com/docs/messaging/tutorials/how-to-send-sms-messages/how-to-send-sms-messages-csharp" rel="noopener noreferrer"&gt;(Example take from the Twilio quick start)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Wrong with This Approach?
&lt;/h2&gt;

&lt;p&gt;On the surface, not a lot. Twilio and their SDK will work great for a long time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More work to be done: Not shown is just how to deserialize the API response and make sense of it in your application.&lt;/li&gt;
&lt;li&gt;Vendor Lock: The more communications, the more you’re going to use their API. That doesn’t pose a problem until something changes with their service. Price increases, API changes, etc are all going to cost you and your application.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Transmitly Way
&lt;/h2&gt;

&lt;p&gt;First, you need to install the nuget package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install the base Transmitly package&lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly
&lt;span class="c"&gt;# We'll need the MailKit Transmitly package to use SMTP&lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly.ChannelProvider.Twilio
&lt;span class="c"&gt;# To make our lives easier, we'll use the optional MS DI extensions &lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly.Microsoft.Extensions.DependencyInjection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to do a little configuration first. In your Startup.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//All usual extensions and properties are located in this root namespace&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Transmitly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;//AddTransmitly comes from MS DI extensions library.&lt;/span&gt;
&lt;span class="c1"&gt;//Without the MS DI library, you can still wire up Transmitly using it's&lt;/span&gt;
&lt;span class="c1"&gt;//fluent builder.&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransmitly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tly&lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;{&lt;/span&gt; 
  &lt;span class="n"&gt;tly&lt;/span&gt;
  &lt;span class="c1"&gt;//AddTwilioSupport comes from the Twilio library&lt;/span&gt;
  &lt;span class="c1"&gt;//This allows us to setup what's needed in a strongly typed and central way&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTwilioSupport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;twilio&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;twilio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TWILIO_AUTH_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;twilio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AccountSid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TWILIO_ACCOUNT_SID"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OrderProcessing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//AddSms is a core feature, a channel, of Transmitly&lt;/span&gt;
    &lt;span class="c1"&gt;//Out of the box there are Email, SMS, Voice and Push&lt;/span&gt;
    &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sms&lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;//Transmitly is a bit different. All of our communication content is configured by using templates.&lt;/span&gt;
      &lt;span class="c1"&gt;//Out of the box, we have static or string templates, file and even embedded template support.&lt;/span&gt;
      &lt;span class="c1"&gt;//There are multiple types of templates to get you started. You can even create templates &lt;/span&gt;
      &lt;span class="c1"&gt;//specific to certain cultures!&lt;/span&gt;
      &lt;span class="n"&gt;sms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Your order is being processed, thanks!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;//We've kept it simple for this example, but Transmitly also supports various template engines.&lt;/span&gt;
      &lt;span class="c1"&gt;//Adding a template engine can make your messages a bit more useful by showing the order# or user's name.&lt;/span&gt;
   &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, it looks similar to the original code. You still have credentials and SMS content, but now everything is centralized. Configuration is placed in your &lt;code&gt;Startup.cs&lt;/code&gt;, but as your system grows, you can easily move this into its own class library.&lt;/p&gt;

&lt;p&gt;With Transmitly, you’re also creating a communications pipeline, which gives you centralized control over your communications. You can manage what messages are available and which channel providers are used to send them. In short, you now have a loosely coupled, centralized way of managing your communications.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Next, let’s modify our original sending code:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Transmitly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SmsService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ICommunicationsClient&lt;/span&gt; &lt;span class="n"&gt;_commsClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;EmailService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommunicationsClient&lt;/span&gt; &lt;span class="n"&gt;commsClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_commsClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;commsClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;OrderProcessed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//Dispatch (send) the transactional sms to our recipient using our configured Twilio account and our "OrderProcessing" pipeline.&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;communicationsClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DispatchAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OrderProcessing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"+15017122661"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsAudienceAddress&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSuccessful&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sms sent successfully!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Failed to send SMS"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all there is to it! The code may look similar, but these changes open up several new possibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change Channels: While today you might only need SMS, in the future, you might want to add email, push notifications or better yet, let users set their communication preferences. Transmitly lets you manage that easily with Pipelines, Channels, and Channel Providers.&lt;/li&gt;
&lt;li&gt;Change Providers: If Twilio gives you issues, you can quickly switch to another provider, like Infobip by adding a new Transmitly library and updating your configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You now have the power and flexibility to grow your communication strategy in a safe, controlled, and testable manner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Benefits of Using Transmitly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;   Centralized Communication Management: Manage emails, SMS, and push notifications from one platform, reducing complexity and boosting efficiency.&lt;/li&gt;
&lt;li&gt;   Flexible Configuration: Switch between service providers like SendGrid or Infobip without altering your business logic.&lt;/li&gt;
&lt;li&gt;   Simplified Message Composition: Externalize message composition, making it easier to modify and manage your communication strategy.&lt;/li&gt;
&lt;li&gt;   Scalability and Reliability: Designed for high-volume communications with reliable performance.&lt;/li&gt;
&lt;li&gt;   Provider Agnostic: Integrates seamlessly with almost any communication service (e.g., Twilio, Infobip, SMTP). Easily extensible for adding any missing features you might need.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Transactional communications are vital to modern applications, ensuring timely and effective communication with users. Transmitly offers a powerful alternative that simplifies the process, improves deliverability, and provides valuable insights. By integrating Transmitly into your app, you can ensure your transactional communications are sent efficiently and reliably, enhancing user experience and engagement.&lt;/p&gt;

&lt;p&gt;Peaked your interest? Check out the &lt;a href="https://github.com/transmitly/transmitly" rel="noopener noreferrer"&gt;Transmitly Github Repo&lt;/a&gt; for more exciting ways to manage your business' communications strategies.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Transactional Emails: A long term view</title>
      <dc:creator>Jeremy</dc:creator>
      <pubDate>Thu, 17 Oct 2024 01:59:40 +0000</pubDate>
      <link>https://dev.to/jeremy_tly/transactional-emails-a-long-term-view-13l6</link>
      <guid>https://dev.to/jeremy_tly/transactional-emails-a-long-term-view-13l6</guid>
      <description>&lt;p&gt;Sending emails has become essential for almost all modern applications and games. The most common type of emails in your first app are transactional. Examples of transactional communications include order confirmations, password reset requests, account notifications, and appointment reminders. Luckily, Microsoft has made this task pretty simple out of the box. So much so that you may not put much thought into how you’re sending out your app’s communications. And that’s okay — we all have deadlines to meet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Once you’ve identified the required transactional communications for your app, you need to decide how to send them. Again, you’re in luck here, too. You have a few different options when deciding how to send your emails. To keep things simple, you can start by using an established SMTP server. There are countless examples of how to use Gmail, Zoho, and other third-party SMTP services. It’s simple enough and will get you through development and even to the MVP phase.&lt;/p&gt;

&lt;p&gt;As your app grows, you might notice you’re being rate-limited by the SMTP service, transient errors are creeping in, and your simple email solution is no longer holding up to the stress of your growing app. First of all, congrats! Your app is growing! Second, it’s time to revisit our communications strategy. You’re in luck here as well. Numerous third-party APIs make it even easier to send emails. Services such as SendGrid, Mailgun, and ZeptoMail all come with their own pros and cons and a wide range of features. Now, you can do some really neat things with your emails. Again, your communications strategy has evolved, and so has the complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smooth Sailing…
&lt;/h2&gt;

&lt;p&gt;You’ve chosen a third-party service you love, and it’s working great. You’ve created an email service using their SDK. Now you can get back to growing your app, team, and business. Unfortunately, you receive an email from your third-party service. They are increasing their prices… again. Or worse, they’ve moved a feature you’ve been using heavily behind an expensive paywall.&lt;/p&gt;

&lt;p&gt;It’s time to change your service… again. It’s generally not too big of a deal, right? …Right?! Integrating a new email service only took a day. But the app is growing quickly, we have tech debt throughout, and not all of our emails are consistent. It wasn’t a big deal, but the new service doesn’t handle our older, legacy formats.&lt;/p&gt;

&lt;p&gt;While it may only be a mild annoyance that only rears its ugly head every few years, you’ve got a successful app. You don’t have time to learn a new service, a new API, all the quirks of a new service, and regression test all of your communications… again. This is why the open-source Transmitly communications library was created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transmit-Who?
&lt;/h2&gt;

&lt;p&gt;The Transmitly library is an open-source library designed to manage and control outgoing transactional communications, including emails, SMS, and push notifications. It offers centralized communication management, allowing developers to handle multiple communication channels from a single platform.&lt;/p&gt;

&lt;p&gt;Transmitly provides flexible configuration, enabling easy switching between SMTP and service providers like SendGrid, Twilio, and Infobip without altering domain code. It simplifies message composition and delivery and integrates seamlessly with various dependency injection containers and template engines.&lt;/p&gt;

&lt;h2&gt;
  
  
  And Now for Something Completely Different
&lt;/h2&gt;

&lt;p&gt;Transmitly is built on concepts pioneered by Serilog, Microsoft, and many other extensibility-first libraries. At its core, Transmitly enables you to choose as much or as little integration as you have the time or effort to use.&lt;/p&gt;

&lt;p&gt;Love the idea? Convert your whole codebase in a day or two. Not sure? Try it on only new transactional communications to start. It’s up to you.&lt;/p&gt;

&lt;p&gt;All this extensibility doesn’t come without some downsides. There’s going to be a ‘different’ way of doing things. And with different, there come some new terms we need to understand before we can really grasp the full scope of what’s possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Channels
&lt;/h2&gt;

&lt;p&gt;A channel is the base of all communications. Out of the box, Transmitly supports email, SMS, voice and push notifications. But you’re not limited to these channels. Transmitly is built with extensibility in mind at all times. This means that if you have an idea for a channel; such as physical mail, fax, or Slack, practically any kind of channel can be built in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Channel Providers
&lt;/h2&gt;

&lt;p&gt;Channel Providers do the heavy lifting for your Channels. A Channel Provider can support one to many channels. Examples include SMTP (Email), SendGrid (Email), Infobip (Email &amp;amp; SMS), or Firebase (iOS/Android/App push notifications).&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipelines
&lt;/h2&gt;

&lt;p&gt;Pipelines are where the real power of Transmitly starts to materialize. With a pipeline, you gain control of managing communications in a single location. You can also manage which communications are available and which channel providers are allowed to send them.&lt;/p&gt;

&lt;p&gt;That’s it! For now, at least. There are a few more advanced concepts that make the Transmitly transition even sweeter. For now, we’re sticking to the basics to get you up to speed ASAP. After all, you have a fast-growing application to maintain!&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Code
&lt;/h2&gt;

&lt;p&gt;First, you’ll need to install the Transmitly NuGet library in your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install the base Transmitly package&lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly

&lt;span class="c"&gt;# To make our lives easier, we'll use the optional MS DI extensions &lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly.Microsoft.Extensions.DependencyInjectionbash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we’ll continue with our email theme by recreating a welcome email that is sent to a newly signed-up user of your app.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Startup.cs&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Transmitly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetRequiredSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EmailSettings"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EmailSettingsConfiguration&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransmitly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tly&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Pipelines allow you to define your communications&lt;/span&gt;
    &lt;span class="c1"&gt;// as a domain action. This allows your domain code to &lt;/span&gt;
    &lt;span class="c1"&gt;// stay agnostic to the details of how you&lt;/span&gt;
    &lt;span class="c1"&gt;// may send out a transactional communication.&lt;/span&gt;

    &lt;span class="c1"&gt;// Notice "WelcomeKit" doesn't specify the how or what&lt;/span&gt;
    &lt;span class="c1"&gt;// might be sent. This is our 'intent'. It's up to our configuration&lt;/span&gt;
    &lt;span class="c1"&gt;// or domain if any communications will spawn and to whom.&lt;/span&gt;
    &lt;span class="n"&gt;tly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WelcomeKit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// AsIdentityAddress() is also a convenience method that helps us create an audience identity&lt;/span&gt;
        &lt;span class="c1"&gt;// Identity addresses can be anything: email, phone, or even a device/app ID for push notifications!&lt;/span&gt;
        &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"welcome@my.app"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsIdentityAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Welcome Committee"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Transmitly is a bit different. Most channel content is configured by using &lt;/span&gt;
            &lt;span class="c1"&gt;// templates. The immediate benefit out of the box is being able to configure&lt;/span&gt;
            &lt;span class="c1"&gt;// culture-based templates. &lt;/span&gt;
            &lt;span class="c1"&gt;// For this example, we'll keep things simple and send a static message.&lt;/span&gt;
            &lt;span class="c1"&gt;// But as you may have guessed, Transmitly also has Template Engine plugins as well.&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Subject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Thanks for creating an account!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HtmlBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Check out the &amp;lt;a href=\"https://my.app/getting-started\"&amp;gt;Getting Started&amp;lt;/a&amp;gt; section to see all the cool things you can do!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Check out the Getting Started (https://my.app/getting-started) section to see all the cool things you can do!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we can trigger this welcome kit to happen in the same place we used to send our email. Note how simple your domain logic becomes when we remove communications details.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Using Transmitly:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegistrationService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ICommunicationsClient&lt;/span&gt; &lt;span class="n"&gt;_commsClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;RegistrationService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommunicationsClient&lt;/span&gt; &lt;span class="n"&gt;commsClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_commsClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;commsClient&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commsClient&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;RegisterUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AccountDetail&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Create user&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;newUser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Trigger the welcome kit email&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_commsClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DispatchAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WelcomeKit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TransactionalModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSuccessful&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;newUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RegistrationException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Registration failed. Rollback!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run this new code… technically, it will work. However, you’ll be disappointed that you’re no longer sending emails. This is because we have not yet defined the 'how' of sending the emails out. With Transmitly, the 'how' or services are referred to as Channel Providers. Channel Providers are what the name implies: they are providers for any given channel. Examples of channel providers are SMTP, Twilio, SendGrid, Infobip etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# We want to continue using SMTP for now, so we'll add the SMTP extension&lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly.ChannelProvider.Smtp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can configure the SMTP server settings Transmitly will use for our pipeline intent, 'WelcomeKit'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Transmitly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetRequiredSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EmailSettings"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EmailSettingsConfiguration&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransmitly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tly&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Configure the SMTP Channel Provider Settings&lt;/span&gt;
    &lt;span class="n"&gt;tly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSmtpSupport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;smtp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;smtp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;smtp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;smtp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Username&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;smtp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// Pipelines allow you to define your communications&lt;/span&gt;
    &lt;span class="c1"&gt;// as a domain action. This allows your domain code to &lt;/span&gt;
    &lt;span class="c1"&gt;// stay agnostic to the details of how you&lt;/span&gt;
    &lt;span class="c1"&gt;// may send out a transactional communication.&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WelcomeKit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// AsIdentityAddress() is also a convenience method that helps us create an audience identity&lt;/span&gt;
        &lt;span class="c1"&gt;// Identity addresses can be anything: email, phone, or even a device/app ID for push notifications!&lt;/span&gt;
        &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"welcome@my.app"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsIdentityAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Welcome Committee"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Transmitly is a bit different. Most channel content is configured by using &lt;/span&gt;
            &lt;span class="c1"&gt;// templates. The immediate benefit out of the box is being able to configure&lt;/span&gt;
            &lt;span class="c1"&gt;// culture-based templates. &lt;/span&gt;
            &lt;span class="c1"&gt;// For this example, we'll keep things simple and send a static message.&lt;/span&gt;
            &lt;span class="c1"&gt;// But as you may have guessed, Transmitly also has Template Engine plugins as well.&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Subject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Thanks for creating an account!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HtmlBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Check out the &amp;lt;a href=\"https://my.app/getting-started\"&amp;gt;Getting Started&amp;lt;/a&amp;gt; section to see all the cool things you can do!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Check out the Getting Started (https://my.app/getting-started) section to see all the cool things you can do!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After deploying your code, sending a simple email can remain just as easy as it was before.&lt;/p&gt;

&lt;p&gt;If SMTP doesn’t quite fit the bill for your app anymore, try a different channel provider.&lt;/p&gt;

&lt;p&gt;Adding SMS or push notifications? Communication preferences? Modify your pipelines to effortlessly add new channels. Handling your user communication preferences are just as easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As your app grows and evolves, having a flexible and scalable communication strategy is crucial. Transmitly not only simplifies the process of sending transactional communications but also provides a robust framework for handling various channels and channel providers. This reduces the time spent managing communication logic and enables you to focus on building and improving your core application.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/transmitly/transmitly" rel="noopener noreferrer"&gt;Transmitly Github repo &lt;/a&gt;if you're interested in learning more!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.csadvent.christmas/" rel="noopener noreferrer"&gt;Happy holidays from the C# Advent Calendar 2024!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Transactional Emails: From SMTP to Transmitly</title>
      <dc:creator>Jeremy</dc:creator>
      <pubDate>Mon, 02 Sep 2024 21:21:06 +0000</pubDate>
      <link>https://dev.to/jeremy_tly/transactional-emails-from-smtp-to-transmitly-3hng</link>
      <guid>https://dev.to/jeremy_tly/transactional-emails-from-smtp-to-transmitly-3hng</guid>
      <description>&lt;p&gt;Sending emails has become essential for almost all modern applications and games. The most common type of emails in your first app are transactional. Examples of transactional communications include order confirmations, password reset requests, account notifications, and appointment reminders. Luckily, Microsoft has made this task pretty simple out of the box. So much so that you may not put much thought into how you’re sending out your app’s communications. And that’s okay — we all have deadlines to meet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Once you’ve identified the required transactional communications for your app, you need to decide how to send them. Again, you’re in luck here, too. You have a few different options when deciding how to send your emails. To keep things simple, you can start by using an established SMTP server. There are countless examples of how to use Gmail, Zoho, and other third-party SMTP services. It’s simple enough and will get you through development and even to the MVP phase.&lt;/p&gt;

&lt;p&gt;As your app grows, you might notice you’re being rate-limited by the SMTP service, transient errors are creeping in, and your simple email solution is no longer holding up to the stress of your growing app. First of all, congrats! Your app is growing! Second, it’s time to revisit our communications strategy. You’re in luck here as well. Numerous third-party APIs make it even easier to send emails. Services such as SendGrid, Mailgun, and ZeptoMail all come with their own pros and cons and a wide range of features. Now, you can do some really neat things with your emails. Again, your communications strategy has evolved, and so has the complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smooth Sailing…
&lt;/h2&gt;

&lt;p&gt;You’ve chosen a third-party service you love, and it’s working great. You’ve created an email service using their SDK. Now you can get back to growing your app, team, and business. Unfortunately, you receive an email from your third-party service. They are increasing their prices… again. Or worse, they’ve moved a feature you’ve been using heavily behind an expensive paywall.&lt;/p&gt;

&lt;p&gt;It’s time to change your service… again. It’s generally not too big of a deal, right? …Right?! Integrating a new email service only took a day. But the app is growing quickly, we have tech debt throughout, and not all of our emails are consistent. It wasn’t a big deal, but the new service doesn’t handle our older, legacy formats.&lt;/p&gt;

&lt;p&gt;While it may only be a mild annoyance that only rears its ugly head every few years, you’ve got a successful app. You don’t have time to learn a new service, a new API, all the quirks of a new service, and regression test all of your communications… again. This is why the open-source Transmitly communications library was created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transmit-Who?
&lt;/h2&gt;

&lt;p&gt;The Transmitly library is an open-source library designed to manage and control outgoing transactional communications, including emails, SMS, and push notifications. It offers centralized communication management, allowing developers to handle multiple communication channels from a single platform.&lt;/p&gt;

&lt;p&gt;Transmitly provides flexible configuration, enabling easy switching between SMTP (MailKit) and service providers like SendGrid, Twilio, and Infobip without altering domain code. It simplifies message composition and delivery and integrates seamlessly with various dependency injection containers and template engines.&lt;/p&gt;

&lt;h2&gt;
  
  
  And Now for Something Completely Different
&lt;/h2&gt;

&lt;p&gt;Transmitly is built on concepts pioneered by Serilog, Microsoft, and many other extensibility-first libraries. At its core, Transmitly enables you to choose as much or as little integration as you have the time or effort to use.&lt;/p&gt;

&lt;p&gt;Love the idea? Convert your whole codebase in a day or two. Not sure? Try it on only new transactional communications to start. It’s up to you.&lt;/p&gt;

&lt;p&gt;All this extensibility doesn’t come without some downsides. There’s going to be a ‘different’ way of doing things. And with different, there come some new terms we need to understand before we can really grasp the full scope of what’s possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Channels
&lt;/h2&gt;

&lt;p&gt;A channel is the base of all communications. Out of the box, Transmitly supports email, SMS, and push notifications. But you’re not limited to these channels. Transmitly is built with extensibility in mind at all times. This means that if you have a need for any kind of channel, such as physical mail, fax, or Slack, practically any kind of channel can be built in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Channel Providers
&lt;/h2&gt;

&lt;p&gt;Channel Providers do the heavy lifting for your Channels. A Channel Provider can support one to many channels. Examples include MailKit (SMTP Email), SendGrid (Email), Infobip (Email &amp;amp; SMS), or Firebase (iOS/Android/App push notifications).&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipelines
&lt;/h2&gt;

&lt;p&gt;Pipelines are where the real power of Transmitly starts to materialize. With a pipeline, you gain control of managing communications in a single location. You can also manage which communications are available and which channel providers are allowed to send them.&lt;/p&gt;

&lt;p&gt;That’s it! For now, at least. There are a few more advanced concepts that make the Transmitly transition even sweeter. For now, we’re sticking to the basics to get you up to speed ASAP. After all, you have a fast-growing application to maintain!&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Code
&lt;/h2&gt;

&lt;p&gt;First, you’ll need to install the Transmitly NuGet library in your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install the base Transmitly package&lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly

&lt;span class="c"&gt;# To make our lives easier, we'll use the optional MS DI extensions &lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly.Microsoft.Extensions.DependencyInjectionbash

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we’ll continue with our email theme by recreating a welcome email that is sent to a newly signed-up user of your app.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Startup.cs&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Transmitly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetRequiredSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EmailSettings"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EmailSettingsConfiguration&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransmitly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tly&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Pipelines allow you to define your communications&lt;/span&gt;
    &lt;span class="c1"&gt;// as a domain action. This allows your domain code to &lt;/span&gt;
    &lt;span class="c1"&gt;// stay agnostic to the details of how you&lt;/span&gt;
    &lt;span class="c1"&gt;// may send out a transactional communication.&lt;/span&gt;
    &lt;span class="n"&gt;tly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WelcomeKit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// AsIdentityAddress() is also a convenience method that helps us create an audience identity&lt;/span&gt;
        &lt;span class="c1"&gt;// Identity addresses can be anything: email, phone, or even a device/app ID for push notifications!&lt;/span&gt;
        &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"welcome@my.app"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsIdentityAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Welcome Committee"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Transmitly is a bit different. Most channel content is configured by using &lt;/span&gt;
            &lt;span class="c1"&gt;// templates. The immediate benefit out of the box is being able to configure&lt;/span&gt;
            &lt;span class="c1"&gt;// culture-based templates. &lt;/span&gt;
            &lt;span class="c1"&gt;// For this example, we'll keep things simple and send a static message.&lt;/span&gt;
            &lt;span class="c1"&gt;// But as you may have guessed, Transmitly also has Template Engine plugins as well.&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Subject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Thanks for creating an account!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HtmlBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Check out the &amp;lt;a href=\"https://my.app/getting-started\"&amp;gt;Getting Started&amp;lt;/a&amp;gt; section to see all the cool things you can do!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Check out the Getting Started (https://my.app/getting-started) section to see all the cool things you can do!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we can trigger this welcome kit to happen in the same place we used to send our email. Note how simple your domain logic becomes when we remove communications details.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Using Transmitly:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegistrationService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ICommunicationsClient&lt;/span&gt; &lt;span class="n"&gt;_commsClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;RegistrationService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommunicationsClient&lt;/span&gt; &lt;span class="n"&gt;commsClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_commsClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;commsClient&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commsClient&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;RegisterUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AccountDetail&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Create user&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;newUser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Trigger the welcome kit email&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_commsClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DispatchAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WelcomeKit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TransactionalModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSuccessful&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;newUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RegistrationException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Registration failed. Rollback!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run this new code… technically, it will work. However, you’ll be disappointed that you’re no longer sending emails. This is because we have not yet defined the ‘how’ of sending the emails out. With Transmitly, the “how” or services are referred to as Channel Providers. Channel Providers are what the name implies: they are providers for any given channel (email, SMS, push, etc.).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# We want to continue using SMTP for now, so we'll add the MailKit extension&lt;/span&gt;
dotnet &lt;span class="nb"&gt;install &lt;/span&gt;Transmitly.ChannelProvider.MailKit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can configure the SMTP server settings Transmitly will use for our WelcomeKit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Transmitly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetRequiredSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EmailSettings"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EmailSettingsConfiguration&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransmitly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tly&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Configure the MailKit Channel Provider Settings&lt;/span&gt;
    &lt;span class="n"&gt;tly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddMailKitSupport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mailkit&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;mailkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;mailkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseSsl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseSsl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;mailkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;mailkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Username&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;mailkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// Pipelines allow you to define your communications&lt;/span&gt;
    &lt;span class="c1"&gt;// as a domain action. This allows your domain code to &lt;/span&gt;
    &lt;span class="c1"&gt;// stay agnostic to the details of how you&lt;/span&gt;
    &lt;span class="c1"&gt;// may send out a transactional communication.&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WelcomeKit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// AsIdentityAddress() is also a convenience method that helps us create an audience identity&lt;/span&gt;
        &lt;span class="c1"&gt;// Identity addresses can be anything: email, phone, or even a device/app ID for push notifications!&lt;/span&gt;
        &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"welcome@my.app"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsIdentityAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Welcome Committee"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Transmitly is a bit different. Most channel content is configured by using &lt;/span&gt;
            &lt;span class="c1"&gt;// templates. The immediate benefit out of the box is being able to configure&lt;/span&gt;
            &lt;span class="c1"&gt;// culture-based templates. &lt;/span&gt;
            &lt;span class="c1"&gt;// For this example, we'll keep things simple and send a static message.&lt;/span&gt;
            &lt;span class="c1"&gt;// But as you may have guessed, Transmitly also has Template Engine plugins as well.&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Subject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Thanks for creating an account!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HtmlBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Check out the &amp;lt;a href=\"https://my.app/getting-started\"&amp;gt;Getting Started&amp;lt;/a&amp;gt; section to see all the cool things you can do!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStringTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Check out the Getting Started (https://my.app/getting-started) section to see all the cool things you can do!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After deploying your code, sending a simple email can remain just as easy as it was before.&lt;/p&gt;

&lt;p&gt;If SMTP doesn’t quite fit the bill for your app anymore, try a different channel provider.&lt;/p&gt;

&lt;p&gt;Adding SMS or push notifications? Communication preferences? Modify your pipelines to effortlessly add new channels. Handling your user communication preferences are just as easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As your app grows and evolves, having a flexible and scalable communication strategy is crucial. Transmitly not only simplifies the process of sending transactional communications but also provides a robust framework for handling various channels and channel providers. This reduces the time spent managing communication logic and enables you to focus on building and improving your core application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/transmitly/transmitly" rel="noopener noreferrer"&gt;Check out the github repo for more details and examples of all the great things Transmitly can do.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
