<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SuprSend</title>
    <description>The latest articles on DEV Community by SuprSend (suprsend).</description>
    <link>https://dev.to/suprsend</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.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F6319%2Fbabd7ef9-76cf-4dd5-b512-a13f0ceb4758.png</url>
      <title>DEV Community: SuprSend</title>
      <link>https://dev.to/suprsend</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/suprsend"/>
    <language>en</language>
    <item>
      <title>One Platform for Every Notification Channel, and a CLI to Manage It All From Your Terminal</title>
      <dc:creator>Nikita Navral</dc:creator>
      <pubDate>Wed, 21 Oct 2026 10:42:52 +0000</pubDate>
      <link>https://dev.to/suprsend/one-platform-for-every-notification-channel-and-a-cli-to-manage-it-all-from-your-terminal-1lg6</link>
      <guid>https://dev.to/suprsend/one-platform-for-every-notification-channel-and-a-cli-to-manage-it-all-from-your-terminal-1lg6</guid>
      <description>&lt;p&gt;If you've ever built notifications into a product, you know it starts with one email and ends with a small platform: multiple channels, multiple vendors, templates, user preferences, retries, analytics, and a PM asking for copy changes every week.&lt;/p&gt;

&lt;p&gt;This post is a quick introduction to &lt;strong&gt;SuprSend&lt;/strong&gt;, the notification infrastructure we work on, and then a closer look at the &lt;strong&gt;SuprSend CLI&lt;/strong&gt;, which lets you manage all of it from your terminal and your Git repo.&lt;/p&gt;

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

&lt;p&gt;SuprSend is a notification infrastructure platform. Instead of wiring up each channel and vendor yourself, you integrate once and manage the notification layer in one place.&lt;/p&gt;

&lt;p&gt;It covers the pieces most teams end up building on their own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multiple channels:&lt;/strong&gt; email, SMS, push, in-app inbox, WhatsApp, Slack and more, through one integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflows:&lt;/strong&gt; the logic for when, to whom and on which channel a notification goes out&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Templates:&lt;/strong&gt; content for each channel, with variables and personalization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User preferences:&lt;/strong&gt; letting end users choose what they get and where&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-tenancy:&lt;/strong&gt; per-customer branding and settings for B2B products&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics:&lt;/strong&gt; delivery and engagement data in one place across channels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is simple: your engineers shouldn't spend sprints reinventing notification plumbing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gap: great platform, but changes happen in a dashboard
&lt;/h2&gt;

&lt;p&gt;Most of these assets (templates, workflows, preferences) are authored in a dashboard. That's friendly for PMs and marketers, but it creates a mismatch for engineering teams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The source of truth isn't in your repo&lt;/li&gt;
&lt;li&gt;Staging and production can drift apart&lt;/li&gt;
&lt;li&gt;Changes don't go through pull requests&lt;/li&gt;
&lt;li&gt;Promoting to production often means someone needs production dashboard access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Engineers manage everything else from code: app logic lives in a repo, ships through PRs, deploys through CI and rolls back through Git. Notifications should be able to work that way too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter the SuprSend CLI
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;SuprSend CLI&lt;/strong&gt; brings the platform into the terminal. Every core asset (&lt;strong&gt;workflows, templates, schemas, events, preference categories and translations&lt;/strong&gt;) can be managed through commands that fit into scripts and CI/CD pipelines.&lt;/p&gt;

&lt;p&gt;Install on macOS or Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; suprsend/tap/suprsend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then authenticate with a service token. For Windows and CI environments, download the binary from GitHub Releases, or build from source.&lt;/p&gt;

&lt;p&gt;Each asset can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;listed&lt;/li&gt;
&lt;li&gt;pulled to local files&lt;/li&gt;
&lt;li&gt;edited in your editor&lt;/li&gt;
&lt;li&gt;pushed back&lt;/li&gt;
&lt;li&gt;committed from draft to live&lt;/li&gt;
&lt;li&gt;synced between workspaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also activate or deactivate workflows from the shell, which is useful for shipping a new workflow, or for taking a misbehaving one offline during an incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it fits the tools you already use
&lt;/h2&gt;

&lt;p&gt;The CLI is built to slot into your setup rather than replace it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your editor
&lt;/h3&gt;

&lt;p&gt;Pulling an asset writes it as readable JSON into your project. Edit it in your IDE with your usual linting, syntax highlighting and AI completions. When you push it back, it's validated against SuprSend schemas before it's saved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git
&lt;/h3&gt;

&lt;p&gt;Once assets are local files, they live in your repo like any other code. Commits show who changed what, diffs show exactly what shifted, and a revert rolls back a bad change in seconds. Your Git log becomes your notification change history.&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD
&lt;/h3&gt;

&lt;p&gt;Every command is scriptable. A GitHub Action, CircleCI job or any other pipeline can run pulls, pushes and syncs as deploy steps, so notification changes ship on the same cadence as your app code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things you can do with it
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Promote staging to production in one command
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;suprsend &lt;span class="nb"&gt;sync&lt;/span&gt; &lt;span class="nt"&gt;--from&lt;/span&gt; staging &lt;span class="nt"&gt;--to&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because your pipeline does the promotion, nobody needs UI access to the production workspace to ship a change. Production access stays locked down, and changes flow through reviewed pull requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Get type-safe payloads
&lt;/h3&gt;

&lt;p&gt;Generate native type definitions from your SuprSend schemas and drop them into your SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;suprsend schema generate-types &lt;span class="nt"&gt;--schema&lt;/span&gt; order-confirmation &lt;span class="nt"&gt;--output&lt;/span&gt; ./types
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A wrong payload key then fails in your IDE, in CI and in your build, before any send is attempted. The schema becomes a guardrail instead of a runtime surprise.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Manage workflows and templates as code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bootstrap a new workspace&lt;/strong&gt; by provisioning templates from a script instead of building them one by one in the UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migrate templates&lt;/strong&gt; from another tool or an internal codebase without recreating them by hand&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review changes in PRs&lt;/strong&gt; like any other code&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Open source and verifiable
&lt;/h2&gt;

&lt;p&gt;The CLI is &lt;strong&gt;open source and free to use&lt;/strong&gt;. Install via Homebrew, grab the binary from GitHub Releases, or build from source. If you're in a security-sensitive environment, you can verify the binary's signature with &lt;strong&gt;Cosign&lt;/strong&gt; before installing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to go from here
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📖 &lt;a href="https://docs.suprsend.com/reference/cli-intro?_gl=1*1vupz8t*_gcl_au*MjAzODM1MDA1MS4xNzkwMzIxNjUw*_ga*MTQ5OTQ3MjI2Ny4xNzkwMzIxNjUw*_ga_PPDYBESP2L*czE3OTI1NzkxNjQkbzIwJGcxJHQxNzkyNTc5MTY5JGo1NSRsMCRoMTM5NDczNzY1Ng.." rel="noopener noreferrer"&gt;CLI docs&lt;/a&gt;: install and run your first command&lt;/li&gt;
&lt;li&gt;🧰 &lt;a href="https://docs.suprsend.com/reference/cli-intro?_gl=1*oexhsz*_gcl_au*MjAzODM1MDA1MS4xNzkwMzIxNjUw*_ga*MTQ5OTQ3MjI2Ny4xNzkwMzIxNjUw*_ga_PPDYBESP2L*czE3OTI1NzkxNjQkbzIwJGcxJHQxNzkyNTc5Mjg1JGo2MCRsMCRoMTM5NDczNzY1Ng..#available-commands" rel="noopener noreferrer"&gt;All CLI commands&lt;/a&gt;: the full surface&lt;/li&gt;
&lt;li&gt;🌐 &lt;a href="https://www.suprsend.com" rel="noopener noreferrer"&gt;SuprSend&lt;/a&gt;: the platform itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Over to you:&lt;/strong&gt; how does your team manage notification templates today? Dashboard, Git, or a mix? Tell us in the comments.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Choosing The Right Message Queue Technology For Your Notification System</title>
      <dc:creator>Nikita Navral</dc:creator>
      <pubDate>Fri, 16 Oct 2026 10:57:47 +0000</pubDate>
      <link>https://dev.to/suprsend/choosing-the-right-message-queue-technology-for-your-notification-system-1ocl</link>
      <guid>https://dev.to/suprsend/choosing-the-right-message-queue-technology-for-your-notification-system-1ocl</guid>
      <description>&lt;p&gt;Your notification system works great at 100 messages a minute. Then your app goes viral, a flash sale hits, and suddenly your OTPs are stuck behind 2 million promotional pushes.&lt;/p&gt;

&lt;p&gt;Sooner or later, every notification system needs a message queue. The hard part is picking one. Kafka, RabbitMQ, SQS, Pub/Sub and Kinesis all "move messages," but they behave very differently when you need ordering, retries, replays or priorities.&lt;/p&gt;

&lt;p&gt;This guide walks through the factors that matter for notifications, compares the five most common options, and ends with a checklist you can use to decide.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, what do notifications need from a queue?
&lt;/h2&gt;

&lt;p&gt;Forget feature lists for a second. Here's what actually matters, with a real scenario for each.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;Your sports app sends a push whenever a team scores. Traffic is quiet until a derby match, then every user gets a notification within seconds. You need a queue that scales out without redesign.&lt;/p&gt;

&lt;h3&gt;
  
  
  Message retention
&lt;/h3&gt;

&lt;p&gt;You send transaction alerts in real time. One night your consumer crashes for 30 minutes. If the queue discards messages that aren't consumed, those users never hear about their money moving.&lt;/p&gt;

&lt;p&gt;With retention, messages wait in the queue (for an hour, a day, longer) and are processed when the consumer comes back.&lt;/p&gt;

&lt;h3&gt;
  
  
  Low latency
&lt;/h3&gt;

&lt;p&gt;A fraud team needs to be alerted the moment a suspicious transaction appears. Delay matters here.&lt;/p&gt;

&lt;p&gt;A caveat: Redis Pub/Sub is often cited for this, but it's fire-and-forget. If no subscriber is listening, the message is gone. For anything you can't afford to lose, use Redis Streams or a durable broker.&lt;/p&gt;

&lt;h3&gt;
  
  
  High throughput
&lt;/h3&gt;

&lt;p&gt;A food delivery app sends status updates ("being prepared", "on its way") for every order. Volume is high, and many consumers need to process it in parallel. This is where Kafka and Kinesis shine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Message ordering
&lt;/h3&gt;

&lt;p&gt;A trading platform sends market alerts. If "price dropped" arrives after "price recovered," users act on stale information. You need ordering guarantees, at least per user or per entity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prioritization
&lt;/h3&gt;

&lt;p&gt;A hospital monitoring system alerts nurses when a patient's heart rate crosses a threshold. That alert can't wait behind a batch of routine reports.&lt;/p&gt;

&lt;p&gt;One thing to know: &lt;strong&gt;most queues don't have native priority.&lt;/strong&gt; The usual pattern is separate queues or topics per priority:&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="n"&gt;TOPICS&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;critical&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;notif.critical&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# OTP, security, health alerts
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&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;notif.high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;# transactional
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&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;notif.low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;# promos, digests
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;TOPICS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;   &lt;span class="c1"&gt;# same user -&amp;gt; same partition -&amp;gt; ordered
&lt;/span&gt;    &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&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;Each topic gets its own consumers and throughput limits, so a promo blast can't starve your OTPs. (RabbitMQ is the exception, with native priority queues.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Dead letter queues (DLQs)
&lt;/h3&gt;

