Enviando SMS com Amazon SNS
Tags: node, javascript, aws, braziliandevs
Published: 2020-05-23 21:44:44

Enviar mensagens de texto, mum mundo em que os celulares dominam, é uma das formas mais simples e usuais de confirmação para login ou registro. Embora implementar algo assim tenha cara de complexo - afinal, envolve telefonia móvel, tipos de rotas e coisas obscuras para o cidadão médio -  veremos nesse artigo como lançar mão da AWS para isso, com o Simple Notification Service (SNS) e um pouco de Javascript.

# O que eu espero
- Que você já tenha uma familiaridade mínima com a AWS;
- Que você tenha acesso à credenciais (access key id e secret access key) para uma conta na AWS com acesso a SNS.
- Que você já tenha utilizado Node (e mais especificamente express).

# Conceitos
Já percebeu que o número daquela mensagem de confirmação do Uber ou iFood é bem curto?

![Short Codes Example](https://i.imgur.com/h5mgrDt.jpge)

Esses números são os chamados *short code*. O seu número, por outro lado, é um exemplo de *long code*. E por que isso é importante?

Short codes são destinados à comunicação em massa, podendo enviar cerca de 100 mensagens por segundo. Os *long codes*, além de destinados para comunicação pessoal, podem enviar apenas uma mensagem por segundo (e quase sempre são identificados como spam).

Um segundo conceito importanté diz respeito ao tipo da mensagem. As mensagens promocionais (*Promotional Messages*) são otimizadas para reduzir custos. Quando se trata de algo não crítico, em que reenviar o conteúdo é aceitável, esse é o tipo mais interessante. O outro se trata de mensagens transacionais (*Transactional Messages*), que são mais caras, mas garantem maior confiabilidade na entrega.

# Codando um exemplo
> Obs.: Por simplicidade, vamos omitir alguns passos relativos à segurança da aplicação durante o exemplo.

Vamos utilizar o `express` para construir uma API simples de envio de SMS e a própria sdk da AWS (`aws-sdk`) para ter acesso à plataforma.

# TL;DR
O código abaixo resume como criar a API:
```javascript
import express from 'express';
import AWS from 'aws-sdk';

// Função para envio da mensagem
async function sendSMS({ sns, Message, PhoneNumber }) {
  // Definições sobre o tipo de mensagem
  await this.sns.setSMSAttributes({
    attributes: {
      DefaultSMSType: 'Promotional'
    }
  }).promise();

  // Envio da mensagem
  sns.publish({
    Message,
    PhoneNumber, 
  }).promise();
}

// Configuração da SDK
const {
  AWS_ACCESS_KEY_ID: accessKeyId,
  AWS_SECRET_ACCESS_KEY: secretAccessKey,
 } = process.env;

AWS.config.update({
  region: 'us-east-1',
  accessKeyId,
  secretAccessKey,
});

const sns = new AWS.SNS({apiVersion: '2010-03-31'});

// Criação da API
const app = express();
app.use(express.json());
app.post('/send-sms', (req, res) => {
  const { PhoneNumber, Message } = req.body;
  sendSMS({ sns, PhoneNumber, Message });
  return res
    .status(201)
    .end();
});

app.listen(process.env.PORT || 3000);
```
Agora que tal ver isso em detalhes?

## Configuração da SDK
Caso já tenha utilizado a SDK da AWS para javascript, essa é uma parte bem simples e sem mistérios. De todo modo, vale a pena explicar rapidamente o que é feito.

Ao trabalhar com os serviços da Amazon, é necessário ter, como dito no início, credenciais válidas - uma chave secreta e seu ID. Tendo isso em mãos, basta utilizar o método `update` dentro do pacote `AWS.config`:

```javascript
AWS.config.update({
  region: 'us-east-1',
  accessKeyId,
  secretAccessKey,
});
```
Observe que existe também um parâmetro chamado "region". Ele se refere a qual região será escolhida para fornecer os serviços solicitados na aplicação, uma vez que a Amazon possui data-centers em diversos países. Nesse caso estamos utilizando a `us-east-1`, mas existem outras regiões compatíveis. [2]

## Função `sendSMS`
Nessa função, implementamos a lógica para envio das mensagens. Ela espera receber um objeto `sns`, criado a partir da classe AWS.SNS, o número para envio e a mensagem.

```javascript
await this.sns.setSMSAttributes({
    attributes: {
      DefaultSMSType: 'Promotional'
    }
  }).promise();
```

Definimos o tipo da que será enviada como `"Promotional"`. Observe que o método `setSMSAttributes` por si utiliza um esquema de callbacks, mas pode ser facilmente convertido em promise utilizado o método `promise` em cadeia. 

```javascript
sns.publish({
    Message,
    PhoneNumber, 
  }).promise();
```

Para de fato enviar a mensagem, basta chamar o método `publish`. Novamente, observe que utilizamos o método `promise`, mas desta vez não bloqueamos a execução da aplicação pelo fato de não ser importante monitorar a entrega do SMS.

## Criação da API
Tendo configurado a SDK e criado a função para enviar as mensagens de texto, resta construir uma API para a aplicação, o que é feito no ultimo trecho do código de exemplo:

```javascript
const app = express();
app.use(express.json());
app.post('/send-sms', (req, res) => {
  const { PhoneNumber, Message } = req.body;
  sendSMS({ sns, PhoneNumber, Message });
  return res
    .status(201)
    .end();
});
```
# Conclusão
Enviar SMS utilizando o Amazon SNS é uma tarefa simples, que pode ser feita sem muitas complicações. Contudo, é interessante estar atento aos custos (aprox. USD 0.02/sms no momento em que escrevo este artigo) e ao tipo de mensagem.

Gostou do artigo? Tem algum feedback? Quer sugerir algum tema? Deixa seu comentário e vamos trocar uma ideia. E claro, se acredita que mais alguem pode achar esse conteúdo relevante, não pense duas vezes antes de compartilhar. 

# Referências
[1] [Why use a short code instead of a long code?](https://support.twilio.com/hc/en-us/articles/223134587-Why-use-a-short-code-instead-of-a-long-code-)

[2] [Regiões e países compatíveis (SNS)](https://docs.aws.amazon.com/pt_br/sns/latest/dg/sns-supported-regions-countries.html)