<?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>Forem: Courier</title>
    <description>The latest articles on Forem by Courier (@courier).</description>
    <link>https://forem.com/courier</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%2Forganization%2Fprofile_image%2F3288%2Fd7c19ec0-5176-496e-b68e-d0e11b23b5aa.png</url>
      <title>Forem: Courier</title>
      <link>https://forem.com/courier</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/courier"/>
    <language>en</language>
    <item>
      <title>Sending Scheduled and Recurring Email Notifications with PHP</title>
      <dc:creator>Oleksii Klochai</dc:creator>
      <pubDate>Thu, 27 Jul 2023 11:01:32 +0000</pubDate>
      <link>https://forem.com/courier/sending-scheduled-and-recurring-email-notifications-with-php-28n3</link>
      <guid>https://forem.com/courier/sending-scheduled-and-recurring-email-notifications-with-php-28n3</guid>
      <description>&lt;p&gt;Sending timely targeted email notifications greatly affects how your audience engages with your product. For these notifications to be effective at notifying your users of key events, you need to schedule when they are sent so that they are delivered at the right time. &lt;/p&gt;

&lt;p&gt;Scheduled and recurring notifications are in use everywhere — for example, online stores use scheduled notifications to inform users about sale events (like Black Friday), and doctors, dentists, and tradespeople have systems that send appointment reminders. Recurring emails are commonly used for subscription services to email monthly bills to customers.&lt;/p&gt;

&lt;p&gt;This tutorial covers two different ways for PHP developers to send scheduled and recurring email notifications through the Courier notification platform using its &lt;a href="https://github.com/trycourier/courier-php"&gt;PHP SDK&lt;/a&gt;. It also offers a low-code solution for sending scheduled emails using just the Courier UI. Courier is a multi-channel notification service with a robust API, which you can use to build a production-ready email notification system in a few minutes. &lt;/p&gt;

&lt;h3&gt;
  
  
  Configure an email service provider in Courier
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://app.courier.com/signup"&gt;Create a Courier account&lt;/a&gt; if you don’t already have one, so that you can configure an &lt;a href="https://www.courier.com/integrations/#email"&gt;email service provider&lt;/a&gt; in Courier, allowing it to send emails on your behalf. \&lt;/p&gt;

&lt;p&gt;In the Courier app, navigate to &lt;strong&gt;&lt;a href="https://app.courier.com/channels"&gt;Channels&lt;/a&gt;&lt;/strong&gt; and choose your email service provider. For this tutorial, we will use Gmail.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/35bXpb6BEkYc4bTFRefipC/43181e7401688bd42ead6034633a3f10/send_notifications_php_1.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/35bXpb6BEkYc4bTFRefipC/43181e7401688bd42ead6034633a3f10/send_notifications_php_1.png" alt="Screenshot showing how to select an email service provider in Courier."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the next screen, select &lt;strong&gt;Sign in with Google&lt;/strong&gt; to give Courier permission to access your Gmail account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a notification template in Courier
&lt;/h2&gt;

&lt;p&gt;Courier uses email templates to make it easy to reuse your emails. In this tutorial, we will use an example of a hairdressing business that sends emails to its clients before (and sometimes after) appointments.&lt;/p&gt;

&lt;p&gt;To create your first template, start by navigating to the &lt;a href="https://app.courier.com/designer/notifications"&gt;Designer&lt;/a&gt;. Click &lt;strong&gt;Create Template&lt;/strong&gt;, give it the name &lt;strong&gt;Hair appointment reminder&lt;/strong&gt;, and click &lt;strong&gt;Create Template&lt;/strong&gt; again.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/377LkgHFun4nR5fdlNhpho/102549fcd4df4b60b8e38d91d9f35a57/send_notifications_php_2.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/377LkgHFun4nR5fdlNhpho/102549fcd4df4b60b8e38d91d9f35a57/send_notifications_php_2.gif" alt="Animation showing how to create a notification template in Courier."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, select &lt;strong&gt;Email&lt;/strong&gt; as the channel for this notification (choosing Gmail as the specific provider in the drop-down box). Now, click on your new email channel on the left side to see the no-code editor for designing your notification. &lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/T3BYkDx6VuzYvN27Hy1dp/1b290705838cdfba4288d87a008d3766/send_notifications_php_3.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/T3BYkDx6VuzYvN27Hy1dp/1b290705838cdfba4288d87a008d3766/send_notifications_php_3.gif" alt="Animation showing how to add text to an email template in Courier and choose Gmail as your notification provider."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give your notification the subject “Hair appointment reminder”, and paste the following content into the message body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dear {name},

This email is to confirm your upcoming hair appointment tomorrow.

We look forward to seeing you at {place}. Please arrive five minutes before your appointment start time.

If you need to reschedule, please let us know at least 24 hours prior to your appointment time.

Thank you for your appointment.

The {salonName} Team
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The curly braces in this template are variables that will later be passed to the template as data. Now that your template is complete, click &lt;strong&gt;Publish Changes&lt;/strong&gt;. Later on, you will need your notification template ID and Courier authorization token when you want to call the Courier API. These are both available in your notification template settings. Navigate there now and copy both so that you can use them later.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/5npucjyNygwXbMdsslJ69w/0757d2036423c57a073758b7a9b4ebfb/send_notifications_php_4.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/5npucjyNygwXbMdsslJ69w/0757d2036423c57a073758b7a9b4ebfb/send_notifications_php_4.gif" alt="Animation showing how to copy the notification template ID and Courier authorization token in your notification settings."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you have three options: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Directly send scheduled or recurring emails using Courie&lt;/strong&gt;r*&lt;em&gt;:&lt;/em&gt;* Call the &lt;code&gt;sendEnhancedNotification()&lt;/code&gt; function from the Courier PHP SDK, and use a third party task scheduling library called Crunz to deal with the scheduling side of things. This works using cron syntax, so the same principle can be used for scheduled or recurring emails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Courier’s automations to add send logic to your scheduled emails:&lt;/strong&gt; An automation in Courier is a way of chaining together different steps such as the sending of emails (or other notification-related logic) so that the steps happen in a particular order. An automation can be run by calling the &lt;code&gt;invokeAutomation()&lt;/code&gt;function,  and as with option 1, you can use Crunz to deal with the scheduling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using Courier’s no-code automations designer:&lt;/strong&gt; This is a no-code GUI tool in the Courier UI that uses a drag-and-drop canvas to build up your notification logic. It contains some more advanced logic than option 2 (such as the ability to create  email digests or batching).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Option 1: directly send a scheduled or recurring email using Courier
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Preparing your PHP environment
&lt;/h3&gt;

&lt;p&gt;For both of the PHP examples shown below, you will need to prepare a PHP environment and create a notification template in the Courier app.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the latest versions of PHP and &lt;a href="https://getcomposer.org/download/"&gt;Composer&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Install the following packages using Composer:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/trycourier/courier-php"&gt;trycourier/courier&lt;/a&gt; — the Courier PHP SDK&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/guzzle/guzzle"&gt;guzzlehttp/guzzle&lt;/a&gt; — required by the Courier PHP SDK&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/crunzphp/crunz"&gt;crunzphp/crunz&lt;/a&gt; — for scheduling one-time and recurring tasks&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/vlucas/phpdotenv"&gt;vlucas/phpdotenv&lt;/a&gt; — for handling environment variables&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can install these by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require crunzphp/crunz vlucas/phpdotenv trycourier/courier guzzlehttp/guzzle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also find the code shown in this tutorial in our working &lt;a href="https://github.com/trycourier/courier-cron"&gt;example repository on GitHub&lt;/a&gt;. If you are cloning the repository, you will need to run the &lt;code&gt;composer install&lt;/code&gt; command to install the dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending a scheduled email
&lt;/h3&gt;

&lt;p&gt;To manage the scheduling side of things, we will use &lt;a href="https://github.com/crunzphp/crunz"&gt;Crunz&lt;/a&gt; — a PHP package that allows you to run scheduled tasks within your PHP code without having to create a cron job for each of them. We will wrap this around Courier’s &lt;code&gt;sendEnhancedNotification()&lt;/code&gt; function, which is used for sending emails. &lt;/p&gt;

&lt;p&gt;For this example, we have specified that the hair appointment reminder should be sent at a specific time (13:30 2023-07-01). However, note that Crunz’s &lt;code&gt;on()&lt;/code&gt; function accepts any date format parsed by PHP's &lt;a href="http://php.net/manual/en/function.strtotime.php"&gt;&lt;code&gt;strtotime()&lt;/code&gt;&lt;/a&gt; function, so it’s easy to pass in a time value derived from one of your variables.&lt;/p&gt;

&lt;p&gt;As per the example in our GitHub repository, you must provide your configuration in an &lt;a href="https://github.com/vlucas/phpdotenv"&gt;&lt;code&gt;.env&lt;/code&gt; file at the project root&lt;/a&gt;. You can create this file by copying the provided example file into your project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, fill out the contents of the newly copied &lt;code&gt;.env&lt;/code&gt; file:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;COURIER_AUTHORIZATION_TOKEN&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Courier API key, found in Settings&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TEST_EMAIL_TO&lt;/td&gt;
&lt;td&gt;Use your own email address as the value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TEST_DIRECT_SEND_NOTIFICATION_TEMPLATE_ID&lt;/td&gt;
&lt;td&gt;The notification template ID for the “Hair appointment reminder” email template&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Crunz requires you to add a single &lt;a href="https://linuxhint.com/cron_jobs_complete_beginners_tutorial/"&gt;crontab&lt;/a&gt; entry that runs every minute. Whenever this job runs, any tasks scheduled using Crunz for that time will be executed. You only need to do this once for your project. Append the following line to your own user’s crontab on your PHP server (you can do this by typing &lt;code&gt;crontab -e&lt;/code&gt; in your terminal):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* * * * * cd /path/to/project &amp;amp;&amp;amp; vendor/bin/crunz schedule:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;/path/to/project&lt;/code&gt; with the absolute path to your PHP project. For security reasons, you should not add this line to your root user's crontab but instead create a user who has execute permissions for the project directory or is a member of the group that your web server runs under (by default, &lt;code&gt;www-data&lt;/code&gt; on most Linux systems).&lt;/p&gt;

&lt;p&gt;Crunz requires the presence of a configuration file, which contains a configured timezone. Create this by running this command in your project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vendor/bin/crunz publish:config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the default configured timezone is UTC, but you can change this in the config if needed.&lt;/p&gt;

&lt;p&gt;All Crunz tasks must be contained in a directory called &lt;code&gt;tasks&lt;/code&gt; at the root level of your project. The file containing each task should end with &lt;code&gt;Tasks.php&lt;/code&gt;. Create this directory, and inside it, create a file called &lt;code&gt;scheduledSendTasks.php&lt;/code&gt;and paste the following code into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Crunz\Schedule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Courier\CourierClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Dotenv\Dotenv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Configure environment variables - set the .env directory to the parent of the Tasks directory&lt;/span&gt;
&lt;span class="c1"&gt;// Environment variables are stored in a variable so that they can be passed to the scheduled task, which will not have access to the current global namespace&lt;/span&gt;
&lt;span class="nv"&gt;$dotenv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Dotenv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;createArrayBacked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"/.."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Configure scheduler&lt;/span&gt;
&lt;span class="nv"&gt;$schedule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Schedule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Configure the Courier PHP SDK - note the first null is the API path, of which we will use the default&lt;/span&gt;
&lt;span class="nv"&gt;$courier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CourierClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'COURIER_AUTHORIZATION_TOKEN'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Create a new scheduled task&lt;/span&gt;
&lt;span class="nv"&gt;$task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$schedule&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$courier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="k"&gt;__FILE__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Send notification using the Courier PHP SDK&lt;/span&gt;
    &lt;span class="nv"&gt;$notification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"to"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"email"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'TEST_EMAIL_TO'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"template"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'TEST_DIRECT_SEND_NOTIFICATION_TEMPLATE_ID'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"routing"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"method"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"single"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"channels"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"data"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"place"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"123 High Street"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"salonName"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Cutting Edge"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$courier&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;sendEnhancedNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$notification&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Schedule a single notification for a specific time&lt;/span&gt;
&lt;span class="nv"&gt;$task&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'13:30 2023-07-01'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Sending scheduled email'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$schedule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that you’ve created a scheduled task, it will run as soon as the scheduled time is reached. Remember, as mentioned above, the default timezone is UTC, but you can change this.&lt;/p&gt;

&lt;p&gt;If you want to test your scheduled task, you can force it to run immediately using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vendor/bin/crunz schedule:run --force
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will run all scheduled or recurring tasks that you’ve created. If you want to be sure which tasks will run with this command, you can run another command to check how many scheduled tasks you have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vendor/bin/crunz schedule:list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output a table containing your scheduled tasks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+---+------------------------------+-------------+-----------------+
| # | Task                         | Expression  | Command to Run  |
+---+------------------------------+-------------+-----------------+
| 1 | Sending scheduled email      | 30 13 1 7 * | object(Closure) |
| 2 | Sending recurring email      | 30 13 * * * | object(Closure) |
| 3 | Sending scheduled automation | 30 13 1 7 * | object(Closure) |
+---+------------------------------+-------------+-----------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sending a recurring email
&lt;/h3&gt;

&lt;p&gt;You can also use Crunz to create recurring tasks on a schedule.&lt;/p&gt;

&lt;p&gt;Inside your &lt;code&gt;tasks&lt;/code&gt; directory, create a PHP file called &lt;code&gt;recurringSendTasks.php&lt;/code&gt; and paste this code into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Crunz\Schedule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Courier\CourierClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Dotenv\Dotenv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Configure environment variables - set the .env directory to the parent of the Tasks directory&lt;/span&gt;
&lt;span class="c1"&gt;// Environment variables are stored in a variable so that they can be passed to the scheduled task, which will not have access to the current global namespace&lt;/span&gt;
&lt;span class="nv"&gt;$dotenv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Dotenv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;createArrayBacked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"/.."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Configure scheduler&lt;/span&gt;
&lt;span class="nv"&gt;$schedule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Schedule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Configure the Courier PHP SDK - note the first null is the API path, of which we will use the default&lt;/span&gt;
&lt;span class="nv"&gt;$courier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CourierClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'COURIER_AUTHORIZATION_TOKEN'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Create a new scheduled task&lt;/span&gt;
&lt;span class="nv"&gt;$task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$schedule&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$courier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="k"&gt;__FILE__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Send notification using the Courier PHP SDK&lt;/span&gt;
    &lt;span class="nv"&gt;$notification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"to"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"email"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'TEST_EMAIL_TO'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"template"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'TEST_DIRECT_SEND_NOTIFICATION_TEMPLATE_ID'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"routing"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"method"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"single"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"channels"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"data"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"place"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"123 High Street"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"salonName"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Cutting Edge"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$courier&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;sendEnhancedNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$notification&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Set up a recurring task&lt;/span&gt;
&lt;span class="nv"&gt;$task&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;daily&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'13:30'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Sending recurring email'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$schedule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test this, again run &lt;code&gt;vendor/bin/crunz schedule:run --force&lt;/code&gt;. However, you’ll only receive one email, as you are using the &lt;code&gt;–-force&lt;/code&gt; option, which forces a single run of each task. When your recurring task is being invoked by Crunz as a scheduled task, it will be called at the specified interval, and if you use the above code example, you will receive one email per day at 13:30.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Laravel? It’s already got scheduling baked in
&lt;/h3&gt;