&lt;p&gt;An e-commerce site sends order confirmations. Some email addresses are invalid and fail every time. Without a DLQ, those messages are retried forever or block the line. With a DLQ, failures move aside where you can inspect them and fix the cause.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"RedrivePolicy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deadLetterTargetArn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:sqs:us-east-1:123456789012:notif-dlq"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"maxReceiveCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's an SQS redrive policy: after 5 failed receives, the message goes to the DLQ.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five contenders, side by side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;RabbitMQ&lt;/th&gt;
&lt;th&gt;Kafka&lt;/th&gt;
&lt;th&gt;AWS SQS&lt;/th&gt;
&lt;th&gt;Google Pub/Sub&lt;/th&gt;
&lt;th&gt;AWS Kinesis&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Broker with exchanges and queues (AMQP)&lt;/td&gt;
&lt;td&gt;Distributed log, consumer groups&lt;/td&gt;
&lt;td&gt;Queue (pull)&lt;/td&gt;
&lt;td&gt;Topics and subscriptions (push or pull)&lt;/td&gt;
&lt;td&gt;Streams split into shards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ordering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;FIFO per queue&lt;/td&gt;
&lt;td&gt;Per partition&lt;/td&gt;
&lt;td&gt;FIFO queues, per message group&lt;/td&gt;
&lt;td&gt;Per ordering key (opt-in)&lt;/td&gt;
&lt;td&gt;Per shard / partition key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Throughput&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate to high&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High (shard-bound)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Retention / replay&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Until acked (Streams plugin adds replay)&lt;/td&gt;
&lt;td&gt;Configurable, replayable&lt;/td&gt;
&lt;td&gt;Up to 14 days, no replay&lt;/td&gt;
&lt;td&gt;Configurable, can seek back&lt;/td&gt;
&lt;td&gt;24h up to 365 days, replayable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Native priority&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No (use separate topics)&lt;/td&gt;
&lt;td&gt;No (use separate queues)&lt;/td&gt;
&lt;td&gt;No (use separate topics)&lt;/td&gt;
&lt;td&gt;No (use separate streams)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dead letter queue&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dead-letter exchanges&lt;/td&gt;
&lt;td&gt;DIY (a DLQ topic)&lt;/td&gt;
&lt;td&gt;Native&lt;/td&gt;
&lt;td&gt;Native&lt;/td&gt;
&lt;td&gt;No native DLQ (handle in the consumer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ops burden&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate (self-host or managed)&lt;/td&gt;
&lt;td&gt;Heavy if self-hosted, managed options exist&lt;/td&gt;
&lt;td&gt;Fully managed&lt;/td&gt;
&lt;td&gt;Fully managed&lt;/td&gt;
&lt;td&gt;Fully managed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Infra cost if self-hosted&lt;/td&gt;
&lt;td&gt;Infra cost if self-hosted&lt;/td&gt;
&lt;td&gt;Pay per request&lt;/td&gt;
&lt;td&gt;Pay per volume&lt;/td&gt;
&lt;td&gt;Pay per shard / volume&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Access control&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;vhosts and permissions&lt;/td&gt;
&lt;td&gt;ACLs&lt;/td&gt;
&lt;td&gt;IAM&lt;/td&gt;
&lt;td&gt;IAM&lt;/td&gt;
&lt;td&gt;IAM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Limits like max message size change over time, so check each provider's docs before you design around them.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one should you pick?
&lt;/h2&gt;

&lt;p&gt;Here are three common situations.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 Startup with low-volume transactional notifications → RabbitMQ (or SQS)
&lt;/h3&gt;

&lt;p&gt;Easy to set up, simple to reason about, and flexible routing. It has native priority queues and dead-letter exchanges, so you get a lot of notification-friendly features without much ceremony. If you're all-in on AWS and want zero ops, SQS is a strong alternative.&lt;/p&gt;

&lt;h3&gt;
  
  
  📈 Mid-sized company, high volume, low latency → Kafka
&lt;/h3&gt;

&lt;p&gt;Distributed, high throughput, and great for fan-out: one event can feed email, push and analytics consumers at once. Replication and replay are strong, and you can reprocess history when something goes wrong. The trade-off is operational complexity, so consider a managed offering.&lt;/p&gt;

&lt;h3&gt;
  
  
  🏢 Enterprise on AWS with many microservices → Kinesis (plus SNS/SQS where it fits)
&lt;/h3&gt;

&lt;p&gt;Fully managed, integrates natively with Lambda and the rest of AWS, and handles large volumes. Kinesis is a streaming service rather than a classic queue, so many teams pair it with SQS or SNS for simple fan-out and retry patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  At-least-once delivery means you need idempotency
&lt;/h2&gt;

&lt;p&gt;Almost every queue above delivers messages &lt;strong&gt;at least once&lt;/strong&gt;. Retries and rebalances can deliver the same message twice, and a user getting the same "payment received" push twice is a bug.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;already_processed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;      &lt;span class="c1"&gt;# e.g. Redis SETNX or DB unique key
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="nf"&gt;send_notification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;mark_processed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whichever queue you pick, build this in from day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Latency vs throughput: you can't max both
&lt;/h2&gt;

&lt;p&gt;Optimizing for one tends to cost you the other.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Low latency&lt;/strong&gt; needs fast ingest and delivery, which uses more CPU, memory and network per message.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High throughput&lt;/strong&gt; relies on batching and parallelism, which can add a little delay per message.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RabbitMQ leans toward low-latency, real-time delivery. Kafka leans toward high-throughput streaming, but it's tunable (settings like batch size and linger time let you trade one for the other). Even then, hardware and architecture set the limits.&lt;/p&gt;

&lt;p&gt;A practical rule: use low-latency settings for your critical queue (OTPs, alerts), and throughput-optimized settings for the low-priority bulk queue.&lt;/p&gt;

&lt;h2&gt;
  
  
  A checklist for deciding
&lt;/h2&gt;

&lt;p&gt;Run through these before you commit.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Define your numbers.&lt;/strong&gt; Message volume, latency target, reliability needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pick your trade-off.&lt;/strong&gt; Latency or throughput first?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan for growth.&lt;/strong&gt; Can it scale horizontally as your user base grows?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check ecosystem fit.&lt;/strong&gt; Your languages, frameworks and existing cloud provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Count the operational cost.&lt;/strong&gt; Setup complexity, monitoring, and what your team already knows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check security.&lt;/strong&gt; Durability, access control and encryption in transit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Budget it.&lt;/strong&gt; Infrastructure, managed service fees and maintenance time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prototype and load-test.&lt;/strong&gt; Don't trust benchmarks, including the ones in this post. Test with your own traffic.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Running multi-cloud or hybrid?
&lt;/h2&gt;

&lt;p&gt;A few things to watch for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multiple queue technologies.&lt;/strong&gt; Different components may use different brokers. Make sure your team can operate all of them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard protocols.&lt;/strong&gt; Prefer widely supported protocols like AMQP or MQTT where you can, and keep message formats consistent to avoid fragmentation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complexity vs flexibility.&lt;/strong&gt; Cross-environment connectivity adds moving parts. Make sure the flexibility is worth it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;There's no single best message queue, only the best fit for your volume, latency needs, team and cloud. Balance performance, reliability, ease of use and ecosystem, and revisit the decision as your notification system grows.&lt;/p&gt;

&lt;p&gt;And if you'd rather not build and operate this whole layer yourself (queues, priorities, retries, fallbacks), that's what we built &lt;a href="https://www.suprsend.com" rel="noopener noreferrer"&gt;SuprSend&lt;/a&gt; for. Full disclosure: we work on it, so take that into account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your turn:&lt;/strong&gt; which queue are you running notifications on today, and would you pick it again? Tell us in the comments. Horror stories welcome.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>scalability</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Introducing SuprSend Agent</title>
      <dc:creator>Nikita Navral</dc:creator>
      <pubDate>Thu, 15 Oct 2026 07:54:36 +0000</pubDate>
      <link>https://dev.to/suprsend/introducing-suprsend-agent-55p6</link>
      <guid>https://dev.to/suprsend/introducing-suprsend-agent-55p6</guid>
      <description>&lt;p&gt;Quick intro: we're the team behind &lt;a href="https://www.suprsend.com" rel="noopener noreferrer"&gt;SuprSend&lt;/a&gt;, a notification infrastructure platform. Today we're launching &lt;strong&gt;SuprSend Agent&lt;/strong&gt;, and we wanted to share what we built, how it's wired, and the guardrails we put around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 30-second version
&lt;/h2&gt;

&lt;p&gt;SuprSend Agent is an AI agent that lives &lt;strong&gt;inside the SuprSend dashboard&lt;/strong&gt;. You describe what you need in plain English, and it builds, configures and debugs your notification setup for you.&lt;/p&gt;

&lt;p&gt;It's connected to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the full SuprSend API surface&lt;/li&gt;
&lt;li&gt;the product documentation&lt;/li&gt;
&lt;li&gt;agent skills&lt;/li&gt;
&lt;li&gt;domain knowledge about how notifications actually work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So it doesn't just fire off API calls. It understands your use case, picks the right tools, applies the correct configuration, and tests the result.&lt;/p&gt;

&lt;p&gt;Try it: &lt;strong&gt;&lt;a href="https://auth.suprsend.com/?client_id=client_01HQTQ7EHH9GZTE1RGXEPN5RX2&amp;amp;redirect_uri=https%3A%2F%2Fapp.suprsend.com%2Fen%2Fcallback&amp;amp;authorization_session_id=01M4Z7KV9RD4ZWE09P14Q8H9Q2" rel="noopener noreferrer"&gt;SuprSend Agent&lt;/a&gt;&lt;/strong&gt; | Docs: &lt;strong&gt;&lt;a href="https://docs.suprsend.com/reference/agent?_gl=1*15vu7gt*_gcl_au*MjAzODM1MDA1MS4xNzkwMzIxNjUw*_ga*MTQ5OTQ3MjI2Ny4xNzkwMzIxNjUw*_ga_PPDYBESP2L*czE3OTIwNDk1NzIkbzEzJGcxJHQxNzkyMDQ5NTc5JGo1MyRsMCRoMTI2OTEwNDgw" rel="noopener noreferrer"&gt;read the docs&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we built it
&lt;/h2&gt;

&lt;p&gt;Notifications are deceptively deep. One message passes through several layers of logic: who gets it, on which channel, at what time, with what content, and what happens if the user does (or doesn't) act. Every layer has to be configured, tested and iterated.&lt;/p&gt;

&lt;p&gt;That depth is what lets a platform handle real-world use cases. It's also why it takes days to build a mental model before you configure anything.&lt;/p&gt;

&lt;p&gt;The agent shifts where that effort goes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;New users&lt;/strong&gt; skip the upfront learning curve. Ask the agent how things work, and let it set up your first workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Existing users&lt;/strong&gt; skip the click-through. No more hopping between screens to change a vendor, check an object or tweak a template.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What you can do with it
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Ask anything (without opening another tab)
&lt;/h3&gt;

&lt;p&gt;Data modeling, how a feature works, what an error means, best practices, how to approach an integration. It answers from the docs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"How do preferences cascade from defaults to tenants to end users?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Manage your assets from a chat
&lt;/h3&gt;

&lt;p&gt;The agent can create, retrieve, update and commit across tenants, objects, preferences, vendors, translations and schemas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Update the SMS vendor for tenant cypher and show me the current preference categories."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Design and test a notification from one prompt
&lt;/h3&gt;

&lt;p&gt;This is the one we're most excited about. Normally you decide everything yourself: flow structure, timing, branching, channels, and how the content should read on each one.&lt;/p&gt;

&lt;p&gt;Now a prompt like this is enough:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Set up a trial expiry reminder for new users."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Map out the workflow nodes&lt;/li&gt;
&lt;li&gt;Set the time delays&lt;/li&gt;
&lt;li&gt;Add the branching logic&lt;/li&gt;
&lt;li&gt;Pick the right channels&lt;/li&gt;
&lt;li&gt;Design and personalize the templates with variables&lt;/li&gt;
&lt;li&gt;Test the result across every channel&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You describe the outcome. It handles the build.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Ask your analytics anything
&lt;/h3&gt;

&lt;p&gt;A fixed dashboard only answers the questions it was built for. The agent reads your notification data through a &lt;strong&gt;semantic layer over the data lake&lt;/strong&gt;, so you can ask things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which notifications performed worst in the last 30 days?&lt;/li&gt;
&lt;li&gt;What's the best performing template this week?&lt;/li&gt;
&lt;li&gt;How do channels compare across segments and tenants?&lt;/li&gt;
&lt;li&gt;How many workflows are active?&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Show me delivery and open rates for the weekly-digest workflow, split by tenant, for the last 30 days."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It returns the answer, can visualize it as a chart, and can post it straight to Slack.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Debug "why didn't they get it?"
&lt;/h3&gt;

&lt;p&gt;We all know this one. A notification doesn't arrive, and the cause could be a channel issue, a preference opt-out, a tenant override or a vendor failure. Finding it means digging through logs and screens.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"User &lt;a href="mailto:john@cypher.com"&gt;john@cypher.com&lt;/a&gt; says he's not getting emails. What's wrong?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent traces the delivery, finds what stopped it, explains the cause and suggests a fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Cool, but is it safe on a live workspace?"
&lt;/h2&gt;

&lt;p&gt;Fair question, and honestly the one we spent the most time on. The agent acts on real organizational data, so safety is built into every step:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Guardrail&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Workspace-scoped access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Every session is limited to one workspace. A conversation in one can't read or change data in another.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Service token auth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each session uses a workspace-scoped JWT that expires and auto-refreshes, so access is short-lived by default.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Permission before changes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The agent asks for confirmation before any edit. Updates read the resource's current state first, so nothing is silently overwritten.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;No destructive deletes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Deletes aren't exposed to the agent at all. Only low-risk, reversible operations (like removing a user from a list) are allowed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Validated, not guessed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;It runs on validated SuprSend schemas and product knowledge, so it uses correct parameters instead of guessing.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Who is it for?
&lt;/h2&gt;

&lt;p&gt;Developers, product managers, marketing, customer success and ops teams. Basically anyone who manages notifications but doesn't want to write integration code for every change. Work that used to wait on engineering can now happen in a conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bigger shift
&lt;/h2&gt;

&lt;p&gt;This launch is part of a larger direction: SuprSend is becoming &lt;strong&gt;AI-first notification infrastructure&lt;/strong&gt;, where you operate the platform by describing what you need instead of learning every knob and switch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it and tell us what you think
&lt;/h2&gt;

&lt;p&gt;Start with a first prompt in the dashboard: &lt;strong&gt;&lt;a href="https://auth.suprsend.com/?client_id=client_01HQTQ7EHH9GZTE1RGXEPN5RX2&amp;amp;redirect_uri=https%3A%2F%2Fapp.suprsend.com%2Fen%2Fcallback&amp;amp;authorization_session_id=01M4Z7PMJ3RCPXM2QMZVXSYYFF" rel="noopener noreferrer"&gt;Try SuprSend Agent&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We'd love to hear from you in the comments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What's the first thing you'd ask the agent to build?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What guardrails would you want on an AI agent that touches production config?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What's the most painful notification bug you've ever had to debug?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We read every reply. 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>agentskills</category>
    </item>
    <item>
      <title>A complete guide on Notification Service for Modern Applications in 2026</title>
      <dc:creator>Nikita Navral</dc:creator>
      <pubDate>Wed, 14 Oct 2026 10:53:02 +0000</pubDate>
      <link>https://dev.to/suprsend/a-complete-guide-on-notification-service-for-modern-applications-in-2026-128c</link>
      <guid>https://dev.to/suprsend/a-complete-guide-on-notification-service-for-modern-applications-in-2026-128c</guid>
      <description>&lt;p&gt;Most notification services start as a single function:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&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;email_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works for a while. Then product asks for push, then SMS, then an in-app inbox, then "can users pick what they get?" Before long, this one function has become a distributed system.&lt;/p&gt;

&lt;p&gt;This post breaks down what a production notification service contains, split into the &lt;strong&gt;functional&lt;/strong&gt; parts users and PMs see, and the &lt;strong&gt;non-functional&lt;/strong&gt; parts that keep it alive at 3 a.m. At the end, there's a framework for deciding whether to build or buy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The big picture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your app --&amp;gt; Notification API --&amp;gt; Preference check --&amp;gt; Template render
                                        |
                              Priority queues (critical / high / low)
                                        |
                              Channel workers (email, SMS, push, inbox...)
                                        |
                              Vendor adapters --&amp;gt; Webhooks --&amp;gt; Analytics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each box hides real engineering work. Let's go through them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: Functional components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Delivery channels and vendor integrations
&lt;/h3&gt;

&lt;p&gt;Users live on different channels: email, SMS, push, in-app inbox, WhatsApp, Slack or Teams, even automated calls. To maximize engagement you'll want several of them.&lt;/p&gt;

&lt;p&gt;Every channel means picking a vendor, learning its API, testing quality of service, monitoring it, and planning a fallback. A common way to keep this manageable is an adapter layer:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChannelAdapter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DeliveryResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SendgridAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChannelAdapter&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TwilioAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChannelAdapter&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FcmAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChannelAdapter&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your core logic talks to one interface, and vendor quirks stay at the edges.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Templating engine
&lt;/h3&gt;

&lt;p&gt;Templates quietly become the biggest ownership burden. They need constant changes for copy, personalization, branding, dynamic variables, conditional logic, multi-lingual support, and correct rendering across devices.&lt;/p&gt;

&lt;p&gt;Each channel also has different strengths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Email:&lt;/strong&gt; long, detailed content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SMS:&lt;/strong&gt; short and attention-grabbing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push:&lt;/strong&gt; rich media and action buttons&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If every copy change needs a deploy, your engineers become a bottleneck. The fix is a visual editor so PMs and marketers can build and test without a pull request.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. User preferences
&lt;/h3&gt;

&lt;p&gt;Marketing emails get a simple unsubscribe link. Product notifications are trickier, because users want some of them (security alerts) and not others (weekly tips).&lt;/p&gt;

&lt;p&gt;A decent preference system lets users control:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type:&lt;/strong&gt; which categories they get&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Channel:&lt;/strong&gt; where they get them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frequency:&lt;/strong&gt; instant, hourly, daily or weekly digest&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timing:&lt;/strong&gt; quiet hours
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;should_send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;prefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_preferences&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prefs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled_categories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;in_quiet_hours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prefs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_critical&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;reschedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prefs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quiet_hours_end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without this, users do the only thing they can: block everything.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Batching and digests
&lt;/h3&gt;

&lt;p&gt;Say your product has comments. If 20 people reply to a thread, you don't want 20 notifications. You want one: "20 new comments."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Batching:&lt;/strong&gt; define a window, collect events inside it, then send one combined message.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Digests:&lt;/strong&gt; send a summary at a cadence the user chooses, such as hourly, daily or weekly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depending on the notification type, you may need both.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Multi-tenancy
&lt;/h3&gt;

&lt;p&gt;If your product serves other businesses and sends notifications to their users, you need tenant-level isolation and customization: their branding, their sending domain, their channels, their preference rules.&lt;/p&gt;

&lt;p&gt;Example: a SaaS tool sending invoices on behalf of customers. The end user doesn't know your brand, so the email must carry your customer's logo, content and sender identity, all running on shared infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Analytics
&lt;/h3&gt;

&lt;p&gt;PMs need delivery, open and click data to improve notifications. But every channel and vendor reports differently, and some metrics don't exist (you can't track opens on SMS).&lt;/p&gt;

&lt;p&gt;That means you need a normalized event model, so cross-channel analysis is possible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"delivered"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"channel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"notification_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"u_456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-10-14T10:32:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Map vendor webhooks into this shape and you can compare channels apples to apples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: Non-functional components
&lt;/h2&gt;

&lt;p&gt;This is the stuff nobody sees until it breaks.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Scalability and load balancing
&lt;/h3&gt;

&lt;p&gt;Notification traffic spikes unexpectedly: a flash sale, a viral feature, an incident. Design for bursts, and balance load across servers and regions.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Fault tolerance and retries
&lt;/h3&gt;

&lt;p&gt;Downtime isn't acceptable for OTPs or compliance messages. You need redundancy, state management, fallback vendors, and rate-limit-aware throttling per channel.&lt;/p&gt;

&lt;p&gt;One subtle point: &lt;strong&gt;not every failure deserves a retry.&lt;/strong&gt; An expired push token is dead, and retrying it just wastes resources.&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="n"&gt;RETRYABLE&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;timeout&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;rate_limited&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;vendor_5xx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;PERMANENT&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;invalid_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;unsubscribed&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;bounced&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;RETRYABLE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;retry_with_backoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;PERMANENT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;mark_channel_inactive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Understanding why something failed matters as much as retrying it.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. High deliverability
&lt;/h3&gt;

&lt;p&gt;Reaching the user involves several things at once: multiple channels, reliable vendors, cleaning inactive contacts, and managing bounces.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Low latency
&lt;/h3&gt;

&lt;p&gt;People expect notifications fast. Cut network round trips, optimize database queries, and shorten delivery paths. It's ongoing work, because performance degrades as you scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Observability
&lt;/h3&gt;

&lt;p&gt;You need detailed logging, error tracking and performance monitoring so you can diagnose failures quickly and answer compliance questions. If you can't answer "what happened to this user's notification?", debugging becomes guesswork.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Message queue prioritization
&lt;/h3&gt;

&lt;p&gt;This one saves a lot of pain. An OTP and a weekly newsletter shouldn't share a queue. If bulk sends clog the pipeline, login codes get delayed and drop-off rises.&lt;/p&gt;

&lt;p&gt;Use separate queues with their own throughput limits:&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="n"&gt;QUEUES&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;critical&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;workers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rate&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;unlimited&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;   &lt;span class="c1"&gt;# OTP, security
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&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;workers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rate&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;1000/s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;      &lt;span class="c1"&gt;# transactional
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&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;workers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rate&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;200/s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;       &lt;span class="c1"&gt;# promos, digests
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This protects critical messages without over-provisioning for everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  To build or not to build?
&lt;/h2&gt;

&lt;p&gt;Here's a quick framework.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build in-house when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your needs are simple.&lt;/strong&gt; Few notification types, low volume, rare changes, a single channel. Direct vendor integration or a lightweight internal service will do.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need heavy customization.&lt;/strong&gt; Your use case is unusual enough that third-party platforms can't support it (like a chatbot over SMS).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notifications are your product.&lt;/strong&gt; If you're something like WhatsApp, owning it makes sense.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Consider alternatives when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resources are limited.&lt;/strong&gt; Building and maintaining this takes real engineering capacity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time to market matters.&lt;/strong&gt; A third-party service can get you live far faster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need complex features.&lt;/strong&gt; Workflows, white-labeling, preferences, personalization, batching and cross-channel logic come ready-made on established platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want to focus on your core product.&lt;/strong&gt; Getting notifications right takes experimentation, channel expertise, scaling work and observability, which pulls attention from what makes your product special.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the layer we built &lt;a href="https://www.suprsend.com" rel="noopener noreferrer"&gt;SuprSend&lt;/a&gt; to handle, so teams can skip the plumbing. Full disclosure: we work on SuprSend, so weigh that accordingly. The checklist above holds whichever way you go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;A good notification service balances two sides. The functional side gives product teams control over templates, preferences and analytics. The non-functional side gives everyone reliability, speed and visibility. Skipping either one hurts.&lt;/p&gt;

&lt;p&gt;Whichever path you choose, the goal is the same: a smooth, meaningful experience that keeps users connected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Over to you:&lt;/strong&gt; did you build your notification system in-house or use a platform? What's the one component you wish you'd planned for earlier? Tell us in the comments.&lt;/p&gt;

</description>
      <category>api</category>
      <category>architecture</category>
      <category>backend</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Notifications Are Not Just an API Call: 11 Reasons They Quietly Eat Your Sprint</title>
      <dc:creator>Nikita Navral</dc:creator>
      <pubDate>Tue, 13 Oct 2026 13:24:26 +0000</pubDate>
      <link>https://dev.to/suprsend/notifications-are-not-just-an-api-call-11-reasons-they-quietly-eat-your-sprint-4i5m</link>
      <guid>https://dev.to/suprsend/notifications-are-not-just-an-api-call-11-reasons-they-quietly-eat-your-sprint-4i5m</guid>
      <description>&lt;p&gt;Every product team starts the same way: "We just need to send an email when someone signs up." One SDK, one template, done by Friday.&lt;/p&gt;

&lt;p&gt;Six months later you have four channels, three vendors, a pile of cron jobs, and a PM asking whether the payment reminder copy can be changed without a deploy.&lt;/p&gt;

&lt;p&gt;Notifications look trivial and behave like infrastructure. They're how your product talks to users: alerts, reminders, recommendations, launches, even user-to-user messages. Send too little and the experience breaks. Send too much and people unsubscribe. Here are the 11 places where it gets hard.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Trivial tasks that keep landing on engineers
&lt;/h2&gt;

&lt;p&gt;Notification logic is rarely hard. What's hard is iteration. Getting the content, trigger and timing right takes many tries, and PMs want to move fast. But when templates and triggers live in code, every tweak joins the sprint queue. Adding a new channel to an existing notification multiplies the work again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; let non-engineers edit content and logic without a deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Nobody knows what's actually live
&lt;/h2&gt;

&lt;p&gt;Before building a new notification, you need to know what already exists. Answering that means digging through the code or trusting a shared doc that went stale weeks ago. With several PMs involved, legacy notifications keep running because nobody wants to audit them. Cleanup becomes a once-or-twice-a-year project.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Testing is a coordination problem
&lt;/h2&gt;

&lt;p&gt;Testing notifications isn't technically complex, but it eats time. Test sends often go to one shared device or account that not everyone can access. Scheduled notifications usually need a developer to trigger them manually whenever QA or a PM wants to check them. That's a lot of context switching for something that should be self-serve.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Scaling exposes the cracks
&lt;/h2&gt;

&lt;p&gt;As volume grows, delivery reliability becomes your problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No priority separation.&lt;/strong&gt; If a promotional blast clogs the queue, your OTP sits behind it. Scaling everything up to compensate gets expensive. What you want is immediate delivery for transactional messages and staggered delivery for promotional ones:&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="c1"&gt;# Pseudocode: route by priority so promos never block transactional
&lt;/span&gt;&lt;span class="n"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;transactional&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;otp&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;payment&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;security&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;promotional&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;No fallback or retries.&lt;/strong&gt; If the provider API is down, queued messages are lost, and so is important communication. You need retries and a fallback path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No failure alerts.&lt;/strong&gt; Many teams only learn about failed deliveries when the business team or a customer complains. In the worst case, they never find out. Treat delivery failures like server downtime and alert on them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stale deliveries.&lt;/strong&gt; A delayed message that arrives two weeks later, like a "payment debited" notice, is worse than no message. Put an expiry on time-sensitive notifications:&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="c1"&gt;# Drop the message if it's too old to be useful
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;mark_expired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It sounds like a rare edge case, but it leaves a bad impression when it happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Analytics are scattered
&lt;/h2&gt;

&lt;p&gt;Each vendor gives you its own dashboard, which makes it hard to compare delivery and click rates across channels. User-level analytics are even rarer. How many messages did one user get this week? Did several fire at once? What does the overall experience feel like from their side? Without that view, users end up either under-engaged or bombarded.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Multi-channel is a tightrope
&lt;/h2&gt;

&lt;p&gt;Reaching users on every channel raises conversion, but it also raises unsubscribes. It's also costly to send the same message on three channels when the user saw it on the first.&lt;/p&gt;

&lt;p&gt;A smarter approach staggers delivery across channels based on past behavior and message type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Push -&amp;gt; wait 30 min -&amp;gt; not seen? -&amp;gt; Email -&amp;gt; wait 24h -&amp;gt; not seen? -&amp;gt; SMS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That saves money and avoids spamming people.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Sending to dead channels
&lt;/h2&gt;

&lt;p&gt;People change numbers and leave companies. Messages to inactive contacts cost money, and high email bounce rates damage your domain reputation, which can push future emails into spam. Most tools report a bounce only after you've sent. It's far better to filter out inactive channels in advance and keep your contact data clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Multi-lingual support
&lt;/h2&gt;

&lt;p&gt;Expanding into non-English markets means storing each user's language preference and maintaining a template per language, per channel. The engineering effort grows quickly, even though the logic stays the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Users want a say
&lt;/h2&gt;

&lt;p&gt;Letting users choose what they get notified about is good engagement strategy. Without granular preferences, many users take the only option available and unsubscribe from everything, which hurts engagement and sales. Quora is a good example: users can opt out of specific types of emails without leaving entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. One-size-fits-all frequency
&lt;/h2&gt;

&lt;p&gt;Engagement notifications usually run on a fixed schedule, because custom frequency per user isn't feasible by hand. The result is endless reminders for users who aren't interested, while engaged users could be getting more.&lt;/p&gt;

&lt;p&gt;A smarter system adapts to behavior: send more when users respond, back off when they go quiet, and try a different way to re-engage. That requires per-user data processing feeding back into the delivery pipeline, which most startups can't justify building. So they settle for light personalization and a frequency cap. It works, but it leaves engagement on the table.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Vendor lock-in and reliability
&lt;/h2&gt;

&lt;p&gt;No vendor guarantees 100% uptime. For time-sensitive messages like OTPs, you need a fallback vendor. But every vendor has its own API and integration rules, so each one costs real engineering time:&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;vendor&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vendor_a&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;vendor_b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vendor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;VendorError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;DeliveryFailed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks simple, until you maintain two or three vendors' payload formats, webhooks and error codes. Most teams stay with one vendor per channel until an outage forces the issue, or pick a multi-channel vendor that may not be the cheapest option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;None of these problems is impossible alone. Together, they turn "just send a notification" into a standing drain on your team's time.&lt;/p&gt;

&lt;p&gt;That's the problem we're building &lt;a href="https://www.suprsend.com" rel="noopener noreferrer"&gt;SuprSend&lt;/a&gt; to solve, so engineering teams can stop reinventing notification infrastructure and focus on their core product.&lt;/p&gt;

&lt;p&gt;Now I'm curious: &lt;strong&gt;how does your team handle notifications today?&lt;/strong&gt; Home-grown service, a single vendor, or something else? What's been the biggest pain point? Let us know in the comments.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Choose the Right Notification Infrastructure for Your App or Website</title>
      <dc:creator>Nik L.</dc:creator>
      <pubDate>Mon, 02 Sep 2024 13:29:40 +0000</pubDate>
      <link>https://dev.to/suprsend/how-to-choose-the-right-notification-infrastructure-for-your-app-or-website-24g9</link>
      <guid>https://dev.to/suprsend/how-to-choose-the-right-notification-infrastructure-for-your-app-or-website-24g9</guid>
      <description>&lt;h4&gt;
  
  
  Breaking Down the Essentials of Notification Infrastructure
&lt;/h4&gt;

&lt;p&gt;To build a resilient notification infrastructure, it’s important to be familiar with its key components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Message Queues and Brokers: The Notification Backbone&lt;/strong&gt;
The backbone of any robust &lt;a href="https://www.suprsend.com/" rel="noopener noreferrer"&gt;notification infrastructure&lt;/a&gt; is the message queue, which manages the flow of notifications. By processing messages asynchronously, message queues help avoid bottlenecks and ensure fault tolerance within your notification system. These queues temporarily store and then dispatch notifications as needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Message brokers like RabbitMQ and Apache Kafka play a crucial role in managing these processes within your notification infrastructure. RabbitMQ supports the AMQP protocol and provides features like message acknowledgments, making it a reliable choice for notification management. Kafka, known for its ability to handle large volumes of data with minimal delay, is an ideal solution for applications that need to process real-time streams.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Real-time Communication Protocols: For Instant Updates&lt;/strong&gt;
Real-time updates are a vital component of any notification infrastructure. Protocols such as WebSocket and HTTP/2 are essential for delivering notifications instantaneously. WebSocket allows for continuous, two-way communication between the client and server, which is particularly useful for live chat or real-time notification alerts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;HTTP/2, an improvement over HTTP/1.1, enhances your notification infrastructure by reducing latency through multiplexing and header compression. This ensures that notifications reach users quickly and efficiently.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Databases and Data Stores: Powering Personalization&lt;/strong&gt;
Personalization is a critical aspect of a successful notification infrastructure. Databases and data stores are the engines that power this personalization by storing user preferences and notification data. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Redis, a commonly used in-memory key-value store, is integral to many notification infrastructures due to its speed. It allows for rapid retrieval of user-specific data, enabling your system to deliver personalized notifications without delay.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scalable Server Clusters: Ready for Growth&lt;/strong&gt;
As your user base expands, so does the demand on your notification infrastructure. Scalable server clusters are essential for handling this growth by distributing the load across multiple servers. This distribution ensures that your &lt;a href="https://www.suprsend.com/" rel="noopener noreferrer"&gt;notification system&lt;/a&gt; remains responsive, even during peak usage times.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Load balancers play a vital role in this aspect of your notification infrastructure by evenly distributing traffic. Additionally, adopting a microservices architecture allows individual components of your notification system to scale independently, making it easier to manage and maintain as your app grows.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Technical Considerations for Building a Notification Infrastructure
&lt;/h4&gt;

&lt;p&gt;When designing your notification infrastructure, several critical aspects need to be considered to ensure it meets your needs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reliability and Redundancy: Ensuring Continuous Operation&lt;/strong&gt;&lt;br&gt;
A reliable notification infrastructure must minimize downtime and ensure continuous operation. Incorporating redundancy within your infrastructure means having backup systems that can take over if the primary ones fail. Failover mechanisms are also essential; they automatically switch to backups to keep your notifications flowing smoothly, regardless of any issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability: Handling Demand Fluctuations&lt;/strong&gt;&lt;br&gt;
Scalability is a key consideration for any notification infrastructure, particularly as your user base grows. Horizontal scaling, which involves adding more servers to handle increased load, is a critical feature of scalable notification systems. A microservices architecture further enhances scalability by allowing different parts of the notification infrastructure to scale independently, maintaining high performance under varying workloads.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customization and Personalization: Delivering Relevant Content&lt;/strong&gt;&lt;br&gt;
Customization and personalization are vital for an effective notification infrastructure. Notifications need to be tailored to user preferences and behaviors to maximize engagement. This requires a sophisticated approach to data handling, enabling your notification system to generate and deliver personalized content in real-time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security: Protecting User Data&lt;/strong&gt;&lt;br&gt;
Security is a cornerstone of any notification infrastructure. Ensuring that all data transmitted through your notification system is encrypted protects it from unauthorized access. Authentication mechanisms validate users and systems accessing the infrastructure, while data protection measures ensure compliance with privacy regulations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Analytics and Monitoring: Gaining Real-time Insights&lt;/strong&gt;&lt;br&gt;
Real-time analytics and monitoring are essential components of a modern notification infrastructure. Monitoring tools like Prometheus and Grafana provide insights into system performance, allowing you to detect and address issues promptly. These tools help you optimize your notification infrastructure over time, ensuring it continues to meet user needs efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Enhancing Your Notification Infrastructure with Specialized Services
&lt;/h4&gt;

&lt;p&gt;Specialized services like SuprSend can significantly enhance your notification infrastructure, making it more efficient and easier to manage:&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/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4n9vkfylsjq7akurrle.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/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4n9vkfylsjq7akurrle.png" alt="Notification architecture for scale"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Streamlined API Integration&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.suprsend.com/" rel="noopener noreferrer"&gt;SuprSend&lt;/a&gt; offers APIs that streamline the integration of notifications into your app or website. This simplifies the development process, ensuring that your notification infrastructure is both robust and easy to maintain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Advanced Routing and Filtering&lt;/strong&gt;&lt;br&gt;
Precision is key in a well-functioning notification infrastructure. &lt;a href="https://www.suprsend.com/" rel="noopener noreferrer"&gt;SuprSend’s&lt;/a&gt; advanced routing and filtering capabilities allow you to target notifications effectively, ensuring that the right messages reach the right users at the right time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Push and Pull Mechanisms&lt;/strong&gt;&lt;br&gt;
Flexibility is another critical component of a successful notification infrastructure. SuprSend supports both push notifications, which actively send updates to users, and pull mechanisms, where users request updates. This flexibility allows your notification system to adapt to different user needs and scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;You can see more of our engineering blogs here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.suprsend.com/post/how-redis-solved-our-challenges-with-dynamic-task-scheduling-and-concurrent-execution-developers-guide" rel="noopener noreferrer"&gt;How Redis Solved Our Challenges with Dynamic Task Scheduling and Concurrent Execution [Developer's Guide]&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discusses how Redis helped overcome challenges related to dynamic scheduling and concurrent task execution for syncing client data from a data warehouse to a store. The solution initially relied on goroutines, SQLite, and a Go service, but needed optimization for SaaS scalability.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.suprsend.com/post/comparing-notification-infrastructure-marketing-automation-tools-a-guide-to-choose-the-right-platform-for-your-product" rel="noopener noreferrer"&gt;Comparing Notification Infrastructure &amp;amp; Marketing Automation Tools: A Guide to Choose the Right Platform for Your Product&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provides insights on when to choose marketing automation tools like Braze or Customer.io and when to opt for notification infrastructure tools like SuprSend, based on product needs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.suprsend.com/post/dynamically-syncing-in-app-notification-center-theme-with-applications-current-theme-state" rel="noopener noreferrer"&gt;Dynamically Syncing In-app Notification Center Theme with Application's Current Theme State&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explains how to customize the app's inbox notification center to sync dynamically with the application's theme, enhancing user experience.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.suprsend.com/post/how-can-saas-tools-enhance-user-engagement-with-notifications-channel-routing-with-linkedins-example" rel="noopener noreferrer"&gt;How Can SaaS Tools Enhance User Engagement with Notifications Channel Routing (like LinkedIn)?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Demonstrates how SaaS tools can efficiently route notifications across different channels (e.g., email to SMS) based on availability, similar to LinkedIn's notification system, to enhance user engagement.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.suprsend.com/post/how-to-batch-notifications-for-your-social-media-collaborative-application" rel="noopener noreferrer"&gt;How to Batch Notifications for your Social Media/ Collaborative Application?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn how to batch multiple notifications to streamline communication, as seen in platforms like Instagram, LinkedIn, and Google Workspace.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>angular</category>
      <category>node</category>
    </item>
    <item>
      <title>Building and Optimizing a Notification System and Infrastructure</title>
      <dc:creator>Nik L.</dc:creator>
      <pubDate>Fri, 09 Aug 2024 16:02:58 +0000</pubDate>
      <link>https://dev.to/suprsend/building-and-optimizing-a-notification-system-and-infrastructure-4b6j</link>
      <guid>https://dev.to/suprsend/building-and-optimizing-a-notification-system-and-infrastructure-4b6j</guid>
      <description>&lt;p&gt;If you're reading this, you likely understand how important it is to send timely notifications to boost user interaction and grow your business. Whether you're notifying users about new messages, upcoming events, or status updates, having a reliable notification system is crucial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.suprsend.com/post/a-complete-guide-on-notification-service-for-modern-applications-in-2023" rel="noopener noreferrer"&gt;Creating a notification system&lt;/a&gt; in-house is challenging. It requires detailed planning, development, and ongoing maintenance. This article will break down the main parts of a notification system. By the end, you'll understand what’s needed to build one in-house, the challenges you might face, and what approach suits your company best.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Components of a Notification System
&lt;/h3&gt;

&lt;p&gt;A well-functioning notification system has several key parts that work together. Here’s a look at each part:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxxkgysxw8tmtwzhtv87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxxkgysxw8tmtwzhtv87.png" alt="Image description" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Delivery Channels &amp;amp; Vendor Integrations:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Delivery channels are how notifications reach users. To maximize engagement, you need to support multiple channels like email, SMS, in-app messages, push notifications, WhatsApp, Slack/Teams, and automated calls. Integrating with these channels can be complex, requiring vendor evaluation, API integration, service quality checks, and fallback strategies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxuh6gah04o9aizaxeail.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxuh6gah04o9aizaxeail.png" alt="Image description" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Templating Engine:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A notification system must create messages that fit each channel. Emails might include detailed information, while SMS should be brief. Push notifications can include multimedia and interactive elements. Managing templates involves handling copywriting, personalization, branding, dynamic content, multilingual support, and testing. A visual editor for non-engineers can help manage these templates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl40m6fexblms8deww14n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl40m6fexblms8deww14n.png" alt="Image description" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;User Preferences:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Proper targeting helps avoid notification fatigue and keeps users happy. Users should have control over what notifications they receive, how often, and through which channels. You need an easy-to-use interface for users to set their preferences, including types of notifications, channels, frequency, and timing. Allowing users to opt in or out of notifications helps prevent them from blocking all communications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0eafdrcc6vddozz0wwz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0eafdrcc6vddozz0wwz.png" alt="Image description" width="653" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Batching &amp;amp; Digest:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For some notifications, grouping several alerts into one message can be better than sending multiple separate alerts. For example, if there are several comments, it’s better to batch them and send them together. Summary digests can also be sent at user-preferred intervals (e.g., hourly, daily, weekly) to keep users updated without overwhelming them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Multi-Tenancy Support:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your system serves multiple customers, it needs to handle multi-tenancy. This means isolating data, customizing notifications for each customer, and supporting branding and preferences for each tenant. For example, a SaaS platform sending invoices needs to use the customer’s branding and preferences in notifications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58bkn3cp012xe3gb44xq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58bkn3cp012xe3gb44xq.png" alt="Image description" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Notification Analytics:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To improve notifications, you need to track their performance. Metrics like delivery rates, open rates, and user engagement are crucial. Different channels have different tracking methods, so standardizing how you measure user actions is important for effective analysis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftcexdspzog348l16mk8e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftcexdspzog348l16mk8e.png" alt="Image description" width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-Functional Aspects of Notification Systems
&lt;/h3&gt;

&lt;p&gt;Reliable and efficient notification services also depend on several non-functional components:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbfoanxiopsvewws05ec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbfoanxiopsvewws05ec.png" alt="Image description" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Scalability &amp;amp; Load Balancing:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notification services must handle varying levels of traffic. Ensuring scalability helps manage increased loads without performance issues. Load balancing across servers and regions keeps the service available and responsive.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Fault Tolerance, Redundancy, &amp;amp; Failure Retries:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To avoid downtime, the system must have redundancy and failover plans. This includes managing state, using fallback vendors, controlling request rates, and retrying failed notifications when appropriate.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;High Deliverability:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ensuring notifications are delivered successfully involves managing multiple channels, choosing reliable vendors, and handling bounce rates. Keeping channels clean and active improves deliverability.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Low Latency:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notifications should arrive quickly. Minimizing delay involves optimizing delivery routes, reducing network trips, and improving database queries. Continuous efforts are needed to maintain low latency as the system grows.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Observability &amp;amp; Diagnosis:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Monitoring and diagnosing issues are essential for smooth operation. Implementing detailed logging, error tracking, and performance monitoring helps identify and resolve problems quickly.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Message Queue Prioritization:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Not all notifications are equally important. High-priority notifications, like authentication alerts, should be sent immediately, while less urgent notifications, like newsletters, can be delayed. Prioritizing messages helps manage queue efficiency and control costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deciding to Build or Buy
&lt;/h3&gt;

&lt;p&gt;After understanding the components, you need to decide whether to build a notification system in-house or use an existing solution:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to Build:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity:&lt;/strong&gt; If your notification needs are minimal and infrequent, a simple integration or a basic central service might work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Needs:&lt;/strong&gt; For highly specific requirements that third-party solutions can't meet, building a custom system is better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Core Product:&lt;/strong&gt; If notifications are central to your product, having full control through an in-house system may be necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to Consider Alternatives:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resource Constraints:&lt;/strong&gt; Limited engineering resources might make it more efficient to use existing services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time to Market:&lt;/strong&gt; Using third-party solutions can speed up development and launch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex Features:&lt;/strong&gt; Established platforms often offer advanced features like workflows and cross-channel communication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Focus on Core Competencies:&lt;/strong&gt; Using external services allows you to focus on your main business rather than the complexities of notification management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SuprSend is designed to handle the complexities of notification orchestration for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm65o8s0cz13re4pld3dj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm65o8s0cz13re4pld3dj.png" alt="Image description" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As an engineering leader, consider your company's needs, resources, and long-term goals when deciding whether to build a notification system in-house or use a third-party solution. The goal is to create a seamless and engaging user experience.&lt;/p&gt;

&lt;p&gt;Check out more of our engineering insights here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.suprsend.com/post/how-redis-solved-our-challenges-with-dynamic-task-scheduling-and-concurrent-execution-developers-guide" rel="noopener noreferrer"&gt;How Redis Solved Our Challenges with Dynamic Task Scheduling and Concurrent Execution&lt;/a&gt;&lt;br&gt;
The problem statement was simple, or so we thought. In our previous setup, we used goroutines for scheduling database queries, allowing us to run the whole setup on minimal setup with SQLite and go service. Seems simple enough, but when we decided to also have this feature on our SaaS platform, at the onset, we didn’t realize we would also be walking into a new set of challenges of dynamic scheduling and concurrent task execution.&lt;br&gt;
We needed a way to sync data in a scheduled manner from the client's data warehouse to our data store.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.suprsend.com/post/comparing-notification-infrastructure-marketing-automation-tools-a-guide-to-choose-the-right-platform-for-your-product" rel="noopener noreferrer"&gt;Comparing Notification Infrastructure &amp;amp; Marketing Automation Tools&lt;/a&gt;&lt;br&gt;
We discuss around when should one prefer marketing automation tools ike Braze, Cutomer.io and when does it make sense to check notification infrastructure tools like SuprSend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.suprsend.com/post/dynamically-syncing-in-app-notification-center-theme-with-applications-current-theme-state" rel="noopener noreferrer"&gt;Dynamically Syncing In-App Notification Center Theme with Application's Current Theme State&lt;/a&gt;&lt;br&gt;
Showcasing some customization capabilities of our app inbox notification center&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.suprsend.com/post/how-can-saas-tools-enhance-user-engagement-with-notifications-channel-routing-with-linkedins-example" rel="noopener noreferrer"&gt;Enhancing User Engagement with Notifications Channel Routing&lt;/a&gt;&lt;br&gt;
Learn how to do efficient notifications channel routing, i.e, if email is unavailable send on SMS with smart logic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>eventdriven</category>
      <category>aws</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Send emails using Java (Javamail API or Simple Java Mail or SuprSend Java SDK)</title>
      <dc:creator>Nik L.</dc:creator>
      <pubDate>Fri, 02 Aug 2024 04:43:06 +0000</pubDate>
      <link>https://dev.to/suprsend/send-emails-using-java-javamail-api-or-simple-java-mail-or-suprsend-java-sdk-4pp3</link>
      <guid>https://dev.to/suprsend/send-emails-using-java-javamail-api-or-simple-java-mail-or-suprsend-java-sdk-4pp3</guid>
      <description>&lt;h2&gt;
  
  
  Method 1: Using JavaMail API for Email Notifications
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview:
&lt;/h3&gt;

&lt;p&gt;The JavaMail API is a robust, platform-independent, and protocol-independent framework designed to support Java client applications in performing comprehensive email and messaging functionalities. This API offers a generic interface with abstract classes representing various objects created in transactional email systems. It is especially useful for enterprise-level applications where reliability and extensive functionalities are paramount.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pros:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Well-Structured and Widely Adopted:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaMail API is renowned for its solid structure and widespread usage, particularly in enterprise environments.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Versatile Functionality:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It provides an extensive set of functionalities, including reading, composing, and sending emails.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Programmatic Integration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplifies the integration with other programs, making it easier to send confirmations and other messages programmatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Cons:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Extended Compilation Time:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers may face longer code compilation times due to the API's complexity.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Memory Consumption:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using the JavaMail API can lead to significant consumption of Java heap space.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementation Steps:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Installing JavaMail API
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Include JAR files (&lt;code&gt;mail.jar&lt;/code&gt; and &lt;code&gt;activation.jar&lt;/code&gt;) in the CLASSPATH.&lt;/li&gt;
&lt;li&gt;Configure an SMTP server (e.g., Pepipost) for email transmission.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Step 2: Setting Up the Mail Session
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create a session object with host information using &lt;code&gt;javax.mail.Session&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Properties&lt;/span&gt; &lt;span class="n"&gt;properties&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;Properties&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDefaultInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Alternatively:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Properties&lt;/span&gt; &lt;span class="n"&gt;properties&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;Properties&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Network authentication:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;javax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Authenticator&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;PasswordAuthentication&lt;/span&gt; &lt;span class="nf"&gt;getPasswordAuthentication&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PasswordAuthentication&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sender@gmail.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;);&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;h4&gt;
  
  
  Step 3: Composing the Email
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Use the &lt;code&gt;javax.mail.internet.MimeMessage&lt;/code&gt; subclass to set the sender, receiver, subject, and message body.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;MimeMessage&lt;/span&gt; &lt;span class="n"&gt;message&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;MimeMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&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;setFrom&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;InternetAddress&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&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;addRecipient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RecipientType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TO&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;InternetAddress&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&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;setSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This is the email subject"&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;setText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This is the email body"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Step 4: Adding Attachments
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;To include attachments, create a &lt;code&gt;Multipart&lt;/code&gt; object and add a &lt;code&gt;BodyPart&lt;/code&gt; for each attachment.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Multipart&lt;/span&gt; &lt;span class="n"&gt;multipart&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;MimeMultipart&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;BodyPart&lt;/span&gt; &lt;span class="n"&gt;messageBodyPart&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;MimeBodyPart&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;messageBodyPart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This is the email body"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;multipart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBodyPart&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageBodyPart&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;messageBodyPart&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;MimeBodyPart&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;DataSource&lt;/span&gt; &lt;span class="n"&gt;source&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;FileDataSource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"path/to/attachment.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;messageBodyPart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDataHandler&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;DataHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;messageBodyPart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFileName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attachment.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;multipart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBodyPart&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageBodyPart&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;setContent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;multipart&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Step 5: Sending the Email
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Use the &lt;code&gt;javax.mail.Transport&lt;/code&gt; class to send the email.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Transport&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Complete Code Example:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Properties&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.mail.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.mail.internet.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.activation.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SendMail&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"receiver@gmail.com"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"sender@gmail.com"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"smtp.gmail.com"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="nc"&gt;Properties&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProperties&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mail.smtp.host"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mail.smtp.port"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"465"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mail.smtp.ssl.enable"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mail.smtp.auth"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

      &lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;javax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Authenticator&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;PasswordAuthentication&lt;/span&gt; &lt;span class="nf"&gt;getPasswordAuthentication&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PasswordAuthentication&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sender@gmail.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;});&lt;/span&gt;

      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;MimeMessage&lt;/span&gt; &lt;span class="n"&gt;message&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;MimeMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&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;setFrom&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;InternetAddress&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&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;addRecipient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RecipientType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TO&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;InternetAddress&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&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;setSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Your email subject goes here"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;Multipart&lt;/span&gt; &lt;span class="n"&gt;multipart&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;MimeMultipart&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;BodyPart&lt;/span&gt; &lt;span class="n"&gt;messageBodyPart&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;MimeBodyPart&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;messageBodyPart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You have a new message"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;multipart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBodyPart&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageBodyPart&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;messageBodyPart&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;MimeBodyPart&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;DataSource&lt;/span&gt; &lt;span class="n"&gt;source&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;FileDataSource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"path/to/attachment.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;messageBodyPart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDataHandler&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;DataHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;messageBodyPart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFileName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attachment.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;multipart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBodyPart&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageBodyPart&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;setContent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;multipart&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;Transport&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&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="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MessagingException&lt;/span&gt; &lt;span class="n"&gt;mex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;mex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="o"&gt;}&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;h2&gt;
  
  
  Method 2: Using Simple Java Mail for Email Notifications
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Overview:
&lt;/h3&gt;

