# Simple Notification Service

Managed pub/sub message delivery service.

1. [TL;DR](#tldr)
1. [Connect a Slack channel to SNS](#connect-a-slack-channel-to-sns)
1. [Further readings](#further-readings)
   1. [Sources](#sources)

## TL;DR

_Publishers_ (or _producers_) send messages to a _topic_.<br/>
Topics are logical access points acting as communication channels for multiple _endpoints_ like SQS, emails, lambda,
and others.

SNS can be also used to send notifications to HTTP(S) endpoints such as Webhook URLs.<br/>
Anyway, SNS does **not** support sending requests using JSON key-value pairs, which some webhooks require (i.e. Slack).

_Subscribers_ (or _consumers_) subscribe to the topic and receive published messages using a supported endpoint type.

<details>
  <summary><i>Standard</i> topics</summary>

- Do **not** enforce strict message ordering, grouping, **nor** deduplication.<br/>
  Consumers of the queue may receive messages out of order, and more than once.
- Support **all** delivery protocols.

</details>
<details style="padding-bottom: 1em">
  <summary><i>FIFO</i> topics</summary>

- Integrate with FIFO queues in [SQS].
- **Do** enforce strict message ordering, grouping, and deduplication.<br/>
  They always deliver messages to subscribed [SQS] queues in the **exact** order in which the messages are published to
  the topic, and **only once**.
- **Do** ensure strict message ordering, message grouping, and deduplication.
- Allowing FIFO and standard queues to subscribe for message processing.

</details>

By default, only the topic's owner can publish or subscribe to the topic.<br/>
Configure additional access permissions by expanding the topic's Access policy.

<!-- Uncomment if used
<details>
  <summary>Setup</summary>

```sh
```

</details>
-->

<details>
  <summary>Usage</summary>

```sh
# List topics.
aws sns list-topics

# Get information about topics.
aws sns get-topic-attributes --topic-arn 'arn:aws:sns:eu-west-1:012345678901:aSucculentTopic'

# List subscriptions.
aws sns list-subscriptions
aws sns list-subscriptions --query 'Subscriptions'
aws sns list-subscriptions-by-topic --topic-arn 'arn:aws:sns:eu-west-1:012345678901:aSucculentTopic'

# Get information about subscriptions.
aws sns get-subscription-attributes \
  --subscription-arn 'arn:aws:sns:eu-west-1:012345678901:aSucculentTopic:abcdef01-2345-6789-abcd-ef0123456789'
```

</details>

<!-- Uncomment if used
<details>
  <summary>Real world use cases</summary>

```sh
```

</details>
-->

## Connect a Slack channel to SNS

Refer [How to Connect AWS SNS to Slack using Webhooks: Easy Step-by-Step Explanation].

SNS does **not** currently support integrating directly with third-party applications.<br/>
Leverage [Slack's incoming webhooks] or create a [Chatbot] configuration for the destination Slack channel.

<details>
  <summary>Webhook</summary>

SNS does **not** currently support sending requests using JSON key-value pairs, and Slack's webhooks require JSON
requests to include a message string as the value of the `text` key.<br/>
To solve this, use a Lambda function to modify the SNS message's body JSON document for the webhook endpoint.

Procedure:

1. Ensure the existence of a [Slack incoming webhook][slack's incoming webhooks] to send requests to.
1. Create a topic.<br/>
   The _standard_ type is usually enough.
1. Create a Lambda function.<br/>
   And test it works.
1. Add a topic trigger to the function.

<details>

<details>
  <summary>Chatbot</summary>

1. Ensure the existence of a [Slack incoming webhook][slack's incoming webhooks] to send requests to.
1. Create a topic.<br/>
   The _standard_ type is usually enough.
1. Create a IAM Role for the Chatbot configuration to use.

   <details>

   ```json
   {
       "Version": "2012-10-17",
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "Service": "chatbot.amazonaws.com"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

   ```json
   {
       "Version": "2012-10-17",
       "Statement": [
           {
               "Sid": "Autogenerated-AWS-Chatbot-NotificationsOnly-Policy",
               "Effect": "Allow",
               "Action": [
                   "cloudwatch:Describe*",
                   "cloudwatch:Get*",
                   "cloudwatch:List*"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

   </details>

1. Create a Chatbot configuration for the destination Slack channel.

<details>

## Further readings

- [SQS]

### Sources

- [What is Amazon SNS?]
- [How To Set Up A Slack Channel To Be An AWS SNS Subscriber]
- [How to Connect AWS SNS to Slack using Webhooks: Easy Step-by-Step Explanation]

<!--
  Reference
  ═╬═Time══
  -->

<!-- In-article sections -->
<!-- Knowledge base -->
[chatbot]: chatbot.md
[sqs]: sqs.md
[slack's incoming webhooks]: ../../slack.md#incoming-webhooks

<!-- Files -->
<!-- Upstream -->
[what is amazon sns?]: https://docs.aws.amazon.com/sns/latest/dg/welcome.html

<!-- Others -->
[how to set up a slack channel to be an aws sns subscriber]: https://medium.com/cohealo-engineering/how-set-up-a-slack-channel-to-be-an-aws-sns-subscriber-63b4d57ad3ea
[how to connect aws sns to slack using webhooks: easy step-by-step explanation]: https://hevodata.com/learn/sns-to-slack/