&lt;p&gt;If you’re using Laravel, you don’t need to worry about setting up your own scheduling solution, as it already has its own(&lt;a href="https://laravel.com/docs/10.x/scheduling"&gt;https://laravel.com/docs/10.x/scheduling&lt;/a&gt;) (and &lt;a href="https://laravel.com/docs/10.x/queues"&gt;queueing&lt;/a&gt;!) built in — one of the many advantages of using a PHP framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: use Courier’s automations to add send logic to your scheduled emails
&lt;/h2&gt;

&lt;p&gt;Sometimes you need to add some logic around the sending of your scheduled or recurring emails, and this is where Courier’s automations can be useful. Automations allow you to chain together a series of &lt;a href="https://www.courier.com/docs/automations/steps/"&gt;different steps&lt;/a&gt;, including the sending of emails based on different notification templates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples of when to use automations
&lt;/h3&gt;

&lt;p&gt;Imagine a gym that sends its customers workout tips — it may want to sometimes send out different workout plans based on customers’ age or other groupings. Using automation in Courier, it could implement some basic branching logic such as “if the customer’s age is greater than 50, send an email using the over 50s email template; otherwise, send using the under 50s email template.”&lt;/p&gt;

&lt;p&gt;Another feature that Courier automations offer is the ability to add a delay between two different actions. To reuse our hairdresser example, imagine that in addition to reminding the customer of their appointment the day before, they also want to send an email the day after their appointment to thank them and offer them 10% off their next appointment. Here’s how to implement this using Courier’s automations:&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending two scheduled emails in one automation
&lt;/h3&gt;

&lt;p&gt;As this involves sending two different emails, you will need to create a second email template for the 10% off offer. Create a new template with the following body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dear {name}, 

We hope you were satisfied with your hair appointment yesterday, and
we would like to offer you 10% off your next booking.

Thanks,

The {salonName} Team
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that you have both email templates ready to go, you can create your automation in Courier. The automation sends the first email, then there is a delay (in the example below, there is a two-minute delay, but for real-world use, you would probably set it to two days), and then it sends a follow-up email. We will continue to use the PHP Crunz package to kick off the automation at the right moment (one day before the customer’s scheduled appointment), meaning that the second follow-up email will be sent one day after their appointment.&lt;/p&gt;

&lt;p&gt;To follow along with this example, you will need to have followed the steps in the “Prepare your PHP environment” step explained earlier.&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;tasks&lt;/code&gt; directory in your PHP project, create a file called &lt;code&gt;scheduleAutomationTasks.php&lt;/code&gt; and paste in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Crunz\Schedule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Courier\CourierClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Dotenv\Dotenv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Configure environment variables - set the .env directory to the parent of the Tasks directory&lt;/span&gt;
&lt;span class="c1"&gt;// Environment variables are stored in a variable so that they can be passed to the scheduled task, which will not have access to the current global namespace&lt;/span&gt;
&lt;span class="nv"&gt;$dotenv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Dotenv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;createArrayBacked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"/.."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Configure scheduler&lt;/span&gt;
&lt;span class="nv"&gt;$schedule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Schedule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Configure the Courier PHP SDK - note the first null is the API path, of which we will use the default&lt;/span&gt;
&lt;span class="nv"&gt;$courier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CourierClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'COURIER_AUTHORIZATION_TOKEN'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Create a new scheduled task&lt;/span&gt;
&lt;span class="nv"&gt;$task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$schedule&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$courier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="k"&gt;__FILE__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Invoke an automation using the Courier PHP SDK&lt;/span&gt;
    &lt;span class="nv"&gt;$automation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"steps"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s2"&gt;"action"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"send"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"recipient"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'TEST_AUTOMATION_RECIPIENT_USER_ID'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="s2"&gt;"template"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'TEST_AUTOMATION_NOTIFICATION_TEMPLATE_ID_1'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Reminder email&lt;/span&gt;
                &lt;span class="s2"&gt;"brand"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'YOUR_COURIER_BRAND_ID'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="s2"&gt;"data"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                      &lt;span class="s2"&gt;"name"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"salonName"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Cutting Edge"&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="s2"&gt;"action"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"delay"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"duration"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"2 minutes"&lt;/span&gt; &lt;span class="c1"&gt;// You will probably want to delay by days or hours, but minutes are easier for testing&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s2"&gt;"action"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"send"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"recipient"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'TEST_AUTOMATION_RECIPIENT_USER_ID'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="s2"&gt;"template"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'TEST_AUTOMATION_NOTIFICATION_TEMPLATE_ID_2'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Follow-up email&lt;/span&gt;
                &lt;span class="s2"&gt;"brand"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$dotenv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'YOUR_COURIER_BRAND_ID'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="s2"&gt;"data"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                      &lt;span class="s2"&gt;"name"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"salonName"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Cutting Edge"&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;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$courier&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;invokeAutomation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$automation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Schedule the automation for a specific time&lt;/span&gt;
&lt;span class="nv"&gt;$task&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'13:30 2023-07-01'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Sending scheduled automation'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$schedule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure you’ve updated your &lt;code&gt;.env&lt;/code&gt; file with any configuration you need to run this automation: &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;COURIER_AUTHORIZATION_TOKEN&lt;/th&gt;
&lt;th&gt;Courier API key, found in Settings&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TEST_AUTOMATION_RECIPIENT_USER_ID&lt;/td&gt;
&lt;td&gt;Find your user ID in Courier’s list of users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TEST_AUTOMATION_NOTIFICATION_TEMPLATE_ID_1&lt;/td&gt;
&lt;td&gt;The notification template ID for the “Hair appointment reminder” email template&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TEST_AUTOMATION_NOTIFICATION_TEMPLATE_ID_2&lt;/td&gt;
&lt;td&gt;The notification template ID for the “Hair appointment — 10% off” email template&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YOUR_COURIER_BRAND_ID&lt;/td&gt;
&lt;td&gt;Choose your brand and find its ID in its “brand settings” or URL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now run &lt;code&gt;vendor/bin/crunz schedule:run --force&lt;/code&gt;, and you will receive the two different emails with the specified delay in between.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic automations API documentation
&lt;/h3&gt;

&lt;p&gt;To understand all the features that automations can offer, you can play around with our dynamic request builder in Courier’s [automation API documentation][20]. This allows you to build up your PHP automation request dynamically by adding request parameters. For example, if you add your preferred Courier brand ID in the “brand” box, your brand ID will be automatically added to a PHP request on the box on the right. You will need to select the “PHP” button to get a PHP request; however, other languages are available at the click of a button. &lt;/p&gt;

&lt;p&gt;One of the key features of a Courier automation is the series of “steps” that make it up. To understand the different steps that can be part of an automation, see Courier’s &lt;a href="https://www.courier.com/docs/automations/steps/"&gt;extensive documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/49yYL3xO9xIGmkiWoXDLEc/e5fdb876c65207a99acd15d978fb8c12/send_notifications_php_6.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/49yYL3xO9xIGmkiWoXDLEc/e5fdb876c65207a99acd15d978fb8c12/send_notifications_php_6.png" alt="How to use the dynamic request builder tool in Courier’s automation API documentation — a convenient visual tool to help you explore the structure of an automation API request object."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 3: use Courier’s no-code automations designer to build complex logic around scheduled emails
&lt;/h2&gt;

&lt;p&gt;The automations designer is a UI tool for building automation templates in Courier. An automation template offers a way to reuse Courier automations, and because they can be created in the Courier UI, they are super easy to create. Even your non-developer colleagues will be able to create automation templates using Courier’s simple drag-and-drop canvas.&lt;/p&gt;

&lt;p&gt;For this example, we will use a “remember to pay your taxes” email, as this email could be sent on a schedule (April 1 of this year) or as a recurrence (April 1 every year).&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a notification template
&lt;/h3&gt;

&lt;p&gt;Create a new notification template with the subject “Tax deadline approaching,” and use the AI content generator to create some text for the body of your email. This may looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dear {name},

The end-of-year tax deadline is fast approaching. If you haven't yet filed your taxes, you can do this using our app:

{appUrl}

If you have any questions or concerns, please don't hesitate to contact us.

Thank you,

The {companyName} Team
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that your template is complete, click &lt;strong&gt;Publish Changes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/2xzlzffuqUCq8wItTLfT2C/0cfbd0117b0899494aa1762df4ca38d6/send_notifications_php_6-1.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/2xzlzffuqUCq8wItTLfT2C/0cfbd0117b0899494aa1762df4ca38d6/send_notifications_php_6-1.png" alt="Screenshot showing how to create an email template in Courier."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create an automation template
&lt;/h3&gt;

&lt;p&gt;Navigate to &lt;a href="https://app.courier.com/automations"&gt;automations&lt;/a&gt;, and click &lt;strong&gt;New Automation&lt;/strong&gt;. Rename your automation from “Untitled Automation” to “Tax Deadline Reminder.”&lt;/p&gt;

&lt;p&gt;To define the trigger for your automation, drag the &lt;strong&gt;Schedule&lt;/strong&gt; trigger onto the canvas. &lt;/p&gt;

&lt;p&gt;For a one-off scheduled email, change the &lt;strong&gt;Type&lt;/strong&gt; of the &lt;strong&gt;Schedule&lt;/strong&gt; node to &lt;strong&gt;Date&lt;/strong&gt;, and enter the date and time you want your notification to be sent — in this case, we will choose midnight on April 1, 2024.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/6pBLPEq36P1rP0CmNRw7b9/0421548af718493f8a027d903fda2fd4/send_notifications_php_9.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/6pBLPEq36P1rP0CmNRw7b9/0421548af718493f8a027d903fda2fd4/send_notifications_php_9.png" alt="Screenshot showing how to schedule an email in the Courier automations designer."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a recurring email, change the &lt;strong&gt;Type&lt;/strong&gt; to &lt;strong&gt;Recurrence&lt;/strong&gt;. Then set a start date of April 1, 2024, 00:00, an end date of April 1, 2028, 00:00, and a frequency of &lt;strong&gt;Yearly&lt;/strong&gt;. This will ensure the reminder email is sent for the next five years.&lt;/p&gt;

&lt;p&gt;Next, drag a &lt;strong&gt;Send&lt;/strong&gt; action onto the canvas, and ensure a line connects the bottom of the &lt;strong&gt;Schedule&lt;/strong&gt; node to the top of the &lt;strong&gt;Send&lt;/strong&gt; node so that it’s clear that the send action follows the schedule trigger.&lt;/p&gt;

&lt;p&gt;Enter &lt;code&gt;refs.data.user_id&lt;/code&gt; as the user that the email should be sent to, and select your “Tax deadline approaching” notification template from the drop-down box. Now, click on &lt;strong&gt;Edit&lt;/strong&gt; next to &lt;strong&gt;Advanced&lt;/strong&gt; to edit some advanced properties. &lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/4fifzJIV2SX4wn6y17GRZc/f9f42eae85623285d04d7e762c3b5ba3/send_notifications_php_10.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/4fifzJIV2SX4wn6y17GRZc/f9f42eae85623285d04d7e762c3b5ba3/send_notifications_php_10.png" alt="Screenshot showing how to edit advanced properties for your email automation."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will use the &lt;strong&gt;Advanced&lt;/strong&gt; area to add some data to send to your automation template. This includes the &lt;code&gt;user_id&lt;/code&gt; referred to in the previous paragraph plus any variables that your &lt;strong&gt;Tax deadline approaching&lt;/strong&gt; notification template may be expecting.&lt;/p&gt;

&lt;p&gt;Add this JSON to the &lt;strong&gt;Data&lt;/strong&gt; section of the &lt;strong&gt;Advanced&lt;/strong&gt; area:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "John Doe",
  "user_id": "courier-user-id",
  "appUrl": "example.com/file-taxes",
  "companyName": "Acme Ltd"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/57VkOA1v2pQZjYq754jWkz/30f80cff078cfb88883764a1565aea57/send_notifications_php_11.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/57VkOA1v2pQZjYq754jWkz/30f80cff078cfb88883764a1565aea57/send_notifications_php_11.gif" alt="Screenshot showing how to add the user ID and other variables to your email automation."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, click &lt;strong&gt;Publish changes&lt;/strong&gt;. Your email notification will be sent on April 1, 2024, at midnight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending digests on a recurring schedule
&lt;/h2&gt;

&lt;p&gt;If your reason for sending recurring emails is that your users are subscribed to regular news or updates from your app, you may want to set up an email digest. A digest allows you to avoid overwhelming your users with too many emails by condensing a large number of emails into one regular email update. Courier now offers the ability to send email digests. For more information, see the &lt;a href="https://www.courier.com/docs/automations/digest/"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Sending scheduled or recurring emails is not the simplest thing to do in PHP, as it doesn't have a task scheduler built into the language. On top of this, using a third party library like Crunz to deal with scheduling includes an extra layer of complication, in that you have to edit your &lt;code&gt;crontab&lt;/code&gt;file to hand over scheduling responsibility from your cron system to Crunz. This requires at least a basic understanding of how cron jobs work, including the syntax needed to run them.&lt;/p&gt;

&lt;p&gt;The simpler option is to remove any need for scheduling tasks in PHP by using Courier's automation designer. This is a no-code solution that brings all your send logic inside the Courier UI. Aside from simplicity, an advantage of this is it allows your non-developer colleagues to be able to review or edit the logic around sending scheduled emails. &lt;/p&gt;

&lt;p&gt;On the other hand, if it's more important to you to keep your send logic locked down and version controlled, and if you're prepared to get to grips with using Crunz, then you just need to decide whether you want to send a simple email (either a single email or a recurring one) — in which case you should use option 1 — or if you need to add more logic to the sending of your notifications, with the possibility of chaining together multiple steps — in which case option 2 is best.&lt;/p&gt;

&lt;p&gt;If you haven’t yet joined Courier, you can &lt;a href="https://app.courier.com/signup"&gt;sign up today&lt;/a&gt; and get started immediately. If you’re an existing Courier user, you can easily try scheduling one of your existing notification templates in our &lt;a href="https://app.courier.com/automations"&gt;automations designer&lt;/a&gt;, or use our PHP SDK to get started with scheduled and recurring emails.&lt;/p&gt;

</description>
      <category>php</category>
      <category>webdev</category>
      <category>notifications</category>
      <category>api</category>
    </item>
    <item>
      <title>A Developer’s Guide to Notification APIs</title>
      <dc:creator>Oleksii Klochai</dc:creator>
      <pubDate>Wed, 26 Jul 2023 13:41:04 +0000</pubDate>
      <link>https://forem.com/courier/a-developers-guide-to-notification-apis-2n90</link>
      <guid>https://forem.com/courier/a-developers-guide-to-notification-apis-2n90</guid>
      <description>&lt;p&gt;While marketing-related notifications are often handled by marketing automation platforms, engineering teams require notification infrastructure that is designed for automated product-driven notifications. This might be a simple &lt;a href="https://www.courier.com/blog/how-to-send-password-resets-via-sms-and-email-using-node-js-and-next-js/"&gt;SMS password reset&lt;/a&gt; notification or new user onboarding email sequence. Or it may be a more complex notification tied to a feature of the application, such as an approval request sequence. &lt;/p&gt;

&lt;p&gt;The infrastructure required to handle these notifications is extensive. Logic is typically required to trigger on an event, follow a specific workflow, personalize content, follow compliance guidelines, respect user preference, and work intelligently across channels (eg. email, SMS, push, in-app inbox, chat, etc). And it may require advanced send logic such as &lt;a href="https://www.courier.com/docs/platform/automations/batching/"&gt;batching&lt;/a&gt;, &lt;a href="https://www.courier.com/docs/platform/automations/digest/"&gt;digesting&lt;/a&gt;, &lt;a href="https://www.courier.com/docs/platform/automations/throttle/"&gt;throttling&lt;/a&gt;, and &lt;a href="https://www.courier.com/docs/platform/automations/scheduling/"&gt;scheduling&lt;/a&gt; of notifications.&lt;/p&gt;

&lt;p&gt;This is precisely what notification APIs solve. A notification API is a combination of backend infrastructure and both server- and client-side SDKs that enable developers to build notifications in web and mobile apps. It's &lt;a href="https://app.courier.com/signup"&gt;free to signup&lt;/a&gt; and try &lt;a href="https://www.courier.com/"&gt;Courier&lt;/a&gt;, the leading Notification API, yourself. Otherwise, read on to learn more.&lt;/p&gt;

&lt;p&gt;Rather than developers spending time and effort building and maintaining the infrastructure on their own, Notification APIs give developers everything they need to create optimized, product-driven notifications that users will open and interact with.&lt;/p&gt;

&lt;p&gt;Notification APIs are used together with communication APIs like Twilio, Messagebird, Slack, and FCS—acting as an abstraction layer to enable notification use cases. As a result, integrating notifications into an application and maintaining that infrastructure becomes a swift and future-proof process.&lt;/p&gt;

&lt;p&gt;In this guide, we delve deeper into notification APIs, their role in transactional and marketing notifications, practical use cases, and the indirect benefits they offer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding and using notification APIs
&lt;/h2&gt;

&lt;p&gt;Here are some examples of Notification API features. These are capabilities that add notification capabilities to communication APIs such as Twilio, Microsoft Teams, MessageBird, Slack, and so on. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-channel send:&lt;/strong&gt; Notification APIs allow for dispatching notifications across &lt;a href="https://www.courier.com/docs/guides/tutorials/how-to-configure-multi-channel-routing/"&gt;multiple channels&lt;/a&gt;, like email, SMS, and push notifications. This frees developers from the complexities of maintaining individual infrastructures for each channel, streamlining the process considerably. For instance, an HR application might dispatch a job offer requiring a signature via SMS, a channel offering urgency and external reach, while using a tool like Slack—an internal, less urgent channel—for onboarding tasks with a new employee.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Delivery status awareness across channels:&lt;/strong&gt; A unique feature of notification APIs is their ability to track delivery status across all channels. This means, if an email, SMS, or push notification has been successfully delivered, it's accurately logged and reported. This insight enables developers to understand the efficacy of their communication across different platforms.&lt;/p&gt;

&lt;p&gt;Additionally, some sophisticated notification APIs also monitor “read statuses.” This means that when a user reads a notification on one platform, it can potentially halt the delivery or alter the display of notifications on other channels, for example marking them as opened or read. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automations:&lt;/strong&gt; From fetching the latest data for inclusion in a notification to setting up advanced delivery timings and rules across channels, notification APIs automate much of the orchestration process. Automations within notification APIs reduce manual effort and potential errors. This might involve sending a time-delayed, multi-channel sequence of notifications that stop as soon as the user reads them. Alternatively, it could involve digesting and batching frequent notifications based on preset or user-defined frequency or even throttling messages that trigger too often.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Template management:&lt;/strong&gt; Many notification APIs offer tools for developers to efficiently design, manage, and repurpose notification templates across various channels. These include pre-made templates as well as the option to create your own, eliminating the necessity of crafting notifications from scratch every time. This allows developers to focus more on the message and its intended impact, enhancing efficiency and overall user engagement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Central logs and reporting:&lt;/strong&gt; Robust logging and reporting capabilities are integral to notification APIs. This is especially relevant for notifications because it can present delivery status across channels in a single view. These features provide invaluable insights and aid in troubleshooting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User preferences:&lt;/strong&gt; Notification APIs provide a simple way to collect and respect user preferences for notification topics, channels, and frequencies, ensuring notifications don’t overwhelm users. Eg. a user might want to receive billing notifications via both SMS and email. But they may want to receive system error notifications via PagerDuty. And they may want to hold all comments on a project, to be rolled up into a single email digest every week. All of this is possible with a Notification API, which provides both the frontend components for the UI as well as the backend logic to respect these preferences.  If all notifications get sent through a notification API, the service becomes a useful tool for controlling users’ notification preferences. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web and mobile notification center (Inbox):&lt;/strong&gt; In addition to external channels like email, Slack, and SMS, it often makes sense to hava a notification center, or "inbox" that lives inside of the web or mobile app. This typically also includes a bell icon with a change badge that counts number of messages, as well as related push notifications.  A notification API will not only handle all the back-end logic for this functionality, but it will typically also offer a complete set of web and mobile SDKs for building the frontend experience. This allows developers to construct a fully functional in-app inbox and preference center with a notification API, elevating the overall user experience with minimal additional development time. Here's an example of &lt;a href="https://www.courier.com/inbox/"&gt;Courier's inbox offering&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internationalization:&lt;/strong&gt; Notification APIs offer the advantage of internationalization. If the API manages message templates, it’s possible to select a template appropriate for each user’s region and language or even work in sync with a translation API to serve translated versions of notification content. This ensures that each user receives personalized and localized notifications, further improving user engagement and satisfaction.&lt;/p&gt;

&lt;p&gt;By leveraging a notification API, a developer can save time on building these features without sacrificing the end users’ experience or creating technical debt.&lt;/p&gt;

&lt;h2&gt;
  
  
  The role of notification APIs in transactional versus marketing notifications
&lt;/h2&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/5YVtyABAeqWfiJx4kOhrbL/cdf9608d0a077fd184b342ca0a2cc5a6/Notification_API_2.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/5YVtyABAeqWfiJx4kOhrbL/cdf9608d0a077fd184b342ca0a2cc5a6/Notification_API_2.png" alt="A diagram summarizing transactional and marketing notification workflows"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notification APIs are typically used for transactional notifications. However, the transition away from moment-in-time marketing campaigns to ongoing Growth loops, is making Notification APIs more appropriate for marketing notifications than traditional marketing automation tools. To understand why that’s the case, let’s quickly define these two notification categories.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transactional notifications&lt;/strong&gt; are often triggered by user actions, such as making a purchase, resetting a password, or receiving a direct message. Or they may be tied to the functionality of a product feature - like a commenting feature in the app where you want to notify a person of an @mention.  As their name suggests, these notifications are tied to specific transactions or interactions a user has with the application, playing a continuous role in user experience. They might rely on external channels like email and SMS or, for SaaS apps, they may be used with internal channels such as Slack, MS Teams, and PagerDuty.&lt;/p&gt;

&lt;p&gt;Notification APIs prove particularly useful for transactional notifications due to their dynamic and event-triggered nature. By leveraging APIs, these real-time, personalized messages can be handled as they are generated, ensuring relevance.&lt;/p&gt;

&lt;p&gt;On the other hand, &lt;strong&gt;marketing notifications&lt;/strong&gt; are traditionally associated with promotional time-bound campaigns for a product, offer, or service. These messages focus on driving conversions or sales. Unlike transactional notifications, marketing notifications usually aren’t specific to the user or their activity in the app but instead get sent to larger groups of users. Marketing notifications also focus on external channels like email, SMS, push, and in-app.&lt;/p&gt;

&lt;p&gt;Marketing notifications have traditionally been managed through a marketing platform due to their mass distribution nature and the connection to marketing campaigns. Specialized marketing platforms typically address the need for features such as opt-in logic to comply with anti-spam regulations, campaign management, and detailed analytics of the conversion process.&lt;/p&gt;

&lt;p&gt;However, product growth experiments now cross the divide of marketing and are often more appropriate for Notification APIs than marketing automation tools. For example, if a user hits a key usage lifecycle milestone in your application, you may want to trigger a notification with a unique offer or with best practices to ensure their success. These kinds of notifications can drive higher application engagement and overall monetization of the app.&lt;/p&gt;

&lt;p&gt;Over time, notification APIs have the potential to bridge the gap between transactional and marketing notifications. This potential stems from notification APIs’ ability to offer more personalized, event-driven marketing notifications that adhere to the user’s behavior and preferences.&lt;/p&gt;

&lt;p&gt;In essence, notification APIs offer a robust framework that supports both transactional and marketing notifications, creating a cohesive and engaging user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of using a notification API for developers
&lt;/h2&gt;

&lt;p&gt;Notification APIs offer numerous indirect benefits that enhance efficiency, increase flexibility, and improve the developer experience.&lt;/p&gt;

&lt;p&gt;One key advantage of notification APIs is provider independence. APIs abstract the underlying implementation details, allowing developers to switch providers (eg. from Postmark to SenGrid) swiftly if necessary without disrupting the overall application function. They can even provide failover between channels and providers without having to build out complex logic.&lt;/p&gt;

&lt;p&gt;Notification APIs also offer consistency in notification formatting and delivery across various channels. Consistency improves user experience by ensuring each message is uniform, regardless of the channel through which it is sent.&lt;/p&gt;

&lt;p&gt;From a developer’s perspective, APIs simplify the integration and management of notification systems. Developers don’t need to write boilerplate code for every new channel or message type or worry if their abstractions will carry over into a new provider’s API schema. Instead, they leverage the API’s functionality and use whichever providers they need, which can save considerable time and effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample use cases for notification APIs
&lt;/h2&gt;

&lt;p&gt;Here are some examples of what you could build in your product using a notification API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Status updates:&lt;/strong&gt; Inform users about the progression of their initiated actions, such as “Your order is out for delivery” in a food delivery app context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Appointment reminders:&lt;/strong&gt; Remind users about upcoming appointments, deadlines, or important dates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Approval requests:&lt;/strong&gt; Request user approval for specific actions, such as document sharing or data access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication management:&lt;/strong&gt; Handle password resets or two-factor authentication prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirmation requests:&lt;/strong&gt; Ask users to confirm potentially irreversible actions or decisions, such as deleting data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Billing notifications:&lt;/strong&gt; Inform users about upcoming payments, send payment confirmations, or notify them of billing issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated invites:&lt;/strong&gt; Send automated invitations to events or cooperative endeavors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Digests:&lt;/strong&gt; Provide digests or summaries on user-selected topics at a frequency and channel set by the user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E-commerce:&lt;/strong&gt; Handle cart abandonment notifications, shipping updates, or requests for credit card updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product engagement:&lt;/strong&gt; Prompt users to return and complete a task, enhancing user engagement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Survey requests:&lt;/strong&gt; Solicit user feedback through surveys or review requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Welcome and user onboarding messages:&lt;/strong&gt; Help new users get started with welcome messages and onboarding instructions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notify about a user’s activity:&lt;/strong&gt; Alert users about new logins or changes to a shared project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform engagement:&lt;/strong&gt; Encourage users to engage with a platform or service more frequently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Critical alerts:&lt;/strong&gt; Notify users about critical issues, such as security alerts, product downtime, or other urgent matters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In each of these use cases, notification APIs streamline the process of sending timely, relevant, and personalized notifications to users, enhancing user engagement and satisfaction.&lt;/p&gt;

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

&lt;p&gt;Notification APIs have emerged as tools that enable developers to build product notification experiences that users love. By offering a streamlined way to manage notification content, delivery logic, internationalization, compliance, and user preferences, notification APIs reduce the complexity of building and maintaining the underlying infrastructure.&lt;/p&gt;

&lt;p&gt;Notification APIs also help improve the user experience. By running all notifications through a single service, it’s possible to offer users more flexible preferences and cross-channel syncing of notification statuses. Prior to Notification APIs, only the largest, most sophisticated engineering teams could build this level of infrastructure in-house.&lt;/p&gt;

&lt;p&gt;If you are interested in using a notification API, &lt;a href="https://www.courier.com/"&gt;Courier&lt;/a&gt; is considered the leader in the market, funded by Twilio, Slack, and Google and used by companies such as Comcast, LaunchDarkly, Contentful, and Lattice. Courier is free to use for up to 10,000 notifications per month.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>api</category>
      <category>notifications</category>
    </item>
    <item>
      <title>Courier Inbox for web and mobile, a complete notification center</title>
      <dc:creator>Micah Zayner</dc:creator>
      <pubDate>Wed, 14 Jun 2023 07:42:59 +0000</pubDate>
      <link>https://forem.com/courier/courier-inbox-for-web-and-mobile-a-complete-notification-center-4ai4</link>
      <guid>https://forem.com/courier/courier-inbox-for-web-and-mobile-a-complete-notification-center-4ai4</guid>
      <description>&lt;p&gt;📣 &lt;strong&gt;Join the conversation on &lt;a href="https://www.producthunt.com/posts/courier-inbox-inapp-notification-center/"&gt;Product Hunt&lt;/a&gt; where we're discussing this groundbreaking launch and the future of in-app notifications.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.producthunt.com/posts/courier-inbox-inapp-notification-center?utm_source=badge-featured&amp;amp;utm_medium=badge&amp;amp;utm_souce=badge-courier-inbox-inapp-notification-center"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W9nZ7ov---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://api.producthunt.com/widgets/embed-image/v1/featured.svg%3Fpost_id%3D397476%26theme%3Dlight" alt="Courier Inbox: InApp Notification Center - A drop-in notification center for your web and mobile apps | Product Hunt" width="250" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A notification center inside of web and mobile apps is now an expectation. It’s a way to reach specific audiences or users with tailored messages and a way to boost engagement by bringing people back into the app. &lt;/p&gt;

&lt;p&gt;While Courier has been adding Inbox capabilities over the last couple years, we’re excited to announce a complete set of SDKs that span web and mobile. You can drop in a full-featured inbox to give your users a best-in-class notification center inside your app that works seamlessly with your existing notification flows.&lt;/p&gt;

&lt;p&gt;Here are just a few features of Courier Inbox:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;All the code needed&lt;/strong&gt; to build custom notification lists that show new messages when they arrive in real time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prebuilt-UI&lt;/strong&gt; that allows you to add a notification center to your app in minutes rather than months.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API, event or manually triggered notifications&lt;/strong&gt; to your user’s inbox, or using inbox as one step in a multichannel sequence that includes email, Slack, or any channel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synchronization of message status&lt;/strong&gt; across web and mobile inboxes, as well as other channels used like email and SMS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User notification preferences&lt;/strong&gt; to offer more control to your users over what notifications they receive from your app and which channels work best for them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To see the full set of features for Courier Inbox, head to &lt;a href="https://www.courier.com/docs/inbox/"&gt;the docs&lt;/a&gt;. Or, if you’d like to see an example of what you can build with Courier, check out our Instagram-inspired IOS app, &lt;a href="https://www.courier.com/blog/introducing-puppygram-powered-by-courier-inbox-next-js-and-inngest"&gt;Puppygram&lt;/a&gt; or see how inbox is used at &lt;a href="https://www.courier.com/blog/courier-inbox-complete-notification-center-web-mobile/#real-world-examples"&gt;LaunchDarkly, DroneDeploy, and Oyster HR&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/5TOVXtSVaIFCcad0L9i6QC/8f969b15380189effd777c71eeb4a88f/inbox_UI.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/5TOVXtSVaIFCcad0L9i6QC/8f969b15380189effd777c71eeb4a88f/inbox_UI.gif" alt="inbox UI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Options to build with Courier Inbox
&lt;/h2&gt;

&lt;p&gt;Previously, it was only feasible for large engineering teams to pull off a full-fledged notification inbox. Smaller teams often found themselves strained by the sheer scope of the project. Besides the engineering challenges, the design and user interface for the notification inbox also required thoughtful attention. Even though standard patterns exist in popular apps, like Instagram and Amazon, there's pressure to deliver a user-friendly experience that’s on-brand and doesn’t compromise the aesthetic integrity of the overall application.&lt;/p&gt;

&lt;p&gt;This was an important driver for Courier Inbox. We wanted to make sure we offered complete SDKs for web, Android and IOS, where a developer has access to the development tools and UI components so that the frontend is as well designed as the backend. Courier also offers &lt;a href="https://www.courier.com/docs/courier-designer/brands/how-to-brand-inbox-toast/"&gt;customizable branding design options&lt;/a&gt;, to match your inbox to your application's look and feel.&lt;/p&gt;

&lt;p&gt;Whether you're looking for a fully hosted implementation that requires minimal configuration or a composable, headless offering that you can tailor to your specific needs, Courier has got you covered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-world examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  DroneDeploy
&lt;/h3&gt;

&lt;p&gt;As a leader in drone mapping software, &lt;a href="https://www.dronedeploy.com/"&gt;DroneDeploy&lt;/a&gt; offers services that capture interior and exterior visual data of a construction project or other environment, managing drone fleets for site documentation and analysis.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With Courier, we added a beautiful inbox and in-app push notifications in a matter of weeks. We used the great looking pre-built component to save even more time. Notifications are not our core competency, so it made complete sense to integrate rather than build out and support our own implementation. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;James Pipe&lt;/strong&gt;, VP of Product, DroneDeploy&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;DroneDeploy has integrated Courier's inbox into their web application as a notification center. This has significantly improved customer communications, providing timely updates and important information to clients directly within the app. &lt;/p&gt;

&lt;p&gt;Top notifications sent through their inbox include status updates when new maps, walkthroughs, or progress videos are uploaded, and edit access is requested/approved/declined.&lt;/p&gt;

&lt;h3&gt;
  
  
  LaunchDarkly
&lt;/h3&gt;

&lt;p&gt;LaunchDarkly offers a feature management platform to developers and DevOps engineers. The platform offers multivariate feature flags, which enables A/B testing and the ability to incrementally roll out new features.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We were able to build the in-app notification experience that we wanted with excellent support and communication from the Courier staff. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lucy Wonsower&lt;/strong&gt;, Software Engineer, LaunchDarkly&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;LaunchDarkly uses Courier's inbox for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Managing event notifications for their feature management platform, such as requests for a new feature flag, or approvals of a feature flag request. The notification inbox speeds up these requests and approvals, thereby increasing value and customer retention.&lt;/li&gt;
&lt;li&gt;Sending team notifications such as team membership admin alerts, new user invites, welcome emails, and email verification messages.&lt;/li&gt;
&lt;li&gt;Billing notifications such as notifications that a user’s card was charged or that there was a failure to charge a card. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Oyster HR
&lt;/h3&gt;

&lt;p&gt;Another organization that has reaped significant benefits from Courier's notification inbox is &lt;a href="https://www.oysterhr.com/"&gt;Oyster HR&lt;/a&gt;. As a global employment platform, Oyster HR enables businesses to hire, pay, and manage employees from across the world without the need to set up business entities in each country.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using Courier Inbox, Oyster saved 4 engineers 3 months of work from not having to construct a notification infrastructure, design a UI, and develop them to spec. But the most important benefit is that as Oyster scales, we won't need to hire additional engineers solely to manage our notification framework as the volume grows. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amy Weinrieb&lt;/strong&gt;, Senior Product Manager, Oyster HR&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Integrating Courier's notification inbox
&lt;/h2&gt;

&lt;p&gt;One of the standout features of Courier's notification inbox is its simplicity of integration. Whether it's a mobile or a web application, a few lines of code are all you need to embed a fully functional notification inbox into your application. &lt;/p&gt;

&lt;p&gt;Here we have examples for adding an inbox to your web, IOS, and Android applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a notification center to your web application
&lt;/h3&gt;

&lt;p&gt;For web applications, you can use either the &lt;a href="https://www.courier.com/docs/inbox/web/react-sdk/"&gt;Courier React SDK&lt;/a&gt; or the vanilla &lt;a href="https://www.courier.com/docs/inbox/web/javascript-sdk/"&gt;JavaScript SDK&lt;/a&gt;. Here is a simple React example to illustrate this process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//App.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CourierProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@trycourier/react-provider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Inbox&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@trycourier/react-inbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Replace 'yourUserId' and 'YOUR_CLIENT_KEY' with your own details&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yourUserId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_CLIENT_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CourierProvider&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;clientKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;clientKey&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Inbox&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/CourierProvider&lt;/span&gt;&lt;span class="err"&gt;&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;The above code is all it takes to integrate Courier's notification inbox into your React application. You just need to import CourierProvider and Inbox from &lt;a href="https://www.npmjs.com/package/@trycourier/react-provider"&gt;@trycourier/react-provider&lt;/a&gt; and &lt;a href="https://www.npmjs.com/package/@trycourier/react-inbox"&gt;@trycourier/react-inbox&lt;/a&gt; respectively. Then, you set the userId and clientKey within the CourierProvider, and place the Inbox component within it. Look at the &lt;a href="https://github.com/trycourier/courier-react/tree/main/packages/react-inbox"&gt;README&lt;/a&gt; on GitHub if you need more information.&lt;/p&gt;

&lt;p&gt;The userId and clientKey are crucial for Courier to know who's using the inbox and to ensure the proper messages are displayed. The clientKey is a public-facing key that can be found by navigating to "Settings &amp;gt; &lt;a href="https://app.courier.com/settings/api-keys"&gt;API keys&lt;/a&gt;" in the Courier app.&lt;/p&gt;

&lt;p&gt;The snippet uses the basic authentication provided by Courier. However, for enhanced security, it is recommended to use JWT Authentication. The complete guide to set up JWT Authentication can be found &lt;a href="https://www.courier.com/docs/inbox/authentication/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a notification center to your IOS application
&lt;/h3&gt;

&lt;p&gt;Here is an example for an iOS application written in Swift:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Courier_iOS&lt;/span&gt;

&lt;span class="c1"&gt;// Create the view&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;courierInbox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;CourierInbox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;didClickInboxMessageAtIndex&lt;/span&gt;&lt;span class="p"&gt;:&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;index&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isRead&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markAsRead&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markAsUnread&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&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="nv"&gt;didClickInboxActionForMessageAtIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;action&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;index&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&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;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nv"&gt;didScrollInbox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;scrollView&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scrollView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contentOffset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&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="c1"&gt;// Add the view to your UI&lt;/span&gt;
&lt;span class="n"&gt;courierInbox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;translatesAutoresizingMaskIntoConstraints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSubview&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;courierInbox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Constrain the view how you'd like&lt;/span&gt;
&lt;span class="kt"&gt;NSLayoutConstraint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;activate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="n"&gt;courierInbox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;topAnchor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;equalTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;topAnchor&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;courierInbox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottomAnchor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;equalTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottomAnchor&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;courierInbox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leadingAnchor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;equalTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leadingAnchor&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;courierInbox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailingAnchor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;equalTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailingAnchor&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="kt"&gt;Task&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="kt"&gt;Courier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"pk_prod_H12..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;clientKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"YWQxN..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"example_user_id"&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;This approach exemplifies the ”drop-in” method. You begin by importing the Courier_iOS package, add the view to your app, then sign in to your Courier account using your access token, client key, and user ID. The CourierInbox, for UIKit, and the CourierInboxView for SwiftUI, is then placed in your app how you’d like and, instantly embedding the notification inbox into your application with minimal effort. It's a quick and efficient way to get started, allowing developers to focus on building the core aspects of their app. This way, you can offer a powerful notification inbox to your users without spending significant time on implementation — and, more importantly, without compromising on the feature set.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a notification center to your Android application
&lt;/h3&gt;

&lt;p&gt;For those interested in Android, here is the default inbox example for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="nl"&gt;inbox:&lt;/span&gt; &lt;span class="nc"&gt;CourierInbox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findViewById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;courierInbox&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;inbox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setOnClickMessageListener&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isRead&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;markAsRead&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;markAsUnread&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="nc"&gt;Courier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;inbox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setOnClickActionListener&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;Courier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;lifecycleScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;launch&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Courier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signIn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"pk_prod_H12..."&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;clientKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YWQxN..."&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"example_user_id"&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code snippet showcases the power of the Courier library in Android development, demonstrating the ability to log, mark messages as read or unread, and capture actions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alternative, headless approach to building an inbox with Courier
&lt;/h3&gt;

&lt;p&gt;But what if you need more control over your notification inbox's appearance and behavior? Courier also offers a headless option. This approach allows developers to customize every aspect of their inbox, tailoring it to meet specific design or functional requirements. You have the flexibility to change everything from the overall layout and individual components to the styling of each notification card. This way, Courier ensures that developers can create an inbox that not only fits their needs but also aligns perfectly with their application's UI and UX.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;Whether you’re working on web or mobile app development, Courier provides a comprehensive, flexible, and easily integrable solution to ensure your users are always in the know and keep coming back to your app.&lt;/p&gt;

&lt;p&gt;It’s &lt;a href="https://app.courier.com/signup"&gt;free to try&lt;/a&gt;. You can send 10,000 messages every month for no cost as you get to know the ins and outs of what’s possible with Inbox. To help you get started, we suggest exploring the detailed guides for each platform: &lt;a href="https://www.courier.com/docs/inbox/mobile/ios-sdk/"&gt;iOS&lt;/a&gt;, &lt;a href="https://www.courier.com/docs/inbox/mobile/android-sdk/"&gt;Android&lt;/a&gt;, and &lt;a href="https://www.courier.com/docs/inbox/web/javascript-sdk/"&gt;web&lt;/a&gt;. These comprehensive guides provide step-by-step instructions and code examples to guide you through the integration process.&lt;/p&gt;

&lt;p&gt;Don't forget, Courier also provides seamless integration with push notifications. We've previously covered how to &lt;a href="https://www.courier.com/blog/android-push-notifications-with-firebase-courier-sdk/"&gt;set up push notifications with Courier&lt;/a&gt;. By combining these two  powerful features, you can provide a complete, personalized notification experience to your users.&lt;/p&gt;

&lt;p&gt;Remember, providing a top-notch notification experience to your users doesn't have to be a daunting task. If you want to build a custom notification inbox that is not only user-friendly and efficient but also easily integrable across platforms, &lt;a href="https://app.courier.com/signup"&gt;start your notifications journey&lt;/a&gt; with Courier today!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Create an Automated SMS Notification System</title>
      <dc:creator>Charla Bigelow</dc:creator>
      <pubDate>Tue, 18 Apr 2023 06:40:00 +0000</pubDate>
      <link>https://forem.com/courier/how-to-create-an-automated-sms-notification-system-17oj</link>
      <guid>https://forem.com/courier/how-to-create-an-automated-sms-notification-system-17oj</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;All apps need a solid, automated notifications system. Whether it’s reminders, updates, or alerts, some notifications can be urgent and time-sensitive, in which case SMS is the most effective communication channel.&lt;/p&gt;

&lt;p&gt;Let’s take a moment to talk about what that means for you as a developer. You need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;store data on how each individual user is interacting with your app,&lt;/li&gt;
&lt;li&gt;design personalized messages that inform your users based on different activities,&lt;/li&gt;
&lt;li&gt;respect your user’s communication preferences to avoid notification fatigue,&lt;/li&gt;
&lt;li&gt;and view logs in a centralized location for efficient debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Realistically, building this feature from scratch can be time-consuming and complicated. You risk wasting time on simple tasks like integrating with SMS providers, managing message delivery, and scaling your system to handle increased message volume.&lt;/p&gt;

&lt;p&gt;To simplify this process, we will use Courier, which provides a layer of abstraction over multiple SMS providers, making integration easier. It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CDP integrations to send automated messages based on user activity&lt;/li&gt;
&lt;li&gt;message delivery tracking and retry mechanisms, which can help ensure reliable message delivery&lt;/li&gt;
&lt;li&gt;scalable architecture, which can handle increased message volume as your application grows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial will cover everything you need to know to set up an effective and efficient automated SMS notification system using Courier. Let’s begin.&lt;/p&gt;

&lt;h1&gt;
  
  
  Send with SMS
&lt;/h1&gt;

&lt;p&gt;The following is a simple API call that sends SMS messages with Courier, adapted from the &lt;a href="https://www.courier.com/docs/guides/getting-started/nodejs/" rel="noopener noreferrer"&gt;Node.js quick start&lt;/a&gt;: &lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CourierClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@trycourier/courier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;courier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CourierClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;authorizationToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;auth_token&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendSMS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;requestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;courier&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;br&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
            &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
                &lt;span class="na"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123-456-7890&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;&lt;br&gt;
            &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
                &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
                &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thanks for signing up, {{name}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;&lt;br&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Peter Parker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;&lt;br&gt;
            &lt;span class="na"&gt;routing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
                &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;single&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
                &lt;span class="na"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sms&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;br&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;&lt;br&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;&lt;br&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nf"&gt;sendSMS&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Integrate SMS API&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;You can use Twilio or &lt;a href="https://www.courier.com/docs/guides/providers/sms/" rel="noopener noreferrer"&gt;any of the following providers&lt;/a&gt; based on your preference.&lt;/p&gt;

&lt;p&gt;** Step 1: &lt;a href="https://www.twilio.com/try-twilio" rel="noopener noreferrer"&gt;Sign up for Twilio&lt;/a&gt;**&lt;/p&gt;

&lt;p&gt;** Step 2: Set up your preferred SMS API in &lt;a href="https://app.courier.com/channels" rel="noopener noreferrer"&gt;channels&lt;/a&gt;**&lt;/p&gt;

&lt;p&gt;Each Courier Integration needs specific information based on the Integration provider's requirements (check the &lt;strong&gt;Provider Documentation&lt;/strong&gt; section on the left sidebar for each Integration's needs).&lt;/p&gt;

&lt;p&gt;For Twilio, you will need to provide an &lt;strong&gt;&lt;a href="https://console.twilio.com/" rel="noopener noreferrer"&gt;Account SID&lt;/a&gt;&lt;/strong&gt;, an &lt;strong&gt;&lt;a href="https://console.twilio.com/" rel="noopener noreferrer"&gt;Auth Token&lt;/a&gt;&lt;/strong&gt;, and a &lt;strong&gt;&lt;a href="https://www.twilio.com/docs/messaging/guides/best-practices-at-scale" rel="noopener noreferrer"&gt;Messaging Service SID&lt;/a&gt;&lt;/strong&gt;, which you will get directly from Twilio. If you don’t have a Messaging Service SID from Twilio, you can add a &lt;strong&gt;From Number&lt;/strong&gt; instead.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/y0Djn4VAYJTNo2WFFN0Wi/dc791a6c406960a0c416bf1b03d17899/image-1.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/y0Djn4VAYJTNo2WFFN0Wi/dc791a6c406960a0c416bf1b03d17899/image-1.png" alt="Add Twilio channel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you sign in to Twilio, click the house icon on the sidebar to go to the &lt;strong&gt;Dashboard&lt;/strong&gt;. On this page, you'll see a section called &lt;strong&gt;Project Info&lt;/strong&gt;, which shows your &lt;strong&gt;Account SID&lt;/strong&gt; and &lt;strong&gt;Auth Token&lt;/strong&gt;. Copy these and paste them into the matching fields on Courier's Twilio Integration page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/.%2Fimages%2Fimage-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/.%2Fimages%2Fimage-2.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/2IDv94v66vmxo2AxU1ocmT/3f6083af3496e761c77c9d1f18ad35e0/image-2.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/2IDv94v66vmxo2AxU1ocmT/3f6083af3496e761c77c9d1f18ad35e0/image-2.png" alt="Twilio account info"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find more information on how to get a phone number from Twilio and how to set up a Messaging Service SID in our &lt;a href="https://www.courier.com/docs/guides/providers/sms/twilio/" rel="noopener noreferrer"&gt;Twilio documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Your Notification(s)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create a new template&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to the Courier Designer and click on the &lt;strong&gt;Create Notification&lt;/strong&gt; button to create a new notification template. You will need to give your notification a name (otherwise it will default to “Untitled Notification”. You can choose to use AI to generate content based on the name you chose.&lt;/p&gt;

&lt;p&gt;Leave the Subscription Topic blank for now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Select your preferred channel and integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this case, you will use the SMS channel and Twilio integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Customize your message and publish changes when complete&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;** Step 4: Add links to the Preference Center**&lt;/p&gt;

&lt;p&gt;You’ll set up your Preference Center later in this tutorial, but you can add links to the Preference Center here by including &lt;code&gt;({$.urls.preferences})&lt;/code&gt; in the message or hyperlinking text with &lt;code&gt;{$.urls.preferences}&lt;/code&gt;. &lt;a href="https://www.courier.com/docs/courier-preferences/preference-center/hosted-page/#adding-preferences-link-to-notification-text" rel="noopener noreferrer"&gt;Learn more.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optional Step 4: Test your event&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To confirm that your message is appearing the way you’d expect it to, go to the Preview tab and create a new test event. Replace the value of &lt;code&gt;phone_number&lt;/code&gt; in the JSON with a number you would like to receive the test SMS at. Click create and proceed to the Send tab. Click Send Test to receive the test message. Click on the Design tab to revise the message until you are satisfied with the way it looks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.courier.com/docs/guides/tutorials/how-to-design-a-notification-template/" rel="noopener noreferrer"&gt;Learn more about designing templates.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Repeat this process to create all notifications you need to send via SMS&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create an Automation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: &lt;a href="https://app.courier.com/automations" rel="noopener noreferrer"&gt;Create a new Automation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Drag and drop your preferred trigger&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have integrated a CDP in Courier and want to send notifications based on events being tracked within your application, you can choose any of them as the trigger (Segment or Rudderstack).&lt;/p&gt;

&lt;p&gt;This will require you to have the integration setup within the CDPs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://segment.com/docs/connections/destinations/catalog/courier/" rel="noopener noreferrer"&gt;Send Segment events to Courier&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rudderstack.com/docs/destinations/streaming-destinations/courier/" rel="noopener noreferrer"&gt;Send Rudderstack events to Courier&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Drag and drop a Send step&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Connect the notification template based on which message you want to send with this trigger.&lt;/p&gt;

&lt;p&gt;Edit the recipient information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add a &lt;code&gt;phone_number&lt;/code&gt; field to send to a specific number,&lt;/li&gt;
&lt;li&gt;add a &lt;code&gt;user_id&lt;/code&gt; to send to a specific contact within your [Courier Users database](&lt;a href="https://app.courier.com/users0" rel="noopener noreferrer"&gt;https://app.courier.com/users0&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;or add a &lt;code&gt;list_id&lt;/code&gt; to send to a list of users (another way to do this is to use the Send to List step)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Publish the Automation template&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.courier.com/docs/automations/designer/" rel="noopener noreferrer"&gt;Learn more about designing Automation templates&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up user preferences
&lt;/h2&gt;

&lt;p&gt;To allow your users to decide how they receive messages, you can use Subscription Topics to categorize your notifications and give users the ability to opt in/out of these Topics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create Subscription Topics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Head over to the &lt;a href="https://app.courier.com/designer/preferences" rel="noopener noreferrer"&gt;Preferences Designer&lt;/a&gt; and add your Topics. Some examples are “Marketing Messages,” “Billing Alerts,” and “Critical Messages.” You can edit the Default State of each Topic to decide whether users can opt in/out or if they are required to receive these notifications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Link the Notification Templates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edit your Topics to link the Templates you created earlier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optional Step 3: Enable Channel Delivery Customization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can also edit the Section settings (a Section groups multiple topics together) and enable Channel Delivery Customization so users can decide which channel they receive messages on. This means that if a user opts out of “SMS” notifications for a Section, they will not receive any SMS notifications within the Topics of that Section.&lt;/p&gt;

&lt;p&gt;Learn more about the &lt;a href="https://www.courier.com/docs/courier-preferences/preference-center/designer/" rel="noopener noreferrer"&gt;Preferences Designer&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Best Practices for SMS Notifications
&lt;/h1&gt;

&lt;p&gt;The ease and convenience of SMS have made it an effective and popular method for delivering messages to customers, employees, and stakeholders. However, best practices must be followed to ensure the effectiveness of SMS notifications. Here are some of the best practices for SMS notifications:&lt;/p&gt;

&lt;h2&gt;
  
  
  A. Timing and frequency of SMS notifications
&lt;/h2&gt;

&lt;p&gt;SMS notifications require precise timing and frequency to be effective. The notifications should be sent at the optimal time for the recipient to read and respond to the message. For example, a retail store may send SMS notifications to customers with promotions and discounts during the holiday season or a special sale event. Similarly, a healthcare provider may send reminders to patients for upcoming appointments or medication refills. It is also important to avoid overloading the recipient with too many messages. Finding the right balance between frequency and relevance is crucial to ensure that SMS notifications are well-received and effective.&lt;/p&gt;

&lt;h2&gt;
  
  
  B. Personalizing the SMS notifications for each recipient
&lt;/h2&gt;

&lt;p&gt;Personalization is a key factor in delivering effective SMS notifications. By personalizing the message with the recipient's name, location, or other relevant information, it becomes more engaging and meaningful. Personalized SMS notifications can also help to build stronger relationships between the sender and recipient. For example, a fitness center may send SMS notifications to members with personalized workout plans based on their fitness goals and progress. Similarly, a bank may send personalized SMS notifications to customers with account balances and transaction details.&lt;/p&gt;

&lt;h2&gt;
  
  
  C. Measuring the success of SMS notifications with analytics
&lt;/h2&gt;

&lt;p&gt;Analytics can provide valuable insights into how the recipient is engaging with the message. For example, open rates, click-through rates, and conversion rates can indicate the effectiveness of the SMS notification. By analyzing these metrics, the sender can identify areas for improvement and make data-driven decisions. Analytics can also help to refine the timing and frequency of SMS notifications.&lt;/p&gt;

&lt;h2&gt;
  
  
  D. Improving the SMS notification strategy based on recipient engagement
&lt;/h2&gt;

&lt;p&gt;Finally, we can continuously improve the SMS notification strategy based on recipient engagement. By soliciting feedback from recipients, the sender can better understand their preferences and needs. For example, a survey or feedback form can be included in the SMS notification to gather feedback from the recipient. Based on this feedback, the sender can adjust the timing, frequency, and content of the SMS notifications to meet the recipient's needs better.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Now you have a completely automated SMS notification system that respects your user’s preferences. Creating an automated SMS notification system with Courier and Twilio is a powerful way to enhance customer communication. Courier's advanced features, like multi-channel support, pre-built templates, and detailed analytics, make it a great tool for managing all your notifications in one place. Twilio's SMS API is easy to use and provides a wide range of features, like two-factor authentication and automated responses, to help you create an efficient and secure notification system. Combining these two powerful tools allows you to create a notification system that meets your business needs and helps you stay connected with your customers.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>tutorial</category>
      <category>twilio</category>
    </item>
    <item>
      <title>New Datadog integration for Courier notification logs and metrics</title>
      <dc:creator>Charla Bigelow</dc:creator>
      <pubDate>Wed, 12 Apr 2023 16:00:00 +0000</pubDate>
      <link>https://forem.com/courier/new-datadog-integration-for-courier-notification-logs-and-metrics-18k1</link>
      <guid>https://forem.com/courier/new-datadog-integration-for-courier-notification-logs-and-metrics-18k1</guid>
      <description>&lt;p&gt;The ability to unify all notification metrics and logs across channels and providers into an easy-to-use dashboard is a core advantage of Courier’s notification infrastructure. &lt;/p&gt;

&lt;p&gt;However, with product notifications so critical to the entire application experience, it’s important to connect that data back to central cloud observability platforms that look across the entire stack. This gives platform engineering teams a complete understanding of application health and lets them quickly troubleshoot even the most complex issues.&lt;/p&gt;

&lt;p&gt;Today, we’re incredibly excited to announce our first observability integration with Datadog.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.datadoghq.com/"&gt;Datadog&lt;/a&gt; is a tool for collecting metrics and other data from applications and viewing them in a centralized place. Datadog’s dashboards and monitoring tools build a more accurate picture of the health of your application and how it changes over time.&lt;/p&gt;

&lt;p&gt;Our integration with Datadog is easy to spin up when you use our “dashboard starter kit.” This consists of some pre-configured JSON to set up a simple dashboard in Datadog for your Courier data.&lt;/p&gt;

&lt;p&gt;Our Datadog integration is currently only available on Courier’s Business plan, much like our other production-focused features such as &lt;a href="https://www.courier.com/docs/guides/business/analytics/#template-analytics-notification-metrics"&gt;template analytics&lt;/a&gt;, &lt;a href="https://www.courier.com/docs/guides/business/okta-integration/"&gt;Okta integration for SSO&lt;/a&gt;, and &lt;a href="https://www.courier.com/docs/courier-preferences/preference-center/introduction/"&gt;advanced user preferences&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fastest way to pull your notification data into Datadog
&lt;/h2&gt;

&lt;p&gt;Courier's &lt;a href="https://www.courier.com/docs/notification-data/message-logs/"&gt;message logs&lt;/a&gt; and analytics dashboard are optimized for helping product teams understand everything about the messaging use case — the status of notifications, recipients, lists, automations, and more. It brings all this data together across channels and providers in one place and provides the fastest way to learn about your notifications and troubleshoot notifications-related issues. &lt;/p&gt;

&lt;p&gt;However, many organizations need to understand how notifications interact with the rest of the tech stack or would prefer to view and store all logs and metrics data in one place. &lt;/p&gt;

&lt;p&gt;Until now, the only way to pull this data outside of Courier was to build your own bespoke solution, by listening to Courier’s outbound webhooks and writing custom code. But now the Datadog integration enables sending information about health and performance directly to your own monitoring system, which is much more convenient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Notification metrics and logs
&lt;/h3&gt;

&lt;p&gt;The most obvious use cases involve sending data about the health and delivery status of your notifications. This could include metrics such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Percentage of messages that are successfully sent, delivered, opened, and clicked.&lt;/li&gt;
&lt;li&gt;Delivery errors&lt;/li&gt;
&lt;li&gt;Percentage of customers who are unsubscribing from your messages&lt;/li&gt;
&lt;li&gt;Any metrics that measure outliers — for example, a metric that checks if you are sending either more or fewer messages than you should be.&lt;/li&gt;
&lt;li&gt;Number of people who opened your emails over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/3lM8WS2Gycadc9PLXOQPHi/5e2a92ec8a1bda6dedc4a55136c8bdbb/datadog-courier-integration.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/3lM8WS2Gycadc9PLXOQPHi/5e2a92ec8a1bda6dedc4a55136c8bdbb/datadog-courier-integration.png" alt="datadog-courier-integration"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(An example Datadog dashboard showing key notification health metrics)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/7kIbn1d7NZu1aN43JrG7HD/4fce7f34bba7d074e13a3a52e1bf3fd5/click_and_open_rate_email.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/7kIbn1d7NZu1aN43JrG7HD/4fce7f34bba7d074e13a3a52e1bf3fd5/click_and_open_rate_email.png" alt="Datadog click and open rate tracking"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(A Datadog graph showing the number of emails that are being sent over the course of the day — as well as how many emails are being opened and how many people are clicking on email links. There are options to compare these metrics to other time periods such as the previous day, week, or quarter.)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Feature-specific metrics and logs
&lt;/h3&gt;

&lt;p&gt;The integration also supports data from Courier platform features. This can provide even more color on how notifications support your business or operational goals. For example, If you use &lt;a href="https://www.courier.com/blog/automations-notification-workflow-designer/"&gt;Courier Automations&lt;/a&gt; to build smart notification workflows, you may want to monitor how many times each automation has been invoked. Or, if you use Courier’s &lt;a href="https://www.courier.com/blog/app-notifications-inbox/"&gt;in-app notification Inbox&lt;/a&gt;, you might choose to monitor the number of connections to your Inbox and compare this to the number of active users on your site. A significant difference could indicate a problem that needs further investigation.For example, you might have released a change that broke your Inbox implementation through changes to an authentication method or a key.&lt;/p&gt;

&lt;h2&gt;
  
  
  What data can be sent to Datadog from Courier?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Metrics
&lt;/h3&gt;

&lt;p&gt;Courier metric names will have a &lt;code&gt;courier.*&lt;/code&gt; prefix — for example, &lt;code&gt;courier.notification.sent&lt;/code&gt;. A full list of all the Courier metrics that are available for you to send to Datadog is provided &lt;a href="https://www.courier.com/docs/guides/business/observability/"&gt;here&lt;/a&gt;. These metrics will be sent with additional information, such as success or failure codes, and tags (including whether the metric is for your production or staging environment).&lt;/p&gt;

&lt;p&gt;Once the metrics are being sent to Datadog, you can set up corresponding alerts in Datadog. For example, you could set up an alert that emails your engineers when the  number of notification delivery errors reach a certain predefined threshold. &lt;/p&gt;

&lt;h3&gt;
  
  
  Logs
&lt;/h3&gt;

&lt;p&gt;Courier always had the ability to &lt;a href="https://help.courier.com/en/articles/4364860-using-the-data-logs"&gt;record logs&lt;/a&gt; about notifications, recipients, lists, and automations. Now these can be sent to Datadog in the same way that metrics are sent. &lt;/p&gt;

&lt;p&gt;Courier’s logs provide details about delivery failures, as well as other information that can be relevant when debugging. With these logs now in Datadog, you’ll now be able to easily correlate the logs to your metrics, helping you debug any issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the Datadog integration
&lt;/h2&gt;

&lt;p&gt;To set up this integration all you need is your Datadog API key and URL. From there, simply follow the &lt;a href="https://www.courier.com/docs/guides/business/observability/#datadog"&gt;setup guide&lt;/a&gt;, which will cover the steps to connect Courier with Datadog and how to create a Courier-specific dashboard in Datadog. This is where you’ll find our “dashboard starter kit,” a JSON file that has everything you need to  set up a Courier dashboard, including commonly used Courier metrics. You can easily customize the JSON to add or remove different metrics according to your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;If you’re already on Courier’s Business plan, you can start sending metrics and logs to Datadog right away. Otherwise, you can &lt;a href="https://www.courier.com/request-demo/?utm_source=datadog_launch&amp;amp;utm_medium=blog&amp;amp;utm_campaign=product_news"&gt;request a demo&lt;/a&gt;, and we’ll walk you through this integration in more detail, along with the other features in the Business plan to see if it’s right for your use case. &lt;/p&gt;

&lt;p&gt;The ability to access your metrics and logs in an observability platform like Datadog allows you to set up a dashboard that shows the data that’s most important to you. You can also create graphs that enable you to see at a glance if something’s not right, or even set up alerts based on message delivery failures. Whatever size your business is, some level of monitoring is necessary if you want to have control over your application.&lt;/p&gt;

&lt;p&gt;If you’re a Datadog user who is interested in trying Courier’s full-featured notifications infrastructure, you can &lt;a href="https://app.courier.com/signup"&gt;try it&lt;/a&gt; for free.&lt;/p&gt;

</description>
      <category>webdev</category>
    </item>
    <item>
      <title>Streamline your workflow with CourierJS: Our new client-side SDK</title>
      <dc:creator>Charla Bigelow</dc:creator>
      <pubDate>Mon, 10 Apr 2023 16:03:00 +0000</pubDate>
      <link>https://forem.com/courier/streamline-your-workflow-with-courierjs-our-new-client-side-sdk-3fkk</link>
      <guid>https://forem.com/courier/streamline-your-workflow-with-courierjs-our-new-client-side-sdk-3fkk</guid>
      <description>&lt;p&gt;We are thrilled to announce the release of our first client-side SDK for Courier, written for JavaScript. This new addition expands our existing SDK offerings, which include Java, Python, Node, Go, Ruby, and PHP, and makes it even easier for developers to integrate Courier into their projects. By enabling direct calls to Courier within your JavaScript code, you can eliminate the need to use a back-end service as an extra layer between your front end and the Courier API, saving valuable time and resources.&lt;/p&gt;

&lt;p&gt;With the initial release, we're introducing three new API calls: the &lt;code&gt;identify&lt;/code&gt; call for tying a user to actions they perform, such as logging in or updating their profile, and the &lt;code&gt;subscribe&lt;/code&gt; and &lt;code&gt;unsubscribe&lt;/code&gt; calls for subscribing and unsubscribing to lists. By simplifying these key interactions, CourierJS enhances the overall experience of using Courier. &lt;/p&gt;

&lt;h2&gt;
  
  
  Client-side vs. Server-side SDKs
&lt;/h2&gt;

&lt;p&gt;You may still be wondering: why introduce a client-side JavaScript SDK for Courier when we already have SDKs for many other languages? Let's dive into the differences between client-side and server-side SDKs, which will help you determine the right type of SDK for your specific needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/5rsBb6Xcz2QAvTGR3HTIx7/523b5e34169adb335970d98209b8b492/Client-side_SDK_benefits.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/5rsBb6Xcz2QAvTGR3HTIx7/523b5e34169adb335970d98209b8b492/Client-side_SDK_benefits.png" alt="Client-side SDK benefits"&gt;&lt;/a&gt;&lt;br&gt;
(&lt;em&gt;Comparing integration flows: with and without Courier client-side SDK&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Client-side SDKs are designed to provide a way for you to interact with an API within your application's front-end code. Server-side SDKs, in contrast, interact with your back-end code, making them more suitable for processing and handling data that doesn't directly involve user interactions on the front end. By offering a client-side JavaScript SDK, we're providing developers with an alternative to server-side SDKs that is more suitable when you need to integrate Courier's functionality directly into your web application's front end. When trying to call the API from your front end, having an extra layer of back-end code might not always be the most suitable option for certain use cases. With CourierJS, we provide an alternative that streamlines the process and caters to a broader range of scenarios, enhancing efficiency and helping you deliver valuable applications more quickly.&lt;/p&gt;

&lt;p&gt;We have taken inspiration from popular customer data platforms like Segment and RudderStack, both of which provide an &lt;code&gt;identify&lt;/code&gt; call. In addition to an &lt;code&gt;identify&lt;/code&gt; call, which ties a user action to a particular user, our initial release also includes support for subscribing and unsubscribing to lists, allowing users to manage their communication preferences with ease.&lt;/p&gt;

&lt;p&gt;The JavaScript SDK has been designed to be both intuitive and efficient, working exactly how you'd expect. Instead of issuing multiple commands to update specific fields, you can now easily update multiple fields in a single operation. For example, if you have a user with an ID, name, email address, physical address, and phone number, and you just want to update the email address and phone number, you can pass in just those values. The SDK also automatically merges new data with pre-existing data, overwriting only the specified fields. This functionality ensures a smooth integration with your front-end code and a more seamless user experience.&lt;/p&gt;
&lt;h2&gt;
  
  
  Discover the advantages of CourierJS
&lt;/h2&gt;

&lt;p&gt;Previously, developers using Courier only had access to server-side SDKs. These SDKs required the front-end code to communicate with the back-end services to utilize Courier's functionality, often adding an unnecessary extra layer. In some cases, you even had to create an entire back-end service just to handle the Courier SDK.&lt;/p&gt;

&lt;p&gt;One of the primary challenges faced when using server-side SDKs in the context of Courier arises when you need to send data from the front end to Courier, which previously required going through the back end. This process can be manageable, but it can also be tedious for developers who want a more streamlined solution. To address this, we’ve developed the client-side SDK, making it easier for those who want to directly integrate Courier's functionality into their web application's front end, bypassing the need to pass data through the back end first.&lt;/p&gt;

&lt;p&gt;By introducing the new Courier client-side SDK, we aim to simplify this process and reduce the workload for engineers. This not only saves time but also accelerates the implementation of new features, making your development process more efficient and agile.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ready to get started? Using CourierJS is a breeze
&lt;/h2&gt;

&lt;p&gt;Now that you've discovered the advantages of the Courier client-side SDK, it's time to dive into how you can seamlessly integrate it into your project. To begin, all you need to do is install the JavaScript package and start using the provided function calls in your code. For a comprehensive step-by-step guide on setting up the Courier client-side SDK, you can refer to our documentation &lt;a href="https://github.com/trycourier/courier-js#getting-started"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Exploring the new API calls in Courier's client-side SDK
&lt;/h2&gt;

&lt;p&gt;Now that you're all set up, let's take a closer look at the new API calls introduced in the SDK.&lt;/p&gt;
&lt;h3&gt;
  
  
  The &lt;code&gt;identify&lt;/code&gt; call
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;identify&lt;/code&gt; call allows you to create and update user profiles with ease. Here's an example of how the &lt;code&gt;identify&lt;/code&gt; call can be used in your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;courierSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;identify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user123@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Doe&lt;/span&gt;&lt;span class="dl"&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;In this example, the &lt;code&gt;identify&lt;/code&gt; call creates or updates a user profile with the specified user ID, email, first name, and last name. The simplicity of the call ensures that you can quickly and easily update user profiles as needed, making it an invaluable tool in your communication management toolkit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subscribing and unsubscribing from lists
&lt;/h3&gt;

&lt;p&gt;A list in Courier is a way to group recipient profiles, allowing you to send a message to all subscribed recipients with a single call. This feature is particularly useful for managing newsletters, product updates, and other types of mass communication.&lt;/p&gt;

&lt;p&gt;Managing user subscriptions is easy with the new &lt;code&gt;subscribe&lt;/code&gt; and &lt;code&gt;unsubscribe&lt;/code&gt; API calls. These calls make it straightforward to maintain up-to-date lists of subscribers, due to not needing to call a back-end service. Here are examples of how to use the &lt;code&gt;subscribe&lt;/code&gt; and &lt;code&gt;unsubscribe&lt;/code&gt; calls in your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Subscribe a user to a list&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;courierSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-newsletter-list&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Unsubscribe a user from a list&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;courierSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-newsletter-list&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see from the comments in these examples, the &lt;code&gt;subscribe&lt;/code&gt; call adds a user to a specified list, while the &lt;code&gt;unsubscribe&lt;/code&gt; call removes them from the list. &lt;/p&gt;

&lt;p&gt;By incorporating these new API calls into your project, you can further streamline your development process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Throughout this article, we've unveiled the power of the new CourierJS client-side SDK and explored its features, including the &lt;code&gt;identify&lt;/code&gt; call and &lt;code&gt;subscribe&lt;/code&gt; and &lt;code&gt;unsubscribe&lt;/code&gt; calls. By using the CourierJS client-side SDK, you can reduce the workload involved in your development process and improve the overall efficiency of your projects.&lt;/p&gt;

&lt;p&gt;As you’ve seen, the SDK saves you time and effort by eliminating the need for complex back-end services and enabling direct communication between the front end and Courier. Its intuitive functionality, ease of use, and powerful capabilities make it a valuable addition to your development toolkit.&lt;/p&gt;

&lt;p&gt;We encourage you to try out the new &lt;a href="https://github.com/trycourier/courier-js"&gt;CourierJS client-side SDK&lt;/a&gt; and experience the benefits it offers firsthand. By adopting this innovative tool, you can enhance your product-triggered communication management and unlock the full potential of the Courier ecosystem.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>api</category>
    </item>
    <item>
      <title>Introducing the new and improved Automations designer</title>
      <dc:creator>Charla Bigelow</dc:creator>
      <pubDate>Mon, 03 Apr 2023 15:31:00 +0000</pubDate>
      <link>https://forem.com/courier/introducing-the-new-and-improved-automations-designer-fbd</link>
      <guid>https://forem.com/courier/introducing-the-new-and-improved-automations-designer-fbd</guid>
      <description>&lt;p&gt;&lt;a href="https://www.courier.com/blog/announcing-courier-automations/"&gt;Courier Automations&lt;/a&gt; lets you build smart notification workflows. With Automations, notifications can be scheduled, driven by events, canceled, and more.&lt;/p&gt;

&lt;p&gt;We’ve just completed a big redesign of the automations UI — before this overhaul, notifications were restricted to linear workflows. This made it difficult to build more advanced automations, however the new automations UI, based on &lt;a href="https://reactflow.dev/"&gt;React Flow&lt;/a&gt;, allows you to build more sophisticated workflows, including those requiring branching logic.&lt;/p&gt;

&lt;p&gt;In this article, we explain the differences in functionality between the old and new UI, how the new UI helps developers as well as product managers, and how the migration will affect you if you’re already using the automations designer. For those who are new to Courier automations, we explain the background of what automations are for and how to use them. We also cover how to use the new UI, while providing some useful real-world examples to help you get started.&lt;/p&gt;

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

&lt;p&gt;Courier serves as a product-oriented notification platform, and is well-suited for the post-marketing phase of a business; allowing you to streamline communication with users across your websites and/or applications. Its unified API accommodates multi-channel delivery — including email, SMS, browser notifications, push notifications, and direct messages through platforms such as Slack or Microsoft Teams. The power of the Courier app is that it allows you to design versatile message templates that can be easily repurposed across each messaging channel.&lt;/p&gt;

&lt;p&gt;You can pull data from other systems into Courier, to populate variables within your message templates or when building your application logic in your automations. This data can come from a variety of sources — for example, from customer data platforms (CDPs) like Segment or RudderStack, or from your own site.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Courier automations?
&lt;/h2&gt;

&lt;p&gt;Courier automations enable you to craft intricate notification delivery workflows while seamlessly integrating your custom application logic into the Courier notification ecosystem. Automations can be controlled either through an API or through the automations designer inside the Courier app. The automations designer allows you to design automations either by using a visual builder or by directly editing JSON. It’s the fastest way to build workflows. &lt;/p&gt;

&lt;p&gt;The latest update to the automations designer includes a big update to the visual builder. Where previously your workflows were limited, or were made unnecessarily complex by the linear nature of the visual builder, you can now use the designer to design complex workflows in a simple and intuitive way.&lt;/p&gt;

&lt;p&gt;For example, if you want to send different welcome emails to different groups of people based on user attributes, it was difficult to handle this level of complexity in the old UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/5fe4Xoo5ga0cRVS6zep1il/278908b468abe57fd0ab68593cbb59dc/segmentacctcreated-old2.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/5fe4Xoo5ga0cRVS6zep1il/278908b468abe57fd0ab68593cbb59dc/segmentacctcreated-old2.png" alt="Automation v1 UI Segment account created"&gt;&lt;/a&gt;&lt;br&gt;
(&lt;em&gt;The old UI consists of a linear series of steps. In this example, a Segment event, “Account Created” triggers a 10-minute delay before sending a welcome email.&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/41UUw7FkgalcgFyFtU4AAm/64f52b56267bcf210adc20580784da91/segmentacctcreated3.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/41UUw7FkgalcgFyFtU4AAm/64f52b56267bcf210adc20580784da91/segmentacctcreated3.png" alt="Automations v2 UI Segment account created"&gt;&lt;/a&gt;&lt;br&gt;
(&lt;em&gt;The new automations designer has drag-and-drop elements that can help you create non-linear workflows. In this example, the Segment event, “Account Created” triggers a 10-minute delay and then checks whether the user’s job role contains “engineer.” If they are an engineer, they will be sent the engineer-specific welcome email, and if not, they will receive a generic welcome email.&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;The new automations designer was built using React Flow, a library for building node-based interactive UIs. You can build your messaging workflows by dragging and dropping different elements such as triggers and actions onto a canvas. You can then connect them together in a sequential order, or use branching logic if required to build a more complex workflow.&lt;/p&gt;

&lt;p&gt;The example above shows a workflow for waiting until a user has signed up to send them a message. If they’re online, you can just send a browser notification; otherwise you might want to send an email.&lt;/p&gt;

&lt;h3&gt;
  
  
  The elements of a Courier automation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Triggers
&lt;/h4&gt;

&lt;p&gt;Triggers are events that cause a new automation run to be started. They define the conditions that must occur before an action can happen. A simple example of a trigger is a scheduler that waits until a particular timestamp is reached before an action can happen (such as sending a notification).  Data pulled from your CDP can act as a trigger, too — for example, a new user signing up to your system.&lt;/p&gt;

&lt;p&gt;You can also make use of data from &lt;a href="https://updates.courier.com/announcements/audiences"&gt;Courier Audiences&lt;/a&gt; to design your triggers. An Audience is a dynamic list of your users. When someone joins or leaves an Audience, this event could be used as a trigger to send a notification. An example of this could involve an Audience of all users who are software engineers. If a user who previously worked in tech support becomes a software engineer, as soon as they update their profile they become part of the “software engineer” audience  — which will cause your trigger to invoke an action such as sending a message.&lt;/p&gt;

&lt;h4&gt;
  
  
  Actions
&lt;/h4&gt;

&lt;p&gt;An action is an activity that happens following a trigger. The most common action in Courier is the sending of a message, either to an individual or group. However, actions can also include fetching data from another API, updating a user profile, or adding a delay to your workflow – for example, waiting for 24 hours after a user signed up to remind them to fill in their profile.&lt;/p&gt;

&lt;h4&gt;
  
  
  Branching logic
&lt;/h4&gt;

&lt;p&gt;Branching logic is a new feature in the latest automations designer that allows you to design more complex workflows by dragging and dropping &lt;code&gt;if&lt;/code&gt; statement blocks into your workflow. These are accessed in the menu on the left, under “Control Flow.” An &lt;code&gt;if&lt;/code&gt; statement block has nodes next to its &lt;code&gt;true&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt; conditions, so you can draw lines that link these different conditions to the next steps in your workflow. As this doesn’t involve writing code, non-developers with a decent understanding of the data involved are often able to design their own notification workflows.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/2054asBqXWfi2Ctwa7umPg/07d34f550ca8ce314e1e413c30e339e8/Screenshot_from_2023-03-15_18-20-49.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/2054asBqXWfi2Ctwa7umPg/07d34f550ca8ce314e1e413c30e339e8/Screenshot_from_2023-03-15_18-20-49.png" alt="Automations v2 UI if/else conditional branching"&gt;&lt;/a&gt;&lt;br&gt;
(&lt;em&gt;Once you’ve dragged an &lt;code&gt;if&lt;/code&gt; statement box onto the canvas, you can connect it to different parts of your workflow by drawing lines from the &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt; nodes to other elements within your automations template.&lt;/em&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the new version of the Courier automations designer helps you
&lt;/h2&gt;

&lt;p&gt;Until now, if you were using automations for complex, non-linear workflows, there was a good chance you had to manage this logic yourself using our API, which may even have required a separate back-end service just for dealing with this. And, due to ever-changing requirements, you may have needed to regularly update your code in small but necessary ways. &lt;/p&gt;

&lt;p&gt;This can now be done in the UI, leading to much faster turnaround for small workflow changes. To achieve the fastest turnaround, it’s worth empowering product managers or designers to make their own changes to the logic when needed, so they don’t have to wait for a developer to fit small changes around feature work. As long as they have some knowledge of the underlying data, this can be accomplished with minimal training, as the interface is very intuitive. Allowing your colleagues to create or edit automations has the added benefit of freeing up your time to do more feature work instead of having to focus on small updates to application logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use the automations designer
&lt;/h2&gt;

&lt;p&gt;You can follow our &lt;a href="https://www.courier.com/docs/automations/designer/"&gt;documentation&lt;/a&gt; on how to create a basic automation using the new automations designer UI. After creating your automation template, you’ll need to publish it before it can be invoked. The standard way for an automation to be invoked is automatically — when its trigger condition is met. However, it is still possible to invoke an automation by using our &lt;a href="https://www.courier.com/docs/reference/automation/invoke-template/"&gt;automations API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you need to use variables within your automations — for example, if you want to send your message to varying recipients, or if you want your message template to vary according to certain conditions — you can use our &lt;a href="https://www.courier.com/docs/automations/dynamic/"&gt;refs variable&lt;/a&gt;, which stores dynamic data within Courier.&lt;/p&gt;

&lt;h2&gt;
  
  
  The automations API
&lt;/h2&gt;

&lt;p&gt;If you prefer to &lt;a href="https://www.courier.com/docs/reference/automation/"&gt;use the API directly&lt;/a&gt;, or use an SDK, that’s still an option. You can use these to either invoke automations or get the status of automations. For existing users of the API, you can be reassured that we’ve made no changes to the API — our latest automations release applies to the UI only.&lt;/p&gt;

&lt;h2&gt;
  
  
  Details for existing users of the automations designer
&lt;/h2&gt;

&lt;p&gt;For existing users of the automations designer, we’ll now cover the main points that are likely to be of interest: the main differences between the old and new UIs, and what you need to do to migrate to the new version of automations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Differences between the old and new automations designer UIs
&lt;/h3&gt;

&lt;p&gt;The main difference is that the new automations designer UI is more expansive: you are no longer forced to follow a linear workflow, and can take advantage of branching logic. In addition to this, we have added some improvements to make the UI easier to use. For example, running an automation on a repeat schedule used to require users to learn &lt;a href="https://en.wikipedia.org/wiki/Cron"&gt;Cron&lt;/a&gt; expressions — something that even most engineers have a tough time remembering. Now, with the new “Schedule” trigger, scheduling an automation is as easy as scheduling an appointment in your favorite Calendar app. Changes like these have made the UI more user-friendly, meaning that letting non-developers set up their own workflows is finally an option.&lt;/p&gt;

&lt;h3&gt;
  
  
  What you need to do to migrate to the new version of automations
&lt;/h3&gt;

&lt;p&gt;You don’t need to do anything! We have already rolled out the new changes, so no work is required from your end. &lt;/p&gt;

&lt;p&gt;If you have any existing automations templates that you’ve designed in the past, these will not change. They will appear in exactly the same way using the old UI. However, any new automations templates that you create will now appear using the new UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;You can get started creating automations with the new Designer &lt;a href="https://app.courier.com/automations"&gt;directly in the Courier UI&lt;/a&gt;. Setting up smart notifications in the new UI is fast and intuitive — just follow our &lt;a href="https://www.courier.com/docs/automations/"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>notifications</category>
    </item>
    <item>
      <title>Simplifying notifications with the Courier iOS SDK</title>
      <dc:creator>Charla Bigelow</dc:creator>
      <pubDate>Thu, 23 Mar 2023 17:16:58 +0000</pubDate>
      <link>https://forem.com/courier/simplifying-notifications-with-the-courier-ios-sdk-21ah</link>
      <guid>https://forem.com/courier/simplifying-notifications-with-the-courier-ios-sdk-21ah</guid>
      <description>&lt;p&gt;Push notifications are a valuable tool for keeping users informed and increasing their engagement with your app. You can use push notifications to alert users about promotions, new content, or any other important updates. While push notifications are a powerful tool, setting up push notifications in iOS can be a daunting task that requires a significant amount of effort and time. Fortunately, the Courier iOS Mobile Notifications Software Development Kit (SDK) simplifies this process.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/3rUcQDOobYWo1ZWJPFVwnH/d687bb8df008f348d2f18e38f38b091d/Simplifying_Notifications_with_the_Courier_iOS_SDK.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/3rUcQDOobYWo1ZWJPFVwnH/d687bb8df008f348d2f18e38f38b091d/Simplifying_Notifications_with_the_Courier_iOS_SDK.png" alt="iOS push notifications with Courier"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Courier iOS SDK can help you to implement push notifications in iOS apps more easily thanks to some useful tools. The benefits of using the SDK include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplified setup process&lt;/strong&gt;. The Courier iOS SDK streamlines the process, making it easy to get set up and start sending push notifications. With some easy-to-follow setup steps and a few lines of code, you can quickly integrate the SDK into your apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Effective management of tokens and user state&lt;/strong&gt;. When implementing push notifications, you would normally need to handle token management manually, which involves generating and storing unique identifiers for each device that can receive notifications. This can be complex and time-consuming. The Courier iOS SDK provides tools that enable you to manage tokens and user state effectively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sending test notifications&lt;/strong&gt;. Before sending push notifications to all users, it's important to test that they're working as intended. With the Courier iOS SDK, you can send test notifications to check that your notifications are working as intended before they go live. This can save time and prevent problems later.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Token management
&lt;/h2&gt;

&lt;p&gt;Managing push notification tokens is a complex task. Let’s talk a bit about how they work, to help us better understand the benefits of the Courier SDK.&lt;/p&gt;

&lt;p&gt;Tokens are unique identifiers that are used to identify a specific device for push notifications. They are generated and managed by the push notification service, which is the Apple Push Notification Service (APNS) for iOS. These tokens need to be securely stored on the back end, associated with the relevant user or device, and regularly updated as they can change or expire. Additionally, token management includes handling token deletion when a user unsubscribes from push notifications or uninstalls your app.&lt;/p&gt;

&lt;p&gt;Setting up and managing your own token management infrastructure can be a time-consuming and challenging task, requiring collaboration between front-end, mobile, and back-end developers. However, with the Courier iOS SDK, token management is handled automatically. The SDK automatically takes push notification tokens, stores them in Courier, and invalidates tokens that expire, so you can focus on building your product without having to learn the complex logistics of token management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started with Courier's iOS SDK
&lt;/h2&gt;

&lt;p&gt;Before you can use the &lt;a href="https://github.com/trycourier/courier-ios"&gt;Courier iOS SDK&lt;/a&gt;, you'll need a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://developer.apple.com/xcode/"&gt;Xcode&lt;/a&gt;&lt;/strong&gt;. You'll need to have Apple's integrated development environment (IDE), Xcode, installed on your computer. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An Apple developer account&lt;/strong&gt;. To enable push notifications in your app, you'll need a valid Apple developer account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A physical iOS device&lt;/strong&gt;. You'll need an iOS device to test your push notifications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find a full and detailed set-up guide in the iOS docs on the &lt;a href="https://github.com/trycourier/courier-ios#installation"&gt;Courier GitHub repository&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Push providers
&lt;/h2&gt;

&lt;p&gt;Before we look at sending a test push notification, it’s worth noting that to enable push notification support you will need to configure a push provider. A push provider is a service that handles the delivery of push notifications to targeted devices, ensuring reliable and efficient message transmission.&lt;/p&gt;

&lt;p&gt;Take a look at our &lt;a href="https://github.com/trycourier/courier-ios#3-configure-push-provider"&gt;GitHub&lt;/a&gt; page for more information. There you will find links to APNS (Apple Push Notification Service) and FCM (Firebase Cloud Messaging). Follow the links there to see more detailed information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling push notification capability
&lt;/h2&gt;

&lt;p&gt;Another vital step is to enable push notification capability in your iOS app. Here's how to do that.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new iOS app ID and a provisioning profile in the Apple Developer portal.

&lt;ul&gt;
&lt;li&gt;Log in to the Apple Developer portal and create a new app ID for your app.&lt;/li&gt;
&lt;li&gt;Create a new provisioning profile for your app, which will allow it to access push notification services.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;In Xcode, open your app project and select the project file from the project navigator.&lt;/li&gt;
&lt;li&gt;Select your app target and click on the "Capabilities" tab.&lt;/li&gt;
&lt;li&gt;Turn on the "Push Notifications" capability.&lt;/li&gt;
&lt;li&gt;In the "Signing &amp;amp; Capabilities" tab, select the team for your app and choose the provisioning profile you created in step 1.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once this is done, you’ll have enabled push notification capability in your iOS app and can start sending push notifications to your users through the Courier iOS SDK.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a notification service extension
&lt;/h2&gt;

&lt;p&gt;So that you can better track your notifications, we recommend that you create a notification service extension in your iOS app. &lt;/p&gt;

&lt;p&gt;A notification service extension is a type of iOS app extension that allows developers to track the delivery status of notifications and perform additional actions, such as modifying the content of a notification. &lt;/p&gt;

&lt;p&gt;Setting up this extension allows Courier to accurately tell when your user receives a push notification when they are not using the app.&lt;/p&gt;

&lt;p&gt;You can find a full setup guide &lt;a href="https://github.com/trycourier/courier-ios#add-the-notification-service-extension-recommended"&gt;here&lt;/a&gt;, on the Courier iOS SDK GitHub page. It won’t take long, and then Courier will be able to track delivery status in any state your app could be in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Push notification permissions
&lt;/h2&gt;

&lt;p&gt;The Courier iOS SDK needs to have push notification permissions granted by your users before it can access the push notification token. That’s where the &lt;code&gt;requestNotificationPermission()&lt;/code&gt; function comes in.&lt;br&gt;
Here's how it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Courier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shared&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestNotificationPermission&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Send some notification }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;requestNotificationPermission()&lt;/code&gt; function returns an authorization status that indicates whether the user has granted or denied permissions for push notifications.&lt;/p&gt;

&lt;p&gt;You can read more about authorization status &lt;a href="https://developer.apple.com/documentation/usernotifications/unauthorizationstatus"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once your user has given access to receive notifications, a push notification device token is created by iOS and automatically synced to Courier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing user state
&lt;/h2&gt;

&lt;p&gt;Now that you've set up your notification service extension and handled permissions, it's time to focus on delivering a great user notification experience. One key part of this is keeping track of user state — the status of a user in relation to your app. This allows you to send users appropriate notifications based on whether they’re logged in or out. For instance, if a user is logged out, it wouldn't make sense to send them a notification about an activity that requires them to be logged in. &lt;/p&gt;

&lt;p&gt;The Courier iOS SDK provides tools that help developers manage user state effectively and easily. By using the &lt;code&gt;signIn()&lt;/code&gt; function provided by the SDK, developers can ensure that the user's push notification tokens and their state are kept in sync. Here's how to use the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Courier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shared&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&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;The &lt;code&gt;accessToken&lt;/code&gt; can either be a Courier Auth Key used during development or a JWT (JSON Web Token) that should be used in a production app. You can create an access token by calling the Courier API as shown in the GitHub &lt;a href="https://github.com/trycourier/courier-ios#going-to-production"&gt;documentation&lt;/a&gt;. When the user signs out, you can use the &lt;code&gt;signOut()&lt;/code&gt; function to clear their state.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;signIn()&lt;/code&gt; function saves the &lt;code&gt;accessToken&lt;/code&gt; and &lt;code&gt;userId&lt;/code&gt; to the native-level local storage, ensuring that the user's state persists between app sessions. This ensures that the user's push notification tokens are kept up to date.&lt;br&gt;
By following these steps, you automatically sync push notification tokens and user state to Courier. This lets you ensure that push notifications are delivered at the right time and in the appropriate context for a better user experience.&lt;/p&gt;
&lt;h2&gt;
  
  
  Handling notification delivery
&lt;/h2&gt;

&lt;p&gt;We've made it easy for you to monitor the delivery status of your notifications using the Courier iOS SDK via the &lt;code&gt;onPushNotificationDelivered()&lt;/code&gt; function. &lt;/p&gt;

&lt;p&gt;When a push notification is delivered to a user's device, &lt;code&gt;onPushNotificationDelivered()&lt;/code&gt; is triggered automatically by the SDK if the app is in foreground. Here is an example implementation of the function in the &lt;code&gt;AppDelegate&lt;/code&gt; class (the &lt;code&gt;AppDelegate&lt;/code&gt; class is a key part of every iOS app and handles system-level events, including push notifications):&lt;/p&gt;

&lt;p&gt;Courier analytics will track the delivery of this notification for you automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;AppDelegate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CourierDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nx"&gt;override&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="nx"&gt;pushNotificationDeliveredInForeground&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AnyHashable&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;UNNotificationPresentationOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[.&lt;/span&gt;&lt;span class="nx"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;banner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;badge&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// Pass [] to hide any foreground presentation&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;Note that this function will not be triggered when the app is in the "killed", "not running", or “background” state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling a notification click
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;pushNotificationClicked()&lt;/code&gt; function provided by the Courier iOS SDK can be used to handle user interaction with a notification inside your AppDelegate class. This function is called when the user clicks on a notification that was sent through Courier. Here's sample code for using the function:&lt;/p&gt;

&lt;p&gt;Courier analytics will track the clicking of this notification for you automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;AppDelegate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CourierDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;override&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="nx"&gt;pushNotificationClicked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AnyHashable&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the function simply prints out the content of the message payload. However, you can use the message to perform any number of actions in your app, such as opening a specific screen or executing a certain function. &lt;/p&gt;

&lt;h2&gt;
  
  
  Sending a test push
&lt;/h2&gt;

&lt;p&gt;Now that you’ve set up your push notification infrastructure and know how to manage user state, you can start sending messages. The SDK allows you to send push notifications directly to a user ID without having to juggle tokens or manage a back end.&lt;/p&gt;

&lt;p&gt;To send a test push notification, you can use the &lt;code&gt;sendPush()&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;messageId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Courier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shared&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendPush&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;authKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a_courier_auth_key_that_should_only_be_used_for_testing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example_user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Happy Holidays!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Happy holidays from Courier.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[.&lt;/span&gt;&lt;span class="nx"&gt;apns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fcm&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;Note that your user must have been given access to receive push notifications so that the push notification device tokens can be automatically synced to Courier and Courier can send a message to your user’s device. See “Push notification permissions” above for more details.&lt;/p&gt;

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

&lt;p&gt;With just a few lines of code, you can streamline your push notification management and focus on building your product, thanks to the Courier iOS SDK.&lt;/p&gt;

&lt;p&gt;By taking care of complex tasks such as token management and message delivery tracking, the SDK allows you to focus on building high-quality push notification experiences for your users. &lt;/p&gt;

&lt;p&gt;If you’re an iOS developer, make sure to give the Courier iOS SDK a try and see how it can simplify and enhance your push notification workflow. Courier also has other SDKs available for &lt;a href="https://github.com/trycourier/courier-android"&gt;Android&lt;/a&gt;, &lt;a href="https://github.com/trycourier/courier-react-native"&gt;React Native&lt;/a&gt;, and &lt;a href="https://github.com/trycourier/courier-flutter"&gt;Flutter&lt;/a&gt;. So if you're looking for a way to simplify your push notification management, check out &lt;a href="https://www.courier.com/"&gt;Courier&lt;/a&gt; today.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Automate Slack and Microsoft Teams Notifications using Python</title>
      <dc:creator>Shreya</dc:creator>
      <pubDate>Thu, 16 Mar 2023 16:28:47 +0000</pubDate>
      <link>https://forem.com/courier/automate-slack-and-microsoft-teams-notifications-using-python-2e5n</link>
      <guid>https://forem.com/courier/automate-slack-and-microsoft-teams-notifications-using-python-2e5n</guid>
      <description>&lt;p&gt;Messaging apps are essential for internal collaboration and critical notifications such as reminders, alerts, and other time-sensitive updates. While integrating with the Slack and Microsoft APIs is fairly straightforward, implementing these tools as a part of a full-featured notification system that embeds with your app experience can be far more daunting.&lt;/p&gt;

&lt;p&gt;In this article, we'll show you how to send notifications via Slack and Microsoft Teams, using Courier to make these tools a seamless part of how your app communicates with users.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://app.courier.com/settings/api-keys"&gt;Get access to your Courier API Key&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  Install &lt;a href="https://www.python.org/downloads/"&gt;Python 3.x&lt;/a&gt; on your computer&lt;/li&gt;
&lt;li&gt;  Install &lt;a href="https://github.com/trycourier/courier-python"&gt;trycourier&lt;/a&gt; by running the &lt;code&gt;pip install trycourier&lt;/code&gt; command&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Create a Notification Template for Slack and Teams
&lt;/h1&gt;

&lt;p&gt;Head over to the &lt;a href="https://app.courier.com/designer/notifications"&gt;Notification Designer&lt;/a&gt; and create a new notification. Once you have created the notification, you will be able to select your channels. Here you can add Slack, Teams, and/or any other channels you would like to send with.&lt;/p&gt;

&lt;p&gt;Click on any of the channels to customize your message. Once you have created your message, you can use the drag-and-drop "Library" on the left side to recreate the message for the remaining channels.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/4t6oJw1bAPc9e52j60bSqV/25db3c6da9ca8b2374ce013186d512d0/library.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/4t6oJw1bAPc9e52j60bSqV/25db3c6da9ca8b2374ce013186d512d0/library.png" alt="library"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the settings (gear) icon next to the template name (top right) to access the Notification ID, which you will need later to send this message.&lt;/p&gt;

&lt;h1&gt;
  
  
  Send with Slack
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Add the Slack integration to Courier&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, head to the Slack channel in Courier &lt;a href="https://app.courier.com/channels/slack"&gt;https://app.courier.com/channels/slack&lt;/a&gt; and click "Install Provider". If you only want to send with Teams, you can skip to the “Send with Microsoft Teams” section.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/SWRZHOpuy16BSC7U6bKZC/7012a8b640279a373385030f5915e783/channel_slack.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/SWRZHOpuy16BSC7U6bKZC/7012a8b640279a373385030f5915e783/channel_slack.png" alt="channel slacks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create a Slack App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Navigate to the &lt;a href="https://api.slack.com/apps"&gt;Slack Apps&lt;/a&gt; page and log into Slack. Click the &lt;strong&gt;Create an App&lt;/strong&gt; button and provide your &lt;strong&gt;App Name&lt;/strong&gt; as depicted below.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/miwFyPxaShQwSo2TOsfAw/9a528f8789cc9e4b2254f6596026167f/image-3.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/miwFyPxaShQwSo2TOsfAw/9a528f8789cc9e4b2254f6596026167f/image-3.png" alt="slack-app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Add OAuth Permission and Scopes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Define the permissions that your Slack App is authorized to do.&lt;/p&gt;

&lt;p&gt;To do so, navigate to the &lt;strong&gt;OAuth &amp;amp; Permissions&lt;/strong&gt; page in the sidebar menu and select the following options from the Scopes section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;chat:write&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;im:write&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;users:read&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;users:read.email&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/198iG9vhkW4tlkJyeBrpNn/cbf936323438e33685359b7ebc6b4a8b/image-4.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/198iG9vhkW4tlkJyeBrpNn/cbf936323438e33685359b7ebc6b4a8b/image-4.png" alt="slack-app-scopes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Afterward, click the &lt;strong&gt;Install App to Workspace&lt;/strong&gt; or &lt;strong&gt;Reinstall App&lt;/strong&gt; button at the top of the page. This will generate an output -"Bot User OAuth Token" as depicted below, which will be needed later.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/2EqXlD3eNxgMPsC7HaRbVs/0f34a765a9db3d7c623d59e338a3ad2d/slack-app-oath-token.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/2EqXlD3eNxgMPsC7HaRbVs/0f34a765a9db3d7c623d59e338a3ad2d/slack-app-oath-token.png" alt="slack-app-oath-token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Send a Slack DM with Python&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the code snippet below to your codebase (e.g. &lt;code&gt;index.py&lt;/code&gt; ) and update the following properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  replace  with your Courier API key&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;access_code&lt;/code&gt;: replace &lt;code&gt;xoxb-abcd&lt;/code&gt; with the Bot User OAuth Token&lt;/li&gt;
&lt;li&gt;  replace &lt;code&gt;example@gmail.com&lt;/code&gt; with your user's email address (this is the email associated with the recipient's Slack Account)&lt;/li&gt;
&lt;li&gt;  Recommended: use your own email for testing&lt;/li&gt;
&lt;li&gt;  replace &lt;code&gt;85S5NWXJVQ4GN8J21JSKV3JVCSV2&lt;/code&gt; with your Notification ID from the first part of this tutorial
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from trycourier import Courier
client = Courier(auth_token="&amp;lt;auth-token&amp;gt;")

resp = client.send_message(
  message={
    "to": {
      "slack": {
        "access_token": "xoxb-abcd",
        "email": "example@gmail.com",
      },
    },
    "template": "85S5NWXJVQ4GN8J21JSKV3JVCSV2",
    "data": {
    },
  }
)
print(resp['requestId'])

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

&lt;/div&gt;



&lt;p&gt;Execute the Python script to see your notification popup in the user's Slack direct message!&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/7oK2GoJdrfngJoXuqd8DDo/6bb2407eafaf8b4a1ff1cbf978c9ab61/Slack_message.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/7oK2GoJdrfngJoXuqd8DDo/6bb2407eafaf8b4a1ff1cbf978c9ab61/Slack_message.png" alt="Slack message"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check your Courier logs for errors if your user did not receive the message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slack Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.courier.com/docs/guides/providers/direct-message/slack/"&gt;Slack Integration documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.courier.com/docs/guides/getting-started/python/"&gt;Python quick start guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://youtu.be/sZpxo9kOa78"&gt;Video walkthrough: Automating Slack Messages with Courier API&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Send with Microsoft Teams
&lt;/h1&gt;

&lt;p&gt;We can now try sending the same message via Teams. If you only want to send with Slack, you can skip to the “Routing to multiple channels” section. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Sign up for a Microsoft 365 Developer Account&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you do not have a Microsoft 365 developer account, follow the instructions from &lt;a href="https://developer.microsoft.com/en-us/microsoft-365/dev-program/"&gt;this guideline&lt;/a&gt; to create an account. If you already have an account, you can skip this step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create a Teams App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new App in Teams. You will need to install the &lt;a href="https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/teams-developer-portal"&gt;Developer Portal&lt;/a&gt; from the Team Apps.&lt;/p&gt;

&lt;p&gt;After installing the Developer Portal, navigate to the &lt;strong&gt;Apps&lt;/strong&gt; tab and click the &lt;strong&gt;New App&lt;/strong&gt; button. Then, you will get prompted to enter the application name.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/4aAPZzFGQGiXPs2wvYpv1u/508cbfafe3f3df87b0efed75eb02117a/ms_teams_add_app.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/4aAPZzFGQGiXPs2wvYpv1u/508cbfafe3f3df87b0efed75eb02117a/ms_teams_add_app.png" alt="ms teams add app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After clicking the Add button, you will be redirected to a new window where you can see the App ID. Make sure to copy the App ID for later use.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/5GqgOocVChW7ODrHXOYiSR/ae5c800f466fa408be455448e0828d24/MS_Teams_Basic_Info.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/5GqgOocVChW7ODrHXOYiSR/ae5c800f466fa408be455448e0828d24/MS_Teams_Basic_Info.png" alt="MS Teams Bot Basic Info"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, click &lt;strong&gt;App features&lt;/strong&gt; from the left menu and click on the tile named &lt;strong&gt;Bot&lt;/strong&gt;. It will open a new window for selecting a bot and bot scopes.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/4un7lX2rG9oos1pcte7mXf/c0d66c40799682ffa3e8847ed9d0b265/Identify_Bot.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/4un7lX2rG9oos1pcte7mXf/c0d66c40799682ffa3e8847ed9d0b265/Identify_Bot.png" alt="Identify Bot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you do not have a bot created already, follow &lt;a href="https://learn.microsoft.com/en-us/microsoftteams/platform/resources/bot-v3/bots-create"&gt;these steps&lt;/a&gt; to create a new one. Also, make sure to save the password generated during the process. Keep the &lt;strong&gt;Messaging endpoint&lt;/strong&gt; blank for the moment.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/2QJEtyIRyEW1IoOjVWc5jT/254f097453ffbda26b71a44b518925a2/MS_Teams_App_Configuration.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/2QJEtyIRyEW1IoOjVWc5jT/254f097453ffbda26b71a44b518925a2/MS_Teams_App_Configuration.png" alt="MS Teams App Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Deploy the bot&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now you need to deploy the App to create the messaging endpoint. For that, open the &lt;a href="https://github.com/trycourier/courier-netlify-msteams"&gt;Microsoft Teams Bot Starter Repo&lt;/a&gt; and click the Deploy to Netlify button. There, you will have to connect to your GitHub account and enter your App ID (Bot ID), App Password, &lt;a href="https://app.courier.com/settings/api-keys"&gt;Courier Auth Token&lt;/a&gt;, and a name for the repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/1l8TdpjQHBxZyII6wTz1T8/7d595d569310633ec8f8f188b4f08857/image-11.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/1l8TdpjQHBxZyII6wTz1T8/7d595d569310633ec8f8f188b4f08857/image-11.png" alt="Deploy app on netlify"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the site is deployed, copy your site URL since you need it to finish installing the bot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Install the bot&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, go back to the &lt;strong&gt;Tools &amp;gt; Bot Management&lt;/strong&gt; tab in &lt;strong&gt;Developer Portal&lt;/strong&gt; and select the created bot to finalize the installation process. There, select the Configure option and copy the site URL to the Bot endpoint address field.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/3MSoYstFOcCu92kmVmwTWd/7f4b8dd17db4999c6d0873112a8aca27/Bot_Endpoint_Developer_Portal.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/3MSoYstFOcCu92kmVmwTWd/7f4b8dd17db4999c6d0873112a8aca27/Bot_Endpoint_Developer_Portal.png" alt="Bot Endpoint Developer Portal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, select the &lt;strong&gt;Channels&lt;/strong&gt; option from the left menu and tick the &lt;strong&gt;Microsoft Teams&lt;/strong&gt; option.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/5t8S8x0RqXXaLE6SGIrb31/6174c8f87136d972c2f9e87cba194cd8/Channels_Developer_Portal.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/5t8S8x0RqXXaLE6SGIrb31/6174c8f87136d972c2f9e87cba194cd8/Channels_Developer_Portal.png" alt="Channels Developer Portal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Add the Teams integration to Courier&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, you need to create a Teams integration in Courier. For that, navigate to the &lt;strong&gt;Channels&lt;/strong&gt; tab and select Microsoft Teams from the options. Then, it will show a window like the one below. Enter the &lt;strong&gt;App ID&lt;/strong&gt;, &lt;strong&gt;App Password&lt;/strong&gt; and click the &lt;strong&gt;Install Provider&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/60s7rXRUyYBWby7VaCv4oZ/dd3a0a79a075c791fe3968d5c8a81d92/Channel_Teams.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/60s7rXRUyYBWby7VaCv4oZ/dd3a0a79a075c791fe3968d5c8a81d92/Channel_Teams.png" alt="Channel Teams"&gt;&lt;/a&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/5QmeLiEkDVGii3zjF2v7Yr/34011d75428a42c2c3175c6a89337608/image-15.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/5QmeLiEkDVGii3zjF2v7Yr/34011d75428a42c2c3175c6a89337608/image-15.png" alt="Get link to team"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Sending a Simple Teams Notification with Python&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the code snippet below to your codebase (e.g. index.py ) and update the following properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  replace &lt;code&gt;&amp;lt;auth-token&amp;gt;&lt;/code&gt; with your Courier API key&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;conversation_id&lt;/code&gt;: get the conversation id from threadId query parameter from the URL after opening Microsoft Teams in the browser&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;service_url&lt;/code&gt;: the service URL associated with that Microsoft Teams tenant (if you are located in the Americas Region, the service url is &lt;a href="https://smba.trafficmanager.net/amer"&gt;https://smba.trafficmanager.net/amer&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;tenant_id&lt;/code&gt;: go to &lt;a href="https://teams.microsoft.com/?tenantId"&gt;https://teams.microsoft.com/?tenantId&lt;/a&gt; and copying the value from the redirected URL tenantId query parameter, or click the three dots next to your Team and click &lt;strong&gt;Get link to team&lt;/strong&gt; to find a link with the tenantId parameter
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from trycourier import Courier
client = Courier(auth_token="&amp;lt;auth-token&amp;gt;"

resp = client.send_message(
  message={
      "to": {
      "ms_teams": {
          "conversation_id": "Yl2wJmlmFQkc65UAg0I2kJyCnPJlXvIM4Q3XSrDBZnQ1",
          "tenant_id": "aac0c564-6c5e-4b05-8dc3-408087f77f76",
          "service_url": "https://smba.trafficmanager.net/amer",
      },
      },
      "template": "M79W7S9TRYM04CM634A805T8SYKM",
      "data": {
      },
  } 
)
print(resp['requestId'])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, you can run the python script, and you will see a notification in your Team channel.&lt;/p&gt;

&lt;p&gt;Microsoft Teams Resources&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.courier.com/docs/guides/providers/direct-message/microsoft-teams/"&gt;Teams Integration documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.courier.com/docs/guides/getting-started/python/"&gt;Python quick start guide&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Routing to multiple channels
&lt;/h1&gt;

&lt;p&gt;Courier's multi-channel functionality allows you to send notifications across multiple channels, including email, SMS, push notifications, voice, chatbots, and social media platforms, using a single API.&lt;/p&gt;

&lt;p&gt;For example, if you want to send an urgent alert to your team, you would use Courier to send this alert as an email, as well as a Slack or Teams notification. As you can see below, Courier supports a large selection of Email, SMS, chat, and push notification providers.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/79z4TRaE3a2PunYENuHsUZ/da046abe8e232c15a78af03ee27c5435/channels.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/79z4TRaE3a2PunYENuHsUZ/da046abe8e232c15a78af03ee27c5435/channels.png" alt="Channels"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s update the notification template to send across four channels: email, SMS, Slack, and Teams. First, add email and SMS channels to the template and make sure they both also have the same content as the previous two (remember, you can use the Library to drop in pre-built content blocks).&lt;/p&gt;

&lt;p&gt;Next, update the Settings of each channel so that “Always send to” is toggled on (away from “Best Of”) for each of the four channels listed.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/4FHXzgaBVw4lgmvaSjJCyo/ee47ec3c01f60b41b6620d30b44b2b7f/Always_send_to.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/4FHXzgaBVw4lgmvaSjJCyo/ee47ec3c01f60b41b6620d30b44b2b7f/Always_send_to.png" alt="Always send to Slack"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;trycourier&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Courier&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Courier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth_token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;auth-token&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;slack&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;xoxb-abcd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;example@gmail.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ms_teams&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;conversation_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;85S5NWXJVQ4GN8J21JSKV3JVCSV2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tenant_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aac0c564-6c5e-4b05-8dc3-408087f77f76&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service_url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://smba.trafficmanager.net/amer&lt;/span&gt;&lt;span class="sh"&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;template&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Z5N9D2J8DSMBKEHWF27AEEF6J822&lt;/span&gt;&lt;span class="sh"&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;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;requestId&lt;/span&gt;&lt;span class="sh"&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="//images.ctfassets.net/z7iqk1q8njt4/4BUpIEvF4twcNx4POd0sO0/58b2c3859e8fb57a0b270d1bdcc238df/Four_channels.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/4BUpIEvF4twcNx4POd0sO0/58b2c3859e8fb57a0b270d1bdcc238df/Four_channels.png" alt="Four channels"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also decide whether you actually want to send to all four channels or only specific ones. “Best of” means that Courier will send to one channel out of all that are listed. E.g. if you list Slack as “Always send to”, but have email and SMS as “Best of”, Courier will send a Slack message and attempt to send an email. If the email fails to deliver for any reason, Courier will then reroute to SMS. This means it will only send an SMS if and when email fails.&lt;/p&gt;

&lt;h1&gt;
  
  
  Automating Slack and Teams Notifications## Automating Slack notifications
&lt;/h1&gt;

&lt;p&gt;If you prefer a visual workflow, you can create an automation template within Courier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.courier.com/automations"&gt;Create a new Automation&lt;/a&gt;, select a schedule Trigger, and add a Send step for your notification. We will update the Type to "Date" and Date to the specific date/time this message should be sent.&lt;/p&gt;

&lt;p&gt;In the Send step, select JSON and use the Editor to add the recipient information. In the editor, click "+ Add field" and add slack as an Object. Then click "+Add nested field" and add &lt;code&gt;access_token&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt; with the appropriate values from the code above.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/5mGTvwwLzJJkdFJC9s0a2K/d4d299365be7cf11823824f5866ff6b6/automation_2.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/5mGTvwwLzJJkdFJC9s0a2K/d4d299365be7cf11823824f5866ff6b6/automation_2.png" alt="Update automation JSON"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating Teams notifications
&lt;/h2&gt;

&lt;p&gt;The notification template will automatically send to all selected channels.&lt;/p&gt;

&lt;p&gt;Head over to the Automation and, in the JSON editor of the Send step, click "+ Add field" and add ms_teams as an Object. Then click "+Add nested field" and add &lt;code&gt;conversation_id&lt;/code&gt;, &lt;code&gt;tenant_id&lt;/code&gt;, and &lt;code&gt;service_id&lt;/code&gt;, with the appropriate values from the code above.&lt;/p&gt;

&lt;p&gt;This automation will now have the required user profile data to send to both Slack and MS Teams. If you also want to send to an email or SMS, edit the JSON object to add field for &lt;code&gt;"email"&lt;/code&gt; and &lt;code&gt;"phone_number"&lt;/code&gt; with the appropriate values.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Automating notifications in team communication platforms such as Slack and Teams can significantly improve team productivity and communication. However, building automated notifications from scratch can be complex and time-consuming. That's where Courier comes in with its easy-to-use Python SDK that allows developers to send notifications to multiple channels with just a few lines of code.&lt;/p&gt;

&lt;p&gt;By following the steps outlined in this article, you can set up notification automation with Courier and Python for both Slack and Teams. Additionally, you can leverage Courier's multi-channel functionality to integrate other applications and channels into your notification system.&lt;/p&gt;

&lt;h1&gt;
  
  
  FAQs
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;1. What is Courier?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.courier.com/"&gt;Courier&lt;/a&gt; connects communication APIs, data, and development tools that your team already uses to deliver a best-in-class notification system that will trigger messages from your app at just the right time, using just the right channel. It provides powerful API primitives and reusable UI components for building, plus no-code tools for designing templates and communication sequences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. What is Slack?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Slack is a cloud-based messaging platform that enables teams to communicate and collaborate in real-time. It is known for its user-friendly interface and extensive third-party integrations, making it a highly customizable platform for teams of all sizes. Slack allows users to easily organize their conversations into channels, share files, and collaborate with other team members. It also offers multiple app integrations, including project management and automation tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. What is Microsoft Teams?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Microsoft Teams is another popular communication and collaboration platform that is part of the Microsoft Office 365 suite. It enables teams to chat, share files, and collaborate in real time, both synchronously and asynchronously. With features such as video conferencing, screen sharing, and group chats, Microsoft Teams is ideal for businesses and organizations that require a comprehensive and centralized collaboration platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Missing Provider Support error message&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your message did not go through, check your Courier logs. For a "MISSING_PROVIDER_SUPPORT" error message, you will need to double-check if the Slack and/or  Teams channels were installed properly in Courier. Try removing the channel(s) (go to the channel and click "Remove Channel" at the bottom of the page) that is causing the error and then adding it again.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>New Courier Inbox: Add a full-featured notification center to your app in minutes</title>
      <dc:creator>Riley</dc:creator>
      <pubDate>Wed, 15 Mar 2023 17:18:49 +0000</pubDate>
      <link>https://forem.com/courier/new-courier-inbox-add-a-full-featured-notification-center-to-your-app-in-minutes-17mn</link>
      <guid>https://forem.com/courier/new-courier-inbox-add-a-full-featured-notification-center-to-your-app-in-minutes-17mn</guid>
      <description>&lt;p&gt;Email and SMS are becoming increasingly busy channels. Sometimes, there’s no better way to reach a user than by sending a message to a notification center right inside of your app. However, building an inbox experience like this, from scratch, was a significant engineering effort.&lt;/p&gt;

&lt;p&gt;Today, we are announcing a major update to &lt;a href="https://www.courier.com/docs/inbox/"&gt;Courier Inbox&lt;/a&gt;, a solution for developers to add an in-app notification center to their web application in a matter of minutes.&lt;/p&gt;

&lt;p&gt;If you’re using the previous version of Inbox, we’ll cover the upgrade steps later in this post.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"With Courier, we added a beautiful inbox and in-app push notifications in a matter of weeks. We used the great looking pre-built component to save even more time. Notifications are not our core competency, so it made complete sense to integrate rather than build out and support our own implementation."&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;James Pipe&lt;/strong&gt;, VP of Product, &lt;a href="https://www.dronedeploy.com/"&gt;DroneDeploy&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Courier Inbox is an in-app notification center for web applications (and &lt;a href="https://updates.courier.com/board"&gt;mobile inbox coming soon&lt;/a&gt;). Inbox acts as a convenient in-app notification feed with a clean interface where users can view notifications in real time  directly inside your web app. It also lets them view their message history of all past notifications that you’ve sent to them.&lt;/p&gt;

&lt;p&gt;Using in-app notifications allows you to get users’ attention when they are in the application.  This makes your communication with your users more timely and convenient: instead of interrupting them with an email on their phone when they are busy doing something else, you can use an in-app notification to provide information that is relevant to what your users are trying to do right now. Showing notifications within your web application increases user engagement — and provides a more seamless experience, as you can link users directly to relevant parts of the web app within these notifications.&lt;/p&gt;

&lt;p&gt;While many companies are considering building notifications into their web app, not everyone has the time or resources to build a full-fledged notification center. We first implemented Inbox two years ago together with the &lt;a href="https://www.courier.com/blog/react-toast-inbox-notifications/"&gt;web-based pop-up notification&lt;/a&gt; functionality, and customers loved it exactly because it takes so little time to start using it.&lt;/p&gt;

&lt;p&gt;The notifications that customers send via Inbox may include application activity such as discussions, new events, comments, alerts, and reminders, as well as news about feature updates.&lt;/p&gt;

&lt;p&gt;Based on customer feedback, we’re excited to announce improvements to the Inbox functionality. Meet the new Inbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing the new Inbox
&lt;/h2&gt;

&lt;p&gt;The new Inbox has all the benefits of the original Inbox: it’s fast to implement via pre-built &lt;a href="https://github.com/trycourier/courier-react/tree/main/packages/react-inbox"&gt;Courier JavaScript components&lt;/a&gt;, it offers an intuitive user experience, the design is customizable to your needs, and it natively integrates with the rest of the Courier platform. On top of that, Inbox includes a number of improvements, in terms of both design and functionality.&lt;/p&gt;

&lt;p&gt;On the design side, we took customer feedback on board and simplified how the inbox looks and feels. Specifically, here’s what changed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Visually, the inbox now looks more modern so that it fits better into customer apps.&lt;/li&gt;
&lt;li&gt;There are no more separate tabs for read and unread messages — this separation into tabs previously led to confusion. Now everything is displayed more clearly in a single feed.&lt;/li&gt;
&lt;li&gt;Hovering over a message now shows a check mark or cross to mark a message as read or unread, instead of a vertical three-dot menu taking up screen real estate.&lt;/li&gt;
&lt;li&gt;Unread messages are identified by a colorful logo (vs. gray for unread), and the colors are customizable. A colored dot appears at the top showing how many unread messages there are in the inbox.&lt;/li&gt;
&lt;li&gt;Hovering over a message makes the background of that message change color if it is clickable. Short messages where all the text can be viewed at a glance are not clickable and don't change color on hover.
&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/6BJa4hWUJjED61Kdt0CEAR/965e76e0a0ec92213e7fde2402e68683/Courier_-_Inbox_2.0_-_UI_Screenshot.png" alt="New Courier Inbox UI"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notification state is now synchronized between the inbox and other channels. For example, if a notification was sent as in-app and email, reading the email will mark the in-app notification as read.&lt;/p&gt;

&lt;p&gt;Another new feature is message expiration. It’s now possible to set a timeline for the message to expire, say 7 days, and after that time the message will be removed from the inbox. This feature can help avoid a mess of older notifications for users that rarely sign into the web app.&lt;/p&gt;

&lt;p&gt;The advanced branding options, including applying brand settings (we cover this below) and removing the Courier logo, as well as message retention are available on our Developer and Business tiers.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>New RudderStack Integration: Create Actionable Insights</title>
      <dc:creator>Tejas Kumthekar</dc:creator>
      <pubDate>Wed, 08 Mar 2023 17:00:32 +0000</pubDate>
      <link>https://forem.com/courier/new-rudderstack-integration-create-actionable-insights-3ooe</link>
      <guid>https://forem.com/courier/new-rudderstack-integration-create-actionable-insights-3ooe</guid>
      <description>&lt;p&gt;Are you looking for a way to gain a clearer picture of your users and use that insight to improve your communication strategies? We've got some great news for you! Today, we're thrilled to announce an integration between Courier and &lt;a href="https://www.rudderstack.com/"&gt;Rudderstack&lt;/a&gt;, a customer data platform (CDP) that allows businesses to collect, process, and route customer event data across product, marketing, and analytics tools for better decision-making. &lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/21cNA4cs1XUQkN6bUZkyO8/ebd8e69ee53020b4d57d23212aae53c5/Rudderstack_Courier_data_flow.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/21cNA4cs1XUQkN6bUZkyO8/ebd8e69ee53020b4d57d23212aae53c5/Rudderstack_Courier_data_flow.png" alt="Rudderstack Courier data flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This integration builds on our &lt;a href="https://www.courier.com/blog/smarter-customer-engagement-flows-segment-integration/"&gt;recently improved integration with Segment&lt;/a&gt; and will further improve your ability to track your users' actions and take advantage of customer data stored in RudderStack to improve the notification experience for your users.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Courier makes it easy to trigger notifications based on RudderStack events. We're really excited about this integration because it removes a lot of complexity for engineers and data teams looking to build a notification system."&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Eric Dodds&lt;/strong&gt;, Head of Product Marketing, &lt;a href="https://www.rudderstack.com/"&gt;RudderStack&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For those who may not be familiar with RudderStack, it’s a &lt;a href="https://www.rudderstack.com/blog/what-is-a-customer-data-platform/"&gt;customer data platform&lt;/a&gt; (CDP) that allows businesses to collect, process, and route customer event data across product, marketing and analytics tools for better decision-making. As for Courier, it’s an all-in-one notifications solution that enables development teams to manage communications with their users, from product notifications to marketing messages, through a number of channels, such as email, chat, in-app messages, SMS, and push, all in one place.&lt;/p&gt;

&lt;p&gt;So, by integrating Courier with RudderStack, you get the combined benefits of both systems: you can now collect, process, and route your users' interaction data between Courier and different marketing and analytics tools, via RudderStack. This integration can help you gain a clearer picture of your users and use that insight to improve your communication strategies. &lt;/p&gt;

&lt;p&gt;You can also track notification engagement data, such as the percentage of communications that were successfully delivered, opened and read, and on what notification channels. The detailed notification analytics data gives you the potential to create more personalized app experiences for users based on their activity within your product. For example, you could adjust the way a user receives notifications based on their interactions with your product, as well as data from Salesforce, Google Ads, Mailchimp, and other RudderStack sources.&lt;/p&gt;

&lt;h2&gt;
  
  
  More about Courier
&lt;/h2&gt;

&lt;p&gt;Courier is an API and web studio that centralizes all product-triggered communications, such as email, chat, in-app messages, SMS, and push notifications. With Courier, businesses can deliver messages to their users using their preferred communication channels, with real-time visibility and tracking for each message. This tracked data within Courier can now be passed to RudderStack!&lt;/p&gt;

&lt;p&gt;One of the best things about Courier is that it provides a single, unified interface for developers to manage all communications. This reduces complexity and eliminates the need for developers to manage multiple APIs and libraries to send notifications to various channels. Courier's simple and elegant APIs make it easy for developers to create new notifications and manage messages in a way that doesn’t require additional work for each new notification channel.&lt;/p&gt;

&lt;h2&gt;
  
  
  More about RudderStack
&lt;/h2&gt;

&lt;p&gt;RudderStack, as we already mentioned, is an easy-to-use CDP, with a straightforward installation process and intuitive user interface. It doesn’t require any in-depth technical knowledge, making it a popular choice for businesses that want to collect and process customer data without the need for a dedicated development team.&lt;/p&gt;

&lt;p&gt;Unlike most other CDPs, RudderStack is open-source, which means that developers can access the source code, modify it to suit their needs, and contribute to the development of the platform. Additionally, RudderStack offers a range of pricing plans, including a free plan, making it accessible to businesses of all sizes. Another great feature of RudderStack is that you can host it in your private cloud infrastructure, giving you even more control over your data.&lt;/p&gt;

&lt;p&gt;Unlike most other CDPs, RudderStack is open-source, which means that developers can access the source code, modify it to suit their needs, and contribute to the development of the platform. Additionally, RudderStack offers a range of pricing plans, including a free plan, making it accessible to businesses of all sizes. Another great feature of RudderStack is that you can host it in your private cloud infrastructure, giving you even more control over your data.&lt;/p&gt;

&lt;h2&gt;
  
  
  RudderStack’s control plane
&lt;/h2&gt;

&lt;p&gt;The RudderStack platform consists of two main components: the user-facing control plane and the data plane that operates under the hood. In this section, we'll take a closer look at the control plane.&lt;/p&gt;

&lt;p&gt;The control plane is the web-based interface that allows you to manage data integrations, monitor data flows, and control user access. It's the place where you can configure and manage your RudderStack accounts, add and remove integrations, and control who can access data.&lt;/p&gt;

&lt;p&gt;RudderStack’s control plane also lets you manage your data integrations easily. For instance, you can set up and choose your data destinations and sources, control who can access the data, and monitor the flow of data between the sources and destinations. &lt;/p&gt;

&lt;p&gt;In RudderStack, &lt;a href="https://www.rudderstack.com/docs/sources/overview/"&gt;sources&lt;/a&gt; are platforms or applications from which RudderStack tracks and collects data. A &lt;a href="https://www.rudderstack.com/docs/dashboard-guides/destinations/"&gt;destination&lt;/a&gt;, on the other hand, is a cloud tool or a platform where you want to send this collected data.&lt;/p&gt;

&lt;p&gt;From the control plane, you can also create custom transformations and enrichments to modify the data before it gets sent to the destination. These features provide you with granular control over your data integrations and allow you to create custom data pipelines that fit your specific needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Events — the data sent by Courier
&lt;/h2&gt;

&lt;p&gt;There are two types of user data Courier can now send to RudderStack: message events and audience events.&lt;/p&gt;

&lt;p&gt;Message events are all about notification deliverability and user engagement. These events track whether a message was sent, delivered, clicked, and opened. Message events help businesses track notification usage data, including successful deliveries, opens, clicks, and the channels through which messages are sent. This data can help businesses create custom user journeys that are tailored to users' communication preferences, improving the overall user experience.&lt;/p&gt;

&lt;p&gt;Audience events, on the other hand, make use of Courier's dynamically defined user groups, known as audiences. Audiences give you more flexibility than static lists. For instance, you can define an audience as a set of users with the title “Software Engineer.” You can even take this one step further and define more niche audiences by specifying that the user also has listed, for example, TypeScript as one of their favorite programming languages. &lt;/p&gt;

&lt;p&gt;Audience events allow you to track when people join or leave these pre-defined groups based on changes in user characteristics, allowing for better data collection and therefore improved end user experience. For example, an audience event would be triggered if someone changed their job title to “Software Engineer” or if they changed it from “Software Engineer” to something else. This gives you control over the type and amount of notifications specific users receive, improving their overall experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using this new data
&lt;/h2&gt;

&lt;p&gt;When your events have been loaded in RudderStack, you can use different aggregate views to study them, or you can forward them to an analytics destination like Looker or Tableau. This integration enables you to perform analytics on your notification data, giving you powerful insights about how your users interact with your product, and create even more enjoyable notification experiences. &lt;/p&gt;

&lt;p&gt;You can also automatically update information in Courier from your product or from other software tools via RudderStack. For example, if a user changes their email address in your web app, you can propagate that information into the user’s profile in Courier without the need to add a separate Courier API request.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are you waiting for?
&lt;/h2&gt;

&lt;p&gt;Whether you're new to RudderStack or an existing user, integrating Courier is a straightforward process. To enable the integration, add Courier as a source and/or destination. Adding Courier as a destination is as simple as specifying Courier as a "destination" in your RudderStack dashboard. Just navigate to ‘&lt;a href="https://app.rudderstack.com/directory"&gt;directory&lt;/a&gt;’, go to the &lt;code&gt;destinations tab&lt;/code&gt; and search for Courier.&lt;/p&gt;

&lt;p&gt;For more detailed information on how to implement courier as a source or destination, and help getting started with the RudderStack and Courier integration, visit our &lt;a href="https://www.courier.com/docs/external-integrations/rudderstack/"&gt;documentation&lt;/a&gt; and follow the steps outlined there. This will start the flow of data and can start giving insights straight away, helping you to improve your user experience and helping you make better product decisions.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Introducing Courier Preferences: The Fastest Way to Design the Best Preference Experience</title>
      <dc:creator>Charla Bigelow</dc:creator>
      <pubDate>Thu, 23 Feb 2023 16:32:17 +0000</pubDate>
      <link>https://forem.com/courier/introducing-courier-preferences-the-fastest-way-to-design-the-best-preference-experience-1503</link>
      <guid>https://forem.com/courier/introducing-courier-preferences-the-fastest-way-to-design-the-best-preference-experience-1503</guid>
      <description>&lt;p&gt;Notification preferences are important — especially if you’re building an application that sends dozens of notifications. Users want control over which kind of notifications they receive, and through what channels. That’s why it is essential to provide a well-designed preference experience that’s quick, intuitive, and guaranteed to respect your users’ chosen preferences.&lt;/p&gt;

&lt;p&gt;With Courier, you can build great notification infrastructure effortlessly. But until now, preferences were handled separately, requiring engineers to spend a significant amount of time on both the back-end logic and the UI where users could select which notifications they want to receive and how.&lt;/p&gt;

&lt;p&gt;As an engineer myself, I’ve had to build workflows like this several times in past projects &amp;amp; companies. But those days are over: we’re excited to announce general availability of Courier Preferences. With Courier Preferences, you can build a full notification Preference Center in no time. The clean interface, which comes with endless options for customization, lets users manage their preferences. Courier’s infrastructure will take care of the rest by integrating them into our core products that trigger sends.&lt;br&gt;
&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/1zGTehzHW9Zhm9bF9mMJ54/7f165ef31524e36198b437e748075d4a/preferences_center.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/1zGTehzHW9Zhm9bF9mMJ54/7f165ef31524e36198b437e748075d4a/preferences_center.png" alt="Preferences Center"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Within the Preference Center, users can comfortably &lt;a href="https://www.courier.com/blog/pm-guide-to-preference-management/" rel="noopener noreferrer"&gt;opt in and out of notifications by topic and channel&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Whether you want to build a bespoke notification experience with the Preferences API, embed our pre-built UI components, or use the hosted preferences page that Courier provides out of the box for faster time to value, is entirely up to you.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Courier turned something that takes months into days. We were able to unlock the ability for our users to opt in/out of notifications in a customized Preference Center within one day. It was easy."&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Guilherme Samora&lt;/strong&gt;, Senior Product Manager, &lt;a href="https://www.sastrify.com/" rel="noopener noreferrer"&gt;Sastrify&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this post, we’ll look at how to implement the best preference experience for your users. We’ll talk about how Courier makes it easy to handle preference settings and logs, and how the new Preferences Designer makes preference management a walk in the park. But first, let’s briefly recap why it’s important to implement preferences for your users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notification preferences are a vital feature of any app
&lt;/h2&gt;

&lt;p&gt;Aside from their core functionality of alerting your users to activity in the app that requires their attention, notifications can be used to increase users’ awareness of your product’s features, for marketing and other purposes. &lt;/p&gt;

&lt;p&gt;But getting all these kinds of notifications from different organizations can quickly become annoying for users. To make sure they remain in control of their own notification experience, and to avoid them turning off all notifications from your app, it is vital that you implement notification preferences that are fine-grained and easy to use. And it’s just as important that you respect those preferences and only send your users the notifications they really want.&lt;/p&gt;

&lt;p&gt;Building notification preferences for your app from scratch is hard, especially if you use more than one channel to communicate with your users. It requires a significant amount of time and engineering resources — and don’t forget the need for future maintenance. By letting Courier host your preference infrastructure, you can instead use those resources to focus on building your core product. &lt;br&gt;
&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/7F272P2uQSET33IeUXnNv5/ee57c441348aa4e771bd187d6b6fa6ea/preferences-infrastructure.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/7F272P2uQSET33IeUXnNv5/ee57c441348aa4e771bd187d6b6fa6ea/preferences-infrastructure.png" alt="Preferences Infrastructure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here at Courier, we have spent quite some time thinking about what the best preference experience looks like. It needs to be clean, customizable, and easy to use for the end users. It also needs to offer sufficient transparency for compliance and record-keeping purposes on the back end. Since these requirements align across products, there is no need for every company to build their own. Instead, Courier Preferences lets you set up the notification experience that you want for your users in just a few hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to design a good preference experience
&lt;/h2&gt;

&lt;p&gt;You can now use the &lt;a href="https://www.courier.com/docs/courier-preferences/preference-center/introduction/#preferences-designer" rel="noopener noreferrer"&gt;Preferences Designer&lt;/a&gt; in the Courier web interface to design the best preference experience for your users. (As an alternative to the Preferences Designer, you can use the Preferences API for a more native experience within your app — more on that later.)&lt;/p&gt;

&lt;p&gt;Since most applications send out many different notifications, it can quickly become cumbersome for users to manually set preferences for every single option. For a better user experience, Courier groups notifications by &lt;a href="https://www.courier.com/docs/courier-preferences/#what-is-a-subscription-topic" rel="noopener noreferrer"&gt;subscription topics&lt;/a&gt; (formerly called “categories”). In addition, business tier Courier customers can bundle several topics by sections: as an example, you could set up two topics named “Feature launch” and “Product update” and file them both under a “Product” umbrella section, for even easier preference management.&lt;/p&gt;

&lt;p&gt;Turning notifications on and off is not all, however. Notifications can be sent via &lt;a href="https://www.courier.com/docs/getting-started/courier-concepts/#channels" rel="noopener noreferrer"&gt;different channels&lt;/a&gt; in Courier, such as email, SMS, and push notifications. Users can select which channels they prefer for each subscription topic. For instance, they might prefer to be notified via email about a new message or rating on a social media platform, but not about minor interactions such as likes. Conversely, they may want to activate multiple channels — like SMS, email, and Slack — if there’s an emergency, like a security breach.&lt;/p&gt;

&lt;p&gt;As a developer, you can turn certain notifications on and off by default for different topics and channels. You can also set certain indispensable notification topics as required. By marking a notification topic as required (for example, "Reset Password"), it prevents your users from disabling notifications for that topic, while reassuring them that they’ll still receive such critical notifications even if they disable everything else.&lt;br&gt;
&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/4QZxztLxHb1sx0Lxagztxc/1f489f232c4e074cd88b941715ff3ff6/subscription_topics.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/4QZxztLxHb1sx0Lxagztxc/1f489f232c4e074cd88b941715ff3ff6/subscription_topics.gif" alt="Subscription Topics"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Voilà: a user-facing Preference Center
&lt;/h3&gt;

&lt;p&gt;In the Preferences Designer, you can preview how your users will see the Preference Center in their browser. The page is designed to be easily navigable: preferences for notification topics and channels can be turned on and off with the click of a mouse. &lt;br&gt;
&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/XEsGsLpOZrEmHfXynxBsx/34639f4228816802dd71a29635874a84/user-preferences.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/XEsGsLpOZrEmHfXynxBsx/34639f4228816802dd71a29635874a84/user-preferences.gif" alt="Preferences Center"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All of these features are available in our free tier. For more functionality, like multiple sections or the ability to remove the Courier watermark from the user-facing Preference Center, use our &lt;a href="https://www.courier.com/request-demo" rel="noopener noreferrer"&gt;Business plan&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your preference UI, hosted by Courier
&lt;/h3&gt;

&lt;p&gt;You can now direct users to their personal Preference Center through a hyperlink in your notifications to them. In newer Courier workspaces, your notification templates will include this hyperlink by default. Otherwise, you can &lt;a href="https://www.courier.com/docs/courier-preferences/preference-center/hosted-page/#preference-center-link" rel="noopener noreferrer"&gt;add the link manually&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By following the link, your users will be able to see and update their own notification preferences within the Preference Center. Note that this requires no login: by automatically encoding their &lt;strong&gt;user_id&lt;/strong&gt; in the Preference Center hyperlink, it will be personalized to that user, and their preferences will be saved in their profile in the back end. &lt;br&gt;
&lt;a href="//images.ctfassets.net/z7iqk1q8njt4/7qkwz5ZMzIFWRXjdGoYcHw/49c0ee1ca66838f98efce8e9ffe8325c/Preferences__feature_launch_post_2.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/z7iqk1q8njt4/7qkwz5ZMzIFWRXjdGoYcHw/49c0ee1ca66838f98efce8e9ffe8325c/Preferences__feature_launch_post_2.png" alt="Preferences architecture diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that’s it: the easiest way to create the best customized preference experience, with only a few clicks in the Courier Preferences Designer.    &lt;/p&gt;

&lt;h2&gt;
  
  
  Build your own interface via the Preferences API
&lt;/h2&gt;

&lt;p&gt;You don’t have to use the hosted Preference Center — you can build your own, or even integrate notification controls elsewhere in your application. Have a look at the &lt;a href="https://www.courier.com/docs/courier-preferences/user-preferences-api/" rel="noopener noreferrer"&gt;documentation for the Courier Preferences API&lt;/a&gt; to learn more. &lt;/p&gt;

&lt;p&gt;Finally, you can choose the middle ground and embed &lt;a href="https://www.courier.com/docs/courier-preferences/use-guides/embed-courier-preferences/" rel="noopener noreferrer"&gt;Courier’s prebuilt component&lt;/a&gt; in your own preferences UI. &lt;/p&gt;

&lt;h2&gt;
  
  
  A user-friendly unsubscribe experience
&lt;/h2&gt;

&lt;p&gt;Unsubscribing from unwanted notifications should be fast and easy — and you should make sure to respect your users’ preferences to avoid unnecessary frustration. Similar to the preferences hyperlink, you can easily &lt;a href="https://www.courier.com/docs/courier-preferences/use-guides/embed-courier-preferences/#unsubscribing-from-notifications" rel="noopener noreferrer"&gt;embed an unsubscribe link&lt;/a&gt; in your notification template. By clicking on it, users can unsubscribe from topics that they’re not interested in. &lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping a digital paper trail of your users’ preference history
&lt;/h2&gt;

&lt;p&gt;Keeping &lt;a href="https://www.courier.com/docs/courier-preferences/logs/" rel="noopener noreferrer"&gt;logs of your users’ changes in preference settings&lt;/a&gt; is useful for debugging, compliance, and solving issues in customer support. Courier automatically logs all your users’ changes in notification preferences and lets you view them via the API or directly in the Courier web interface. &lt;/p&gt;

&lt;p&gt;Let’s say, for instance, that a user isn’t receiving your notifications, even though they were enabled in their settings. You can now simply check the logs to determine where the error occurred. Conversely, a user might complain that they’re still receiving unwanted notifications after they thought they turned them off. By looking at the preference logs, you can see whether they indeed turned notifications off, or if they accidentally enabled them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started with Courier Preferences today
&lt;/h2&gt;

&lt;p&gt;Being able to offer users a fine-grained and intuitive preference experience saves companies a lot of time and puts them further ahead on their roadmap. We’re excited to make preference management easy and smooth for businesses.&lt;/p&gt;

&lt;p&gt;To learn more and start designing the best preference experience for your audience, take a closer look at &lt;a href="https://www.courier.com/features/preferences/" rel="noopener noreferrer"&gt;Courier Preferences&lt;/a&gt; and the &lt;a href="https://www.courier.com/docs/courier-preferences/" rel="noopener noreferrer"&gt;docs&lt;/a&gt;. We’re sure your users will love it!&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
  </channel>
</rss>