&lt;p&gt;Simple Java Mail is a user-friendly mailing library designed to simplify the process of sending SMTP emails in Java. It serves as a wrapper around the JavaMail API, streamlining the email sending process by reducing the complexity of the underlying API.&lt;/p&gt;
&lt;h4&gt;
  
  
  Pros:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Robust and Lightweight:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple Java Mail is robust while maintaining a lightweight footprint of 134kB.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RFC Compliance:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It complies with all relevant RFCs, ensuring compatibility with various email clients.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Authenticated SOCKS Proxy Support:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supports sending emails through an authenticated SOCKS proxy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Advanced Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Offers support for HTML content, images, and attachments, and allows sending emails to multiple recipients simultaneously.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Cons:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Limited Community Support:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The community support for Simple Java Mail is smaller compared to JavaMail API.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Implementation Steps:
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Step 1: Creating an Email Object with HTML and Attachments
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EmailBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startingBlank&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"From"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"from@example.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1st Receiver"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"rec1@example.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2nd Receiver"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"rec2@example.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enhanced Email with HTML and Attachments"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withHTMLText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Hello!&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;This is an enhanced email with HTML content.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withAttachment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"path/to/attachment.txt"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;buildEmail&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Step 2: Creating a Mailer Object using MailerBuilder
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Mailer&lt;/span&gt; &lt;span class="n"&gt;mailer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MailerBuilder&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withSMTPServer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"smtp.mailtrap.io"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2525&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withTransportStrategy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TransportStrategy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SMTPS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;buildMailer&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Step 3: Sending the Enhanced Email
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendMail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Complete Code Example:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.simplejavamail.api.email.Email&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.simplejavamail.email.EmailBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.simplejavamail.mailer.Mailer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.simplejavamail.mailer.MailerBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.simplejavamail.api.mailer.config.TransportStrategy&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SendEnhancedMail&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EmailBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startingBlank&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"From"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"from@example.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1st Receiver"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"case1@example.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2nd Receiver"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"case2@example.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enhanced Email with HTML and Attachments"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withHTMLText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Hello!&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;This is an enhanced email with HTML content.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withAttachment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"path/to/attachment.txt"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;buildEmail&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;Mailer&lt;/span&gt; &lt;span class="n"&gt;mailer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MailerBuilder&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withSMTPServer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"smtp.mailtrap.io"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2525&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withTransportStrategy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TransportStrategy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SMTPS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;buildMailer&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendMail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;);&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;h2&gt;
  
  
  Method 3: Using SuprSend for Multichannel Notifications with JAVA SDKs
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Overview:
&lt;/h3&gt;

&lt;p&gt;SuprSend offers a comprehensive third-party multichannel notification infrastructure that supports sending notifications across various channels like email, SMS, and push notifications through a unified API. By leveraging SuprSend, developers can manage complex notification workflows seamlessly.&lt;/p&gt;
&lt;h4&gt;
  
  
  Key Features &amp;amp; Benefits:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Extensive Integration Options:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integrates seamlessly with over 50 Communication Service Providers (CSPs) and supports multiple channels including Mixpanel, Segment, Twilio, Mailchimp, Slack, Teams, SNS, Vonage, Whatsapp, and more.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No Tech Dependency:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manages the entire notification lifecycle without heavy reliance on the engineering team. Integrate the &lt;a href="https://docs.suprsend.com/docs/java-sdk" rel="noopener noreferrer"&gt;JAVA SDK&lt;/a&gt; once, and the product team can handle the rest.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Intelligent Routing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implements intelligent cross-channel flows across providers without requiring technical dependencies.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;In-App SDK:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provides a developer-ready in-app layer for both web and mobile applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Granular Template Management:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Features an intuitive drag &amp;amp; drop editor for designing templates, offering superior control over content.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Powerful Workspace:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manages multiple projects with distinct integrations, workflows, and templates within each workspace.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Unified Analytics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provides a unified view of cross-channel analytics, enabling data-driven decision-making.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Smart Automation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automates synchronization, refreshing, and notification triggers to streamline operations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scalability:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automates scalability, ensuring a hassle-free experience.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Cons:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cost Considerations:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Managing multiple notification channels may incur costs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;Monthly Notification Limit&lt;/em&gt;:*

&lt;ul&gt;
&lt;li&gt;Though SuprSend provides 10k notifications free every month, which resets every month, you can also buy credits. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Limits:**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There may be restrictions on the number of notifications per month.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Implementation Steps:
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Step 1: Integrating the JAVA SDK
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the SuprSend JAVA SDK&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Add the SDK to your JAVA project via Maven or Gradle.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Step 2: Configuring the API Key and Workspace Secret
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set Up Configuration&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Obtain the API key and workspace secret from your SuprSend account and configure them in your JAVA project.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Step 3: Creating and Sending Notifications
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Send Notifications via JAVA SDK&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Use the SDK to send notifications, specifying the required channel (email, SMS, push, etc.) and the content.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.suprsend.Notification&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.suprsend.NotificationBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.suprsend.SuprSendClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SendNotification&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Initialize the SuprSendClient with API key and Workspace Secret&lt;/span&gt;
        &lt;span class="nc"&gt;SuprSendClient&lt;/span&gt; &lt;span class="n"&gt;client&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;SuprSendClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"your_api_key"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"your_workspace_secret"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Build the notification&lt;/span&gt;
        &lt;span class="nc"&gt;Notification&lt;/span&gt; &lt;span class="n"&gt;notification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NotificationBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startingBlank&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withRecipientEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"recipient@example.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withRecipientSMS&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"recipient_phone_number"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Notification Subject"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withHTMLBody&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Hello!&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;This is a multichannel notification.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Send the notification&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendNotification&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="o"&gt;);&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;h3&gt;
  
  
  Complete Code Example with JAVA SDK:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.suprsend.Notification&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.suprsend.NotificationBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.suprsend.SuprSendClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SuprSendExample&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Initialize the SuprSendClient with API key and Workspace Secret&lt;/span&gt;
        &lt;span class="nc"&gt;SuprSendClient&lt;/span&gt; &lt;span class="n"&gt;client&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;SuprSendClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"your_api_key"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"your_workspace_secret"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Create the notification&lt;/span&gt;
        &lt;span class="nc"&gt;Notification&lt;/span&gt; &lt;span class="n"&gt;notification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NotificationBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startingBlank&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withRecipientEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"receiver@example.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Subject of the Notification"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withHTMLBody&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Hello!&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;This is a notification from SuprSend.&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withAttachment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"path/to/attachment.txt"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Send the notification&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendNotification&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="o"&gt;);&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;These methods offer a comprehensive guide to sending email notifications using Java, with varying levels of complexity and integration capabilities to suit different needs and scenarios.&lt;/p&gt;



&lt;p&gt;You may want to check out other SuprSend SDKs too. Consider giving us a star after usage. It's free and open.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/suprsend" rel="noopener noreferrer"&gt;
        suprsend
      &lt;/a&gt; / &lt;a href="https://github.com/suprsend/suprsend-go" rel="noopener noreferrer"&gt;
        suprsend-go
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      SuprSend SDK for go
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;suprsend-go&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;SuprSend Go SDK&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;go get github.com/suprsend/suprsend-go&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Initialize the SuprSend SDK&lt;/p&gt;

&lt;div class="highlight highlight-source-go notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; (
    &lt;span class="pl-s"&gt;"log"&lt;/span&gt;

    suprsend &lt;span class="pl-s"&gt;"github.com/suprsend/suprsend-go"&lt;/span&gt;
)

&lt;span class="pl-k"&gt;func&lt;/span&gt; &lt;span class="pl-en"&gt;main&lt;/span&gt;() {
    &lt;span class="pl-s1"&gt;opts&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; []suprsend.&lt;span class="pl-smi"&gt;ClientOption&lt;/span&gt;{
        &lt;span class="pl-c"&gt;// suprsend.WithDebug(true),&lt;/span&gt;
    }
    &lt;span class="pl-s1"&gt;suprClient&lt;/span&gt;, &lt;span class="pl-s1"&gt;err&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; &lt;span class="pl-s1"&gt;suprsend&lt;/span&gt;.&lt;span class="pl-en"&gt;NewClient&lt;/span&gt;(&lt;span class="pl-s"&gt;"__api_key__"&lt;/span&gt;, &lt;span class="pl-s"&gt;"__api_secret__"&lt;/span&gt;, &lt;span class="pl-s1"&gt;opts&lt;/span&gt;&lt;span class="pl-c1"&gt;...&lt;/span&gt;)
    &lt;span class="pl-k"&gt;if&lt;/span&gt; &lt;span class="pl-s1"&gt;err&lt;/span&gt; &lt;span class="pl-c1"&gt;!=&lt;/span&gt; &lt;span class="pl-c1"&gt;nil&lt;/span&gt; {
        &lt;span class="pl-s1"&gt;log&lt;/span&gt;.&lt;span class="pl-en"&gt;Println&lt;/span&gt;(&lt;span class="pl-s1"&gt;err&lt;/span&gt;)
    }
}&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Trigger Workflow&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-source-go notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;package&lt;/span&gt; main
&lt;span class="pl-k"&gt;import&lt;/span&gt; (
    &lt;span class="pl-s"&gt;"log"&lt;/span&gt;

    suprsend &lt;span class="pl-s"&gt;"github.com/suprsend/suprsend-go"&lt;/span&gt;
)

&lt;span class="pl-k"&gt;func&lt;/span&gt; &lt;span class="pl-en"&gt;main&lt;/span&gt;() {
    &lt;span class="pl-c"&gt;// Instantiate Client&lt;/span&gt;
    &lt;span class="pl-s1"&gt;suprClient&lt;/span&gt;, &lt;span class="pl-s1"&gt;err&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; &lt;span class="pl-s1"&gt;suprsend&lt;/span&gt;.&lt;span class="pl-en"&gt;NewClient&lt;/span&gt;(&lt;span class="pl-s"&gt;"__api_key__"&lt;/span&gt;, &lt;span class="pl-s"&gt;"__api_secret__"&lt;/span&gt;)
    &lt;span class="pl-k"&gt;if&lt;/span&gt; &lt;span class="pl-s1"&gt;err&lt;/span&gt; &lt;span class="pl-c1"&gt;!=&lt;/span&gt; &lt;span class="pl-c1"&gt;nil&lt;/span&gt; {
        &lt;span class="pl-s1"&gt;log&lt;/span&gt;.&lt;span class="pl-en"&gt;Println&lt;/span&gt;(&lt;span class="pl-s1"&gt;err&lt;/span&gt;)
        &lt;span class="pl-k"&gt;return&lt;/span&gt;
    }
    &lt;span class="pl-c"&gt;// Create WorkflowTriggerRequest body&lt;/span&gt;
    &lt;span class="pl-s1"&gt;wfReqBody&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; &lt;span class="pl-k"&gt;map&lt;/span&gt;[&lt;span class="pl-smi"&gt;string&lt;/span&gt;]&lt;span class="pl-k"&gt;interface&lt;/span&gt;{}{
        &lt;span class="pl-s"&gt;"workflow"&lt;/span&gt;: &lt;span class="pl-s"&gt;"workflow-slug"&lt;/span&gt;,
        &lt;span class="pl-s"&gt;"recipients"&lt;/span&gt;: []&lt;span class="pl-k"&gt;map&lt;/span&gt;[&lt;span class="pl-smi"&gt;string&lt;/span&gt;]&lt;span class="pl-k"&gt;interface&lt;/span&gt;{}{
            {
                &lt;span class="pl-s"&gt;"distinct_id"&lt;/span&gt;: &lt;span class="pl-s"&gt;"0f988f74-6982-41c5-8752-facb6911fb08"&lt;/span&gt;,
                &lt;span class="pl-c"&gt;// if $channels is present, communication will be tried on mentioned channels only (for this request).&lt;/span&gt;
                &lt;span class="pl-c"&gt;// "$channels": []string{"email"},&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/suprsend/suprsend-go" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;







&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/suprsend" rel="noopener noreferrer"&gt;
        suprsend
      &lt;/a&gt; / &lt;a href="https://github.com/suprsend/suprsend-py-sdk" rel="noopener noreferrer"&gt;
        suprsend-py-sdk
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      SuprSend SDK for python3 
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;suprsend-py-sdk&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;This package can be included in a python3 project to easily integrate
with &lt;code&gt;SuprSend&lt;/code&gt; platform.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Installation&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;suprsend-py-sdk&lt;/code&gt; is available on PyPI. You can install using pip.&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pip install suprsend-py-sdk&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This SDK depends on a system package called &lt;code&gt;libmagic&lt;/code&gt;. You can install it as follows:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; On debian based systems&lt;/span&gt;
sudo apt install libmagic

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; If you are using macOS&lt;/span&gt;
brew install libmagic&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Usage&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Initialize the SuprSend SDK&lt;/p&gt;
&lt;div class="highlight highlight-source-python notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s1"&gt;suprsend&lt;/span&gt; &lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-v"&gt;Suprsend&lt;/span&gt;
&lt;span class="pl-c"&gt;# Initialize SDK&lt;/span&gt;
&lt;span class="pl-s1"&gt;supr_client&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-v"&gt;Suprsend&lt;/span&gt;(&lt;span class="pl-s"&gt;"workspace_key"&lt;/span&gt;, &lt;span class="pl-s"&gt;"workspace_secret"&lt;/span&gt;)&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Following example shows a sample request for triggering a workflow.
It triggers a pre-created workflow &lt;code&gt;purchase-made&lt;/code&gt; to a recipient with id: &lt;code&gt;distinct_id&lt;/code&gt;,
email: &lt;code&gt;user@example.com&lt;/code&gt; &amp;amp; androidpush(fcm-token): &lt;code&gt;__android_push_fcm_token__&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight highlight-source-python notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s1"&gt;suprsend&lt;/span&gt; &lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-v"&gt;WorkflowTriggerRequest&lt;/span&gt;
&lt;span class="pl-c"&gt;# Prepare Workflow body&lt;/span&gt;
&lt;span class="pl-s1"&gt;wf&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-v"&gt;WorkflowTriggerRequest&lt;/span&gt;(
  &lt;span class="pl-s1"&gt;body&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;{
    &lt;span class="pl-s"&gt;"workflow"&lt;/span&gt;: &lt;span class="pl-s"&gt;"purchase-made"&lt;/span&gt;
    &lt;span class="pl-s"&gt;"recipients"&lt;/span&gt;: [
        {
          &lt;span class="pl-s"&gt;"distinct_id"&lt;/span&gt;: &lt;span class="pl-s"&gt;"0f988f74-6982-41c5-8752-facb6911fb08"&lt;/span&gt;,
          &lt;span class="pl-c"&gt;# if $channels is present, communication will be tried on mentioned&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/suprsend/suprsend-py-sdk" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;






&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/suprsend" rel="noopener noreferrer"&gt;
        suprsend
      &lt;/a&gt; / &lt;a href="https://github.com/suprsend/suprsend-node-sdk" rel="noopener noreferrer"&gt;
        suprsend-node-sdk
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Official SuprSend SDK for Node.js
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;suprsend-node-sdk&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;This package can be included in a node project to easily integrate with SuprSend platform.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install @suprsend/node-sdk@latest&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Initialization&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; Suprsend &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-en"&gt;require&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;"@suprsend/node-sdk"&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;

&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;supr_client&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;Suprsend&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;"workspace_key"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s"&gt;"workspace_secret"&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&lt;a href="https://docs.suprsend.com/docs/node-trigger-workflow-from-api" rel="nofollow noopener noreferrer"&gt;Trigger workflow from API&lt;/a&gt;&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;It is a unified API to trigger workflow and doesn't require user creation before hand. If you are using our frontend SDK's to configure notifications and passing events and user properties from third-party data platforms like Segment, then &lt;a href="https://docs.suprsend.com/docs/node-send-event-data" rel="nofollow noopener noreferrer"&gt;event-based trigger&lt;/a&gt; would be a better choice.&lt;/p&gt;
&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; Suprsend&lt;span class="pl-kos"&gt;,&lt;/span&gt; WorkflowTriggerRequest &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-en"&gt;require&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;"@suprsend/node-sdk"&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;supr_client&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;Suprsend&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;"workspace_key"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s"&gt;"workspace_secret"&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;

&lt;span class="pl-c"&gt;// workflow payload&lt;/span&gt;
&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;body&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
  &lt;span class="pl-c1"&gt;workflow&lt;/span&gt;: &lt;span class="pl-s"&gt;"_workflow_slug_"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
  &lt;span class="pl-c1"&gt;actor&lt;/span&gt;: &lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-c1"&gt;distinct_id&lt;/span&gt;: &lt;span class="pl-s"&gt;"0fxxx8f74-xxxx-41c5-8752-xxxcb6911fb08"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-c1"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;"actor_1"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
  &lt;span class="pl-c1"&gt;recipients&lt;/span&gt;: &lt;span class="pl-kos"&gt;[&lt;/span&gt;
    &lt;span class="pl-kos"&gt;{&lt;/span&gt;
      &lt;span class="pl-c1"&gt;distinct_id&lt;/span&gt;: &lt;span class="pl-s"&gt;"0gxxx9f14-xxxx-23c5-1902-xxxcb6912ab09"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
      &lt;span class="pl-c1"&gt;$email&lt;/span&gt;: &lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-s"&gt;"abc@example.com"&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/suprsend/suprsend-node-sdk" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;






&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/suprsend" rel="noopener noreferrer"&gt;
        suprsend
      &lt;/a&gt; / &lt;a href="https://github.com/suprsend/suprsend-react-inbox" rel="noopener noreferrer"&gt;
        suprsend-react-inbox
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      SuprSend SDK for integrating inbox functionality in React applications
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;@suprsend/react-inbox&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Integrating SuprSend Inbox channel in React websites can be done in two ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SuprSendInbox&lt;/strong&gt; component which comes with UI and customizing props.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SuprSendProvider&lt;/strong&gt; headless component and hooks, incase you want to totally take control of UI. (example: Full page notifications).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailed documentation can be found here: &lt;a href="https://docs.suprsend.com/docs/inbox-react" rel="nofollow noopener noreferrer"&gt;https://docs.suprsend.com/docs/inbox-react&lt;/a&gt;
&lt;br&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;You can install SuprSend inbox SDK using npm/yarn&lt;/p&gt;
&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-s1"&gt;npm&lt;/span&gt; &lt;span class="pl-s1"&gt;install&lt;/span&gt; @&lt;span class="pl-s1"&gt;suprsend&lt;/span&gt;&lt;span class="pl-c1"&gt;/&lt;/span&gt;&lt;span class="pl-s1"&gt;react&lt;/span&gt;&lt;span class="pl-c1"&gt;-&lt;/span&gt;&lt;span class="pl-s1"&gt;inbox&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;SuprSendInbox Integration&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;After installing, Import the component in your code and use it as given below. Replace the variables with actual values.&lt;/p&gt;
&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-v"&gt;SuprSendInbox&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'@suprsend/react-inbox'&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s"&gt;'react-toastify/dist/ReactToastify.css'&lt;/span&gt; &lt;span class="pl-c"&gt;// needed for toast notifications, can be ignored if hideToast=true&lt;/span&gt;

&lt;span class="pl-c"&gt;// add to your react component;&lt;/span&gt;
&lt;span class="pl-c1"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;SuprSendInbox&lt;/span&gt;
  &lt;span class="pl-c1"&gt;workspaceKey&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;'&amp;lt;workspace_key&amp;gt;'&lt;/span&gt;
  &lt;span class="pl-c1"&gt;subscriberId&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;'&amp;lt;subscriber_id&amp;gt;'&lt;/span&gt;
  &lt;span class="pl-c1"&gt;distinctId&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;'&amp;lt;distinct_id&amp;gt;'&lt;/span&gt;
&lt;span class="pl-c1"&gt;/&lt;/span&gt;&lt;span class="pl-c1"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-s1"&gt;interface&lt;/span&gt; &lt;span class="pl-v"&gt;ISuprSendInbox&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
  workspaceKey: &lt;span class="pl-s1"&gt;string&lt;/span&gt;
  distinctId: &lt;span class="pl-s1"&gt;string&lt;/span&gt; &lt;span class="pl-c1"&gt;|&lt;/span&gt; &lt;span class="pl-c1"&gt;null&lt;/span&gt;
  subscriberId: &lt;span class="pl-s1"&gt;string&lt;/span&gt; &lt;span class="pl-c1"&gt;|&lt;/span&gt; &lt;span class="pl-c1"&gt;null&lt;/span&gt;
  &lt;span class="pl-s1"&gt;tenantId&lt;/span&gt;?: &lt;span class="pl-s1"&gt;string&lt;/span&gt;
  &lt;span class="pl-s1"&gt;stores&lt;/span&gt;?: &lt;span class="pl-v"&gt;IStore&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;
  &lt;span class="pl-s1"&gt;pageSize&lt;/span&gt;?: &lt;span class="pl-s1"&gt;number&lt;/span&gt;
  &lt;span class="pl-s1"&gt;pagination&lt;/span&gt;?: &lt;span class="pl-s1"&gt;boolean&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/suprsend/suprsend-react-inbox" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>java</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>App Inbox Notification Feed in Next.js</title>
      <dc:creator>Nik L.</dc:creator>
      <pubDate>Fri, 02 Aug 2024 04:28:01 +0000</pubDate>
      <link>https://dev.to/suprsend/app-inbox-notification-feed-in-nextjs-18kb</link>
      <guid>https://dev.to/suprsend/app-inbox-notification-feed-in-nextjs-18kb</guid>
      <description>&lt;p&gt;A &lt;a href="https://www.suprsend.com/post/implementing-app-inbox-in-next-js-application-as-a-developer" rel="noopener noreferrer"&gt;notification center in a Next.js&lt;/a&gt; app acts as a central hub where users can access all their notifications anytime. This feature enhances user engagement and ensures no important updates are missed. In this tutorial, we'll guide you through creating a comprehensive notification center in a Next.js application, including backend setup and frontend development for a user-friendly notification feed.&lt;/p&gt;

&lt;p&gt;By following this guide, you'll develop a fully functional notification system in your Next.js app with real-time updates. This implementation will enhance your app's user experience and provide a scalable solution for managing notifications.&lt;/p&gt;

&lt;p&gt;Key topics include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up a Next.js project for your notification center.&lt;/li&gt;
&lt;li&gt;Building a backend with Node.js and Express to handle notifications.&lt;/li&gt;
&lt;li&gt;Creating and integrating a frontend notification widget with the backend.&lt;/li&gt;
&lt;li&gt;Implementing real-time updates for an up-to-date notification feed.&lt;/li&gt;
&lt;li&gt;Styling the notification UI for responsiveness and user-friendliness.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No matter if you call it an in-app inbox, notification widget, or alert center, the principles and steps remain consistent. Let's get started on building your Next.js notification center!&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Knowledge of Next.js&lt;/li&gt;
&lt;li&gt;SuprSend account with a secret key and token&lt;/li&gt;
&lt;li&gt;A Next.js application&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Where will we build our app inbox in Next.js?
&lt;/h3&gt;

&lt;p&gt;For this tutorial, we've created a demo Next.js project called &lt;code&gt;b2b2c-freight_company&lt;/code&gt; available on GitHub. The application is also deployed on Vercel, allowing you to see the real-time notification feed here: &lt;a href="https://b2b2c-freight-company.vercel.app" rel="noopener noreferrer"&gt;Freight B2B2C App&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building a real-time notification center in Next.js
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Creating an account on SuprSend
&lt;/h4&gt;

&lt;p&gt;Start by signing up on SuprSend. After onboarding, navigate to Developers → API Keys in the side panel to find your Workspace Key and Workspace Secret.&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/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7oy96wgzqtzqatknww2h.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/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7oy96wgzqtzqatknww2h.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Finding the right place for your app inbox
&lt;/h4&gt;

&lt;p&gt;Typically, the app inbox is located in the header with other menu options. Alternatively, it can be an option in the side panel for a full-page notification center, similar to LinkedIn. In our case, we'll implement the notification center in the navigation header. Relevant code is available &lt;a href="https://github.com/b2b2c-freight_company/src/app/page.tsx" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Installing and integrating SuprSendInbox in Next.js
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the SuprSend App Inbox Package&lt;/strong&gt;:
```bash
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;npm install @suprsend/react-inbox&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
2. **Import Necessary Packages**:
   ```javascript


   import 'react-toastify/dist/ReactToastify.css';


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Disable Server-Side Rendering for SuprSend&lt;/strong&gt;:
```javascript
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;import dynamic from 'next/dynamic';&lt;/p&gt;

&lt;p&gt;const SuprSendInbox = dynamic(() =&amp;gt; import('@suprsend/react-inbox'), { ssr: false });&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
4. **Place the SuprSendInbox Component**:
   ```javascript


   const workspaceKey = process.env.NEXT_PUBLIC_SUPRSEND_WORKSPACE_KEY || '';
   const subscriberId = process.env.NEXT_PUBLIC_SUPRSEND_SUBSCRIBER_ID || '';
   const distinctId = process.env.NEXT_PUBLIC_SUPRSEND_DISTINCT_ID || '';

   export default function HomePage() {
     return (
       &amp;lt;div className="flex min-h-screen bg-gray-900 text-white"&amp;gt;
         &amp;lt;div className="fixed top-0 right-0 m-4 z-50"&amp;gt;
           &amp;lt;SuprSendInbox
             workspaceKey={workspaceKey}
             subscriberId={subscriberId}
             distinctId={distinctId}
             themeType="dark"
           /&amp;gt;
         &amp;lt;/div&amp;gt;
       &amp;lt;/div&amp;gt;
     );
   }


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Styling the App Inbox Component&lt;/strong&gt;:
If using Tailwind CSS, integrate the inbox into your navigation panel and customize it:
```javascript
&lt;/li&gt;
&lt;/ol&gt;


&lt;br&gt;
     
       workspaceKey={workspaceKey}&lt;br&gt;
       subscriberId={subscriberId}&lt;br&gt;
       distinctId={distinctId}&lt;br&gt;
       themeType="dark"&lt;br&gt;
     /&amp;gt;&lt;br&gt;
   




&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&lt;br&gt;
   Customize using props like &lt;code&gt;workspaceKey&lt;/code&gt;, &lt;code&gt;subscriberId&lt;/code&gt;, &lt;code&gt;distinctId&lt;/code&gt;, and &lt;code&gt;themeType&lt;/code&gt;. More details are in the &lt;a href="https://docs.suprsend.com/docs/react-customize-inbox" rel="noopener noreferrer"&gt;SuprSend documentation&lt;/a&gt;.
&lt;h4&gt;
  
  
  Step 4: Setting environment variables
&lt;/h4&gt;

&lt;p&gt;Ensure you set the following in your &lt;code&gt;.env&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;NEXT_PUBLIC_SUPRSEND_WORKSPACE_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_workspace_key
&lt;span class="nv"&gt;NEXT_PUBLIC_SUPRSEND_SUBSCRIBER_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_subscriber_id
&lt;span class="nv"&gt;NEXT_PUBLIC_SUPRSEND_DISTINCT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_distinct_id


&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;h4&amp;gt;
  &amp;lt;a &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"step-5-setting-triggers-for-notifications"&lt;/span&gt; &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"#step-5-setting-triggers-for-notifications"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &amp;lt;/a&amp;gt;
  Step 5: Setting triggers &lt;span class="k"&gt;for &lt;/span&gt;notifications
&amp;lt;/h4&amp;gt;

&amp;lt;p&amp;gt;With your app inbox &lt;span class="nb"&gt;set &lt;/span&gt;up and visible, configure triggers &lt;span class="k"&gt;for &lt;/span&gt;sending notifications using any backend SDK. We will use the Node SDK. Documentation &lt;span class="k"&gt;for &lt;/span&gt;sending and triggering events is available &amp;lt;a &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://suprsend.com"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;here&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;img &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8w4qa0sbhl3vuzt64ur.png"&lt;/span&gt; &lt;span class="nv"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Image description"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;
  &amp;lt;a &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"key-points"&lt;/span&gt; &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"#key-points"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &amp;lt;/a&amp;gt;
  Key Points
&amp;lt;/h3&amp;gt;

&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;Disable server-side rendering, as the app inbox operates only on the client side.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;For generating the subscriber key, perform HMAC authentication using any backend SDK.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;Integrating a notification center &lt;span class="k"&gt;in &lt;/span&gt;your Next.js app significantly boosts user engagement and ensures crucial messages are never missed. By following these steps, you can effectively implement the SuprSend app inbox, optimizing performance and functionality with dynamic import and client-side rendering. &amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;This approach provides extensive customization options, fitting seamlessly within your existing design. With this robust notification system, you can focus on building more features, knowing your &lt;span class="nb"&gt;users &lt;/span&gt;are always informed and engaged. Happy coding!&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

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

&lt;/div&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>react</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Batch Notifications Across Users in a Dedicated Time Window? w/ Example Github Application</title>
      <dc:creator>Nik L.</dc:creator>
      <pubDate>Thu, 04 Jul 2024 05:38:31 +0000</pubDate>
      <link>https://dev.to/suprsend/how-to-batch-notifications-across-users-in-a-dedicated-time-window-w-example-github-application-2p3k</link>
      <guid>https://dev.to/suprsend/how-to-batch-notifications-across-users-in-a-dedicated-time-window-w-example-github-application-2p3k</guid>
      <description>&lt;p&gt;&lt;a href="https://www.suprsend.com/post/how-to-batch-notifications-for-your-social-media-collaborative-application" rel="noopener noreferrer"&gt;Batching notifications&lt;/a&gt; is a feature widely adopted by major social media platforms and collaborative tools like LinkedIn, MS Teams, and Google Workspace products. This technique consolidates multiple alerts into a concise summary within a single notification, creating a clutter-free user experience and reducing interruptions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flkpau5scktu2rxnn33bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flkpau5scktu2rxnn33bg.png" alt="Image description" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;For hands-on implementation, please refer to the provided GitHub repository and deployed application links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/SuprSend-NotificationAPI/social-app-react-app-inbox" rel="noopener noreferrer"&gt;SuprSend Social App&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Deployed Application: &lt;a href="https://suprsend-notificationapi.github.io/social-app-react-app-inbox/" rel="noopener noreferrer"&gt;SuprSend Demo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Benefits of Batching Notifications
&lt;/h3&gt;

&lt;p&gt;Frequent alerts can lead to notification fatigue, causing users to disengage. By batching notifications, we can maintain user attention and promote sustained interaction with our platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Overview: How Batching Works
&lt;/h3&gt;

&lt;p&gt;Batching notifications requires sophisticated workflows and significant development resources. Here's a closer look at the technical aspects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Aggregation Engine&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Efficiently aggregates related notifications, such as likes, shares, and comments, based on metadata attributes.&lt;/li&gt;
&lt;li&gt;Example: Instagram separates notifications for story likes and comments, ensuring clarity.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Batching Window&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The batching window can be fixed (e.g., every 30 minutes) or dynamic (e.g., user-specific intervals).&lt;/li&gt;
&lt;li&gt;Example: LinkedIn batches email alerts for new messages every 30 minutes, while Google Docs batches comments based on user activity.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scheduling&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Determines the optimal time for delivering notifications, which could be immediately, at the end of a batching window, or at a strategic time.&lt;/li&gt;
&lt;li&gt;Example: SaaS companies often send a daily digest of activities the following morning.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Batched Message Presentation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Options range from simple counters to detailed summaries, balancing informativeness and engagement without overwhelming the user.&lt;/li&gt;
&lt;li&gt;Example: "Patrick and 3 others liked your photo" versus listing all activities.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cancelling Aggregation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adjusts the aggregation counter for counter-activities within the batching window.&lt;/li&gt;
&lt;li&gt;Example: If a user likes and then unlikes a post within the batching window, the counter is adjusted accordingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Practical Implementation Using SuprSend
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Pre-requisites:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Account on &lt;a href="https://www.suprsend.com/" rel="noopener noreferrer"&gt;SuprSend&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Integration of &lt;a href="https://docs.suprsend.com/docs" rel="noopener noreferrer"&gt;SuprSend SDK&lt;/a&gt; in your project&lt;/li&gt;
&lt;li&gt;Successful &lt;a href="https://docs.suprsend.com/reference/event-api" rel="noopener noreferrer"&gt;event calls made to SuprSend&lt;/a&gt; with necessary details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ekiq9lmhtoi1168ty2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ekiq9lmhtoi1168ty2g.png" alt="Image description" width="411" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Steps to Implement Batching:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identifying Triggers&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Identify recurring events suitable for batching.&lt;/li&gt;
&lt;li&gt;Example: Trigger a &lt;code&gt;Like_Event&lt;/code&gt; whenever someone likes a post in a React application using SuprSend's JavaScript SDK.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5iohs4abmgcpp4hdlcig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5iohs4abmgcpp4hdlcig.png" alt="Image description" width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Setting Up Batch Parameters&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Use SuprSend’s workflow builder to configure batching.&lt;/li&gt;
&lt;li&gt;Define batch window (fixed or dynamic), batch key (e.g., userName), and retain batch events (e.g., 15 objects).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0r5eqrdupg01fyw7815q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0r5eqrdupg01fyw7815q.png" alt="Image description" width="536" height="775"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the code I am using to send the event to SuprSend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flevvo3x11j8ya3qoh6lz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flevvo3x11j8ya3qoh6lz.png" alt="Image description" width="800" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fizxksactgmi2eb2o1n7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fizxksactgmi2eb2o1n7s.png" alt="Image description" width="800" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Creating Templates for Batched Events&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Use SuprSend’s template editor and Handlebar Helpers to format notifications based on the batched event count.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkaqsszorz5wawyp6hkxs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkaqsszorz5wawyp6hkxs.png" alt="Image description" width="537" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example Template that I used for this demo application using handlebars:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{#compare $batched_events_count '&amp;gt;' 1}} 
{{ $batched_events.[0].username }} and {{ subtract $batched_events_count 1 }} others liked your post. 
{{else}} 
{{ $batched_events.[0].username }} liked your post.
{{/compare}}

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

&lt;/div&gt;



&lt;p&gt;The final result would look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkjb3jfzo6j7cadrpipc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkjb3jfzo6j7cadrpipc.png" alt="Image description" width="550" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Beyond Batching: Implementing Throttling
&lt;/h3&gt;

&lt;p&gt;While batching reduces the total number of notifications, introducing throttling can further enhance user experience by limiting the frequency of notifications. By setting an upper limit on daily notifications, we ensure users are not overwhelmed even with multiple batches.&lt;/p&gt;




&lt;p&gt;For hands-on implementation, please refer to the provided GitHub repository and deployed application links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/SuprSend-NotificationAPI/social-app-react-app-inbox" rel="noopener noreferrer"&gt;SuprSend Social App&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Deployed Application: &lt;a href="https://suprsend-notificationapi.github.io/social-app-react-app-inbox/" rel="noopener noreferrer"&gt;SuprSend Demo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Incase you want to check out the Javascript SDK, you can head here: &lt;a href="https://docs.suprsend.com/docs/javascript-sdk" rel="noopener noreferrer"&gt;https://docs.suprsend.com/docs/javascript-sdk&lt;/a&gt; &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>programming</category>
      <category>react</category>
    </item>
    <item>
      <title>React App Inbox with 0 Notification Costs.</title>
      <dc:creator>Nik L.</dc:creator>
      <pubDate>Sun, 23 Jun 2024 08:32:01 +0000</pubDate>
      <link>https://dev.to/suprsend/react-app-inbox-with-0-notification-costs-jik</link>
      <guid>https://dev.to/suprsend/react-app-inbox-with-0-notification-costs-jik</guid>
      <description>&lt;p&gt;Building a robust notification system in React can be a complex task. Juggling multi-channel notifications, real-time updates, and user interaction requires a powerful solution. Enter the &lt;a href="https://docs.suprsend.com/docs/inbox-react" rel="noopener noreferrer"&gt;SuprSend Inbox for React&lt;/a&gt;, a feature-packed library designed to simplify and elevate your app's notification experience.&lt;br&gt;
Check out this video first to understand how will this notification infrastructure platform work?&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/oNhJjh5ZHkU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Want to see inapp inbox in action first? &lt;a href="https://inbox-playground.suprsend.com/" rel="noopener noreferrer"&gt;Head here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2. Under the Hood
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Frontend:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Built with TypeScript for type safety and enhanced developer experience.&lt;/li&gt;
&lt;li&gt;Provides various UI components like notifications list, bell icon, and notification details view.&lt;/li&gt;
&lt;li&gt;Customization options allow you to tailor the look and feel to match your app's branding.&lt;/li&gt;
&lt;li&gt;Integrates seamlessly with popular state management libraries like Redux and Context.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;REST API for sending notifications, managing subscribers, and tracking user engagement.&lt;/li&gt;
&lt;li&gt;Supports multiple notification channels like email, push notifications, and SMS via external integrations.&lt;/li&gt;
&lt;li&gt;Scalable architecture ensures reliable performance even with high notification volumes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;HMAC authentication secures communication between your app and SuprSend's API.&lt;/li&gt;
&lt;li&gt;Data encryption protects sensitive user information.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Integration Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setup:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install the &lt;code&gt;@suprsend/react-inbox&lt;/code&gt; library using npm.&lt;/li&gt;
&lt;li&gt;Configure the SuprSend SDK with your workspace key and subscriber ID.&lt;/li&gt;
&lt;li&gt;Define optional settings like notification display format, custom icons, and initial visibility.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Integration:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Render the &lt;code&gt;SuprSendInbox&lt;/code&gt; component in your React app layout.&lt;/li&gt;
&lt;li&gt;Pass the configuration details as props to customize the Inbox's behavior and appearance.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import SuprSendInbox from '@suprsend/react-inbox'

// add to your react component
&amp;lt;SuprSendInbox
  workspaceKey= "&amp;lt;workspace_key&amp;gt;"
  subscriberId= "&amp;lt;subscriber_id&amp;gt;"
  distinctId= "&amp;lt;distinct_id&amp;gt;"
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Use SuprSend's API from your backend server to send notifications with rich content and metadata.&lt;/li&gt;
&lt;li&gt;Leverage the SDK's event system to handle user interactions like clicking on notifications or marking them as read.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj44ogzzxtyxnqdxbhzck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj44ogzzxtyxnqdxbhzck.png" alt="Image description" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Advanced Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time Updates:&lt;/strong&gt; WebSockets enable instant notification delivery, keeping the Inbox updated dynamically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Components:&lt;/strong&gt; Build custom UI elements for specific notification types or personalize the Inbox layout with render props.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline Support:&lt;/strong&gt; Store notifications locally for offline access and ensure a seamless user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep Linking:&lt;/strong&gt; Integrate notifications with internal app pages for smooth navigation upon clicking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Analytics:&lt;/strong&gt; Track user engagement metrics like notification open rates and click-through rates for optimization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Technical Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Choose appropriate notification channels based on your app's purpose and target audience.&lt;/li&gt;
&lt;li&gt;Implement proper error handling mechanisms for API requests and network failures.&lt;/li&gt;
&lt;li&gt;Design a user-friendly notification experience with clear visuals and intuitive interactions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.suprsend.com/docs/inbox-react" rel="noopener noreferrer"&gt;SuprSend Inbox for React Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.suprsend.com/docs" rel="noopener noreferrer"&gt;SuprSend API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://legacy.reactjs.org/" rel="noopener noreferrer"&gt;React Community Forums&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Send Push Notifications without Hassles of FCM Token Generation</title>
      <dc:creator>Nik L.</dc:creator>
      <pubDate>Tue, 21 May 2024 14:56:07 +0000</pubDate>
      <link>https://dev.to/suprsend/send-push-notifications-without-hassles-of-fcm-token-generation-1n91</link>
      <guid>https://dev.to/suprsend/send-push-notifications-without-hassles-of-fcm-token-generation-1n91</guid>
      <description>&lt;p&gt;Handling FCM tokens and marking the user state is a hassle that businesses doesn't want to get into. To solve for this, SuprSend provides you with all the popular languages SDK, with point install and integration. &lt;/p&gt;

&lt;h2&gt;
  
  
  Token Generation and Notification handled By SDK
&lt;/h2&gt;

&lt;p&gt;You may use this option if all of your android push notifications are to be handled via SuprSend SDK. We recommend you use this method as it is just a single-step process to just register the service in your application manifest and everything else will be ready.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;!--If you are targeting to API 33 (Android 13) you will additional need to add POST_NOTIFICATIONS --&amp;gt;
&amp;lt;uses-permission android:name="android.permission.POST_NOTIFICATIONS" /&amp;gt;

&amp;lt;service
    android:name="app.suprsend.fcm.SSFirebaseMessagingService"
    android:enabled="true"
    android:exported="false"&amp;gt;
    &amp;lt;intent-filter&amp;gt;
        &amp;lt;action android:name="com.google.firebase.MESSAGING_EVENT" /&amp;gt;
    &amp;lt;/intent-filter&amp;gt;
&amp;lt;/service&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full documentation here: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React Native - &lt;a href="https://docs.suprsend.com/docs/react-native-firebase-fcm-push-integration%C2%A0" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Android - &lt;a href="https://docs.suprsend.com/docs/android-firebase-fcm-push-integration" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Flutter - &lt;a href="https://docs.suprsend.com/docs/flutter-firebase-fcm-push-integration" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>firebase</category>
      <category>android</category>
      <category>reactnative</category>
      <category>flutt</category>
    </item>
  </channel>
</rss>
