Blog Zenvia

O melhor portal de Marketing e Vendas para a sua empresa

Fortaleça sua comunicação com RCS

Novo padrão de comunicação, o RCS promete ser uma evolução do SMS e trazer os mesmos recursos de grandes aplicativos como o WhatsApp.

Entre chats, e-mails, redes sociais e WhatsApp, várias foram as soluções tecnológicas criadas a favor de uma comunicação mais rápida e facilitada. E em breve teremos acesso a mais uma opção de canal de comunicação: o RCS.

Aqui você encontrará:

  1. Definindo o RCS
  2. Quais as funcionalidades do RCS
  3. Por que sua empresa deveria investir em RCS
  4. Outros pontos de apoio para empresas
  5. Falando em segurança
  6. O RCS fora do Brasil
  7. O que podemos esperar
  8. RCS na prática

Tal tecnologia teve origem em 2008 com a Associação Mundial das Operadoras Móveis (GSMA) — instituição responsável pela padronização das telecomunicações móveis no mundo — e tinha como objetivo evoluir as funcionalidades do famoso SMS. Porém somente oito anos depois com aporte de gigantes como Samsung, Motorola, Google e Microsoft que ela ganhou mais visibilidade. 

Em 2017, a linguagem recebeu novas APIs que, entre outras coisas, permitem a integração do RCS com outros aplicativos. 

De acordo com a GSMA, nove são os princípios essenciais para garantir a confiança no RCS e conferir seu lugar como a plataforma de comunicação escolhida:

  1. Abertura;
  2. Inovação;
  3. Alcance;
  4. Qualidade;
  5. Proteção;
  6. Recompensa;
  7. Valor;
  8. Transparência;
  9. Privacidade.

Definindo o RCS 

Trata-se deRich Communication Services ou, em tradução livre, Serviços de Comunicação Rica. Esse formato, bem como WhatsApp irá possibilitar o envio de textos, imagens, GIFs, vídeos, arquivos, áudios, botões interativos e até mesmo carrosséis de produtos. Um dos diferenciais desse padrão é transmissão de mensagens multimídia entre celulares, e para isso os celulares nem mesmo precisam de conexão Wi-fi. 

O fato de o RCS oferecer uma Interface de Programação de Aplicativos (API) aberta e gratuita, colabora a integração deste com chatbots, sistemas de atendimento ao cliente, entre outros softwares. Em 2019, a Mobilesquared lançou um relatório que apontava um futuro bem positivo para o RCS: 

  1. Os consumidores se envolverão com pelo menos duas marcas todos os dias até 2023 via RCS; 
  2. Em 2018, havia 203 milhões de usuários de Android em todo o mundo e, no final de 2023 a previsão é de 2,8 bilhões de usuários de RCS; 
  3. Em 2021, o RCS se tornará oficialmente a maior plataforma de mensagens de negócios do mundo, com mais de 2 bilhões de usuários, representando 50% do total de usuários de smartphones. 

Quais as funcionalidades do RCS? 

O padrão RCS vem para trazer importantes funcionalidades e de forma simples. O que para as empresas é uma grande vantagem, já que elas terão mais uma opção de canal de comunicação com clientes.

Ele traz recursos e funções de grandes aplicativos de comunicação, como WhatsApp, Facebook Messenger e Telegram, possibilitando o envio de outros formatos além de mensagens de texto. Tudo isso é feito através do Messages (Google), aplicativo nativo do sistema Android. 

A seguir alguns dos recursos do RCS que podem melhorar a experiência do cliente: 

Recursos ricos

Os recursos avançados do RCS possibilitam a criação de experiências memoráveis para os clientes como:

  • Funcionalidade de localização aprimorada – compartilhamento de localização, visualização de mapa; 
  • Botões configuráveis – incorporados para enriquecer as comunicações e facilitar o feedback de clientes;
  • Botão ‘Abrir URL’ – permite abrir o link em um navegador da web ou dentro de um aplicativo;
  • Criar evento de calendário – utiliza detalhes pré-definidos para preencher um modelo de mensagem;
  • Mensagens mais longas – diferente do SMS, o RCS se limita a 160 caracteres, ou seja, o conteúdo da mensagem fica mais robusto. 

Oportunidades de marca

A partir do RCS toda a comunicação de sua empresa pode ser marcada, ou seja, na sua mensagem a identidade da sua marca ficará evidente por meio do nome da mesma, o logotipo e as cores características. Isso torna suas mensagens muito mais atraentes visualmente. 

Recurso Chatbot

Saber construir e manter um relacionamento com o cliente é fundamental para qualquer empresa. Através de chatbots habilitados para RCS, você utiliza a automação da conversa para oferecer a seus clientes notificações relevantes e captar padrões de comunicação repetitivos. Com bots você pode ter conversas com clientes, em qualquer lugar, a qualquer hora. 

Análise em tempo real 

A tecnologia do RCS possibilita que você obtenha informações relevantes e detalhadas acerca de seus clientes. Essa análise pode ser feita a partir de mensagens entregues, mensagens visualizadas e acompanhamento de eventos na tela, ou seja, uma visão apurada de como os consumidores estão interagindo com sua marca. 

Isso corrobora para campanhas de marketing mais direcionadas e melhora a taxa de conversão ao longo das interações. 

Por que sua empresa deveria investir em RCS 

Diferentes são os setores que podem aproveitar os benefícios do RCS e solucionar algumas de suas dores. A exemplo disso temos o e-commerce. Uma das métricas que deve ser acompanhada de perto por esse setor é o abandono de carrinhos. Segundo um estudo da E-commerce Radar, em 2017, cerca de 82% dos consumidores brasileiros desistiram de comprar. 

Para Robson Ribas, arquiteto de produtos na Zenvia, o RCS é um canal perfeito para impactar o usuário com conteúdo atraente, próximo ao momento de decisão pelos seguintes motivos: 

  • Diferente de outros canais, o RCS pode ser usado para promoção e remarketing; 
  • Esse padrão oferece bastante liberdade e personalização para criação de conteúdo. Dessa forma, é possível impactar o consumidor com mensagens de maior apelo visual, mostrando, por exemplo, um carrossel com as imagens dos produtos abandonados e botões para finalizar a compra no site/app; 
  • Pode ser integrado aos sistemas da empresa, sendo possível enviar uma mensagem assim que o cliente desistir, ou automaticamente após um período, atuando para ajudá-lo a rever a opinião sobre o carrinho. 

Outros pontos de apoio para empresas 

  1. Alto alcance

A premissa é fazer com que o RCS seja utilizado de forma nativa em dispositivos móveis, ou seja, um recurso de fábrica de tais aparelhos daqui alguns anos. E o alcance seria significativo. O WhatsApp, aplicativo que já está presente em 99% dos celulares dos brasileiros ainda precisa ser baixado pelos usuários. Mas no caso do RCS, o intuito é que no futuro ele já venha pré-instalado em qualquer aparelho

  1. Conteúdo multimídia 

Nem sempre o texto é suficiente para chamar a atenção de um cliente em potencial. Por isso, o RCS permite outros formatos como imagens e vídeos. O consumidor poderá receber notificações a respeito de novos produtos e serviços de maneira mais atraente e personalizada.

  1. Mais interatividade

A partir do RCS são desenvolvidos diálogos reais com clientes, o que dá abertura para feedbacks em tempo real ou a solução de um problema de forma rápida e discreta. Outra característica que agrega valor é a possibilidade de criar grupos, o que pode ser muito útil para comunicação interna. 

  1. Gestão Integrada 

Já que o RCS será uma ferramenta voltado a uma comunicação multicanal, faz sentido falarmos de ações integradas, por exemplo, elaborar um conteúdo a ser divulgado via RCS em vários canais.

Se sua empresa conta com um sistema CRM (Gestão de Relacionamento de Clientes, em tradução livre), uma dica valiosa é abastecer tal sistema com dados provenientes das interações através do RCS Business Messaging. 

Falando em segurança

Os golpes por aplicativos de mensagens aumentaram cerca de 25% durante a pandemia. Entre março e junho deste ano, 50 milhões de mensagens foram disparadas. Destas, 10 milhões a mais do que no mesmo período do ano passado. 

Já o relatório Spam and Phishing, produzido pela Kaspersky, o Brasil é o quinto país que mais sofreu com tentativas de phishing no segundo trimestre deste ano. O documento aponta que pelo menos 1 em cada 8 brasileiros sofreu tentativa deste tipo de golpe no período. 

O padrão RCS é uma ótima alternativa segundo Ribas, já que dispõe de “Remetente Verificado”, ou seja, confirmação de que a mensagem foi real enviada pela marca. 

“Para se tornar um remetente verificado é preciso que a empresa passe por uma análise e concorde com toda a política de segurança e termos de uso do produto do Google”, explica o arquiteto de produtos. Um dos pontos de segurança é o selo de verificação exibido ao lado da marca.

Tal certificação garante a tranquilidade do usuário final. Isso quer dizer que o remetente é confiável e que, portanto, a probabilidade de um caso de phishing ocorrer, como o uso indevido da marca, é menor. 

A criptografia também auxilia o usuário contra golpes. Os recursos de bate-papo do Google, por exemplo, usam criptografia Transport Layer Security (TLS) para proteger as mensagens. Isso significa que qualquer pessoa que tente interceptar as mensagens apenas visualizará o texto criptografado e ilegível. 

Ribas reforça que “além de contribuir na prevenção de phishing e de ter as mensagens criptografadas, é importante ressaltar o cuidado também dispensado na proteção dos dados, que certifica o correto armazenamento e descarte de informações de acordo com os termos da LGPD”.

A segurança dentro desse novo padrão de comunicação também pode ser vista por meio da autenticação de dois fatores (2FA) e alertas de movimentação suspeita.

O RCS fora do Brasil 

Atualmente o RCS do Google está disponível em países como França, México, Espanha, Reino Unido e Estados Unidos. Quanto à implantação no Brasil, Ribas afirma que nosso caso é bem particular. “Para que o usuário receba um RCS, é preciso que a operadora esteja preparada e que tenha um fornecedor de infraestrutura ou cloud associado. Aqui, as quatro operadoras, que respondem por mais de 90% do mercado, já estão habilitadas”. Todas selecionaram o Google como parceiro. 

De acordo com o arquiteto de produtos, em alguns países o processo está um pouco mais fragmentado, já que nem todas as operadoras estão prontas ou com parceiros diferentes. Já o cenário brasileiro se apresenta de forma mais favorável para adotar e acelerar o uso comercial de RCS. “

No caso da Zenvia, Ribas conta que são realizadas várias pesquisas a fim de mapear os principais casos de uso desse padrão. Outra medida é trabalhar próximo a clientes, especialmente os de perfil early adopter, para descobrir casos que fazem sentido dentro de diversas verticais, como Varejo, Financeiro, Tecnologia e Saúde. 

O que podemos esperar

A chegada do RCS promete revolucionar a comunicação, especialmente no que se refere ao relacionamento com o cliente, porém isso não implica que o SMS, daqui a alguns anos, será substituído por esse novo padrão.

“O SMS seguirá relevante e ainda crescendo em volume de mensagens nos próximos anos, mas o RCS vem para complementar a oferta de canais de comunicação entre marcas e consumidores”, explica Ribas

Para o arquiteto de produtos, ainda há um longo caminho para que o RCS esteja presente, de fato, em todos os smartphones, assim como ocorre com o SMS. “A tendência é que os recursos de conteúdo rico, aliados à segurança da comunicação e à identificação da marca que está mandando a mensagem, façam do RCS o canal preferido na comunicação entre marcas e consumidores”.

RCS na prática

O recurso de RCS permite o desenvolvimento de diversas ideias, já que permite diversas funcionalidades de chat. Assim, a criatividade é limite.

Para a construção do nosso chatbot, vamos utilizar a API da Zenvia de RCS, que permite o envio e o recebimento de mensagens gratuitamente em um ambiente de testes chamado de Sandbox.

O projeto final criado neste tutorial está disponível no nosso repositório do github.

Vamos começar criando uma conta, basta acessar este site, clicar em “CRIAR UMA CONTA” no canto superior direito e preencher os campos.

Após criar a conta, siga o seguinte fluxo: Menu superior > Produtos > Desenvolvedores > Sandbox > Criar novo > Escolha o canal “RCS” > Próximo

Informe o número de celular que irá receber as mensagens da Sandbox e clique em “Enviar Mensagem”. Se seu RCS estiver corretamente configurado, você irá receber uma mensagem de boas vindas e uma palavra-chave, basta respondê-la com esta palavra-chava e seu número estará configurado para o uso no ambiente testes:

Pode ocorrer um erro ao tentar cadastrar o celular na Sandbox, isso significa que você precisa ativar o recurso no celular:

Em caso de erro para criar o canal RCS, é preciso verificar se o RCS está ativado em seu celular e se ele e sua operadora são compatíveis.

Para ativar é preciso ter o APP “Mensagens” do Google, ir nos “3 pontinhos” → Configurações → Recursos de chat.

Se aparecer o seguinte erro, significa que você precisa atualizar o Carrier Services do Google:

Se mesmo atualizando o Carrier Services, significa que seu celular não é compatível.

Criando a aplicação Node.js

1- Instale o Node no seu computador (de preferência a versão LTS);

1.1- opcional – Instale o yarn. O node possui um gerenciador de pacotes padrão chamado npm (Node Package Manager), porém existe um gerenciador diferente chamado yarn. No restante deste artigo, haverão as opções de instalação para ambos gerenciadores de pacote como no passo a seguir.

2- Inicie o projeto criando o package.json com o seguinte comando no terminal:

npm init
yarn init

3 – Instale o ts-nodets-node-dev e o typescript como dependências de desenvolvimento:

npm i ts-node ts-node-dev typescript -D
yarn add ts-node ts-node-dev typescript -D

3.1 – Instale o arquivo de configuração do typescript:

npx typescript --init

4 – Abra o arquivo package.json e insira o script para iniciar o servidor assim como na área grifada em cinza:

{
  "name": "zenvia-rcs-chatbot",
  "version": "1.0.0",
  "description": "This project aims to create an example of creating a chatbot for RCS.",
  "main": "index.js",
  "scripts": {
    "dev": "ts-node-dev index.ts"
  },
  "author": "Henry Kimura",
  "license": "MIT",
  "devDependencies": {
    "ts-node": "^9.0.0",
    "ts-node-dev": "^1.0.0",
    "typescript": "^4.0.5"
  }
}

Criando chatbot e enviando mensagem ao celular cadastrado

1 – Instale a dependência request-promise para o Node:

npm i request-promise
yarn add request-promise

2 – Após ter configurado seu número de testes com a SandBox anteriormente, ele aparecerá na aba de contatos:

3 – Copie o código de exemplo abaixo e substitua SEU-TOKEN pelo seu token gerado pela plataforma Zenvia, substitua o REMETENTE e o DESTINATÁRIO também:

import { post } from 'request-promise'
post({
    uri: 'https://api.zenvia.com/v2/channels/rcs/messages',
    headers: {
        'X-API-TOKEN': 'SEU_TOKEN',
    },
    body: {
        from: 'REMETENTE',
        to: 'DESTINATARIO',
        contents: [
            {
                type: 'text',
                text: 'Lembre-se que sua consulta está marcada para às 15:00',
            },
        ],
    },
    json: true,
})
    .then((response) => {
        console.log('Response:', response)
    })
    .catch((error) => {
        console.log('Error:', error)
    })

As informações solicitadas podem ser encontradas nesta tela:

– Crie um arquivo index.ts, cole o código copiado anteriormente e salve o arquivo.

5 – Abra o terminal na pasta do projeto e execute o script criado anteriormente no package.json:

npm run dev
yarn dev

6 – Se estiver tudo certo, você receberá a mensagem configurada no código:

Criando exemplo de recebimento de mensagem

Até o momento apenas criamos um exemplo para enviar uma mensagem definida. Agora vamos para um exemplo mais divertido onde o usuário manda uma mensagem e recebe uma resposta.

Primeiro vamos precisar configurar um webhook, que é uma forma de recebimento de informações quando um evento acontece. No nosso caso, a API da Zenvia irá enviar um objeto JSON com informações sobre uma mensagem recebida pela API.

Configurando webhook

1- Vamos começar instalando o express para lidar com o recebimento das requisições e o body-parser para lidar melhor com o manuseio de objetos:

npm i express
npm i @types/express -D
npm i body-parser
yarn add express
yarn add @types/express -D
yarn add body-parser

2- Renomeie o arquivo index.ts para sendMessage.ts e crie um novo index.ts com este código:

import express, { Request, Response } from 'express'
import bodyParser from 'body-parser'
// Inicializa o express e define uma porta
const app = express()
const PORT = 3000
// Indica para o express usar o JSON parsing do body-parser
app.use(bodyParser.json())
app.post('/hook', (req: Request, res: Request) => {
    const { event } = req.body
    const message = event.body.message.contents[0].text // Armazena em uma variável a mensagem  
    res.status(200).end() // Responde quem solicitou nosso webhook com status 200
})
// Inicia o express na porta definida anteriormente
app.listen(PORT, () => console.log(`Server running on port ${PORT}`))

3- Precisamos tornar nosso webhook visível para que a API da Zenvia possa nos enviar as informações da mensagem recebida, para isto vamos utilizar o ngrok. Faça login no site, baixe a versão para Windows, extraia o zip, execute a aplicação (abrirá um terminal), autentique-se digitando ngrok authtoken SEU_TOKEN (seu token está na primeira tela do seu dashboard) e exponha a porta da aplicação (3000) digitando ngrok http 3000

Configurando a Zenvia para enviar dados ao nosso webhook

1- Após expor a porta da sua aplicação copie o link que aparecerá no terminal:

2- Vamos utilizar uma plataforma chamada pipedream para receber a informação da Zenvia e enviar ao nosso webhook. O pipedream é uma plataforma de workflow e vamos utilizá-la para fazer o fluxo de receber a informação e enviar para nós. Comece criando sua conta na plataforma. Após isso, siga o caminho https://pipedream.com/workflows > New + > HTTP / Webhook > New Requests (Payload Only) > <Dê algum nome> > Create Source > <Copie o link do seu recurso>:

3- Cole seu link do pipedream no campo “Message Webhook URL” e clique em “Salvar”:

4- Adicione um nó e selecione “Run Node.js code” e ligue seu gatilho:

5- Insira o código abaixo no nó e insira seu URL do ngrok no baseUrl e clique em deploy:

const axios = require('axios')
const api = axios.create({
    baseURL: 'SEU URL DO NGROK'
})
const sensitiveCall = await api.post('/hook', {
  event
})

6 – Mande uma mensagem de teste pelo Celular e verifique se seu webhook recebeu a informação. O conteúdo da mensagem estará dentro do corpo da requisição, desta forma: req.body.event.body.message.contents[0].text

7 – Agora que estamos recebendo a mensagem, vamos criar um sistema bem simples onde o chatbot recebe um “Oi” e ele responde com um “OláComo posso ajudar?“. Para começar, precisamos alterar o arquivo sendMessage.ts. Do jeito que ele está, este arquivo apenas envia uma mensagem específica ao nosso contato, vamos torná-lo em uma função dinâmica e exportável.

Vamos criar uma função exportável para mandar mensagem dinamicamente no sendMessage.ts, onde o parâmetro message da função, terá o conteúdo da mensagem que será enviada ao usuário:

import { post } from 'request-promise'
const sendMessage = (message) => {
    post({
        uri: 'https://api.zenvia.com/v2/channels/whatsapp/messages',
        headers: {
            'X-API-TOKEN': 'SEU_TOKEN',
        },
        body: {
            from: 'REMETENTE',
            to: 'DESTINATARIO',
            contents: [
                {
                    type: 'text',
                    text: message,
                },
            ],
        },
        json: true,
    })
        .then((response) => {
            console.log('Response:', response)
        })
        .catch((error) => {
            console.log('Error:', error)
        })
}
export default sendMessage

Adicione esta linha de importação no index.ts:

import express from 'express'
import bodyParser from 'body-parser'
import sendMessage from './sendMessage'
//...

Por fim, vamos alterar a rota /hook no arquivo index.ts

 //...
app.post('/hook', (req: Request, res: Response) => {
    const { event } = req.body
    const message = event.body.message.contents[0].text // Armazena em uma variável a mensagem
    if (message.toLowerCase().trim() === 'oi') { // Verifica se a mensagem enviada foi um "Oi"
        sendMessage(`Olá! Como posso te ajudar?`)
    } else { // Se não, mande a seguinte mensagem
        sendMessage('Me desculpe, não entendi.')
    }
    res.status(200).end() // Responde quem solicitou nosso webhook com status 200
})
//...

Nosso chatbot agora está funcionando, podendo receber uma mensagem e respondê-la

Com isso tudo apresentado você já consegue colher e enviar mensagens. A partir daqui a criatividade é o limite para a criação do seu chatbot.

Agora vamos criar um chatbot para ser o seu Assistente Pessoal que consiga guardar informações e lembrar o usuário destas informações em um horário específico, liste todas as informações guardadas e consiga removê-las também.

Exemplo de criação de um Assistente Pessoal

Agora a nossa aplicação vai ficar um pouco mais complexa e interessante, necessitando de um banco de dados para armazenar informações.

Para fins de aprendizado, vamos utilizar o SQLite pois é muito simples de ser configurado e não precisa ser instalado na sua máquina. Também utilizaremos um query builder chamado Knex.js, onde podemos contruir consultas em javascript e posteriormente podemos alterar o banco de dados que as consultas permanecerão as mesmas,

Configurando o ambiente

1 – Instale a dependência do SQLite

npm i sqlite3 
yarn add sqlite3

2 – Instale a dependência o Knex.js

npm install knex --save
yarn add knex

3 – Crie o arquivo de configuração knex com o nome knexfile.ts

import path from 'path' // lida com caminhos de arquivos
module.exports = {
    client: 'sqlite3',
    connection: {
        filename: path.resolve(__dirname, 'src', 'database', 'database.sqlite'),
    },
    migrations: {
        directory: path.resolve(__dirname, 'src', 'database', 'migrations'),
    },
    useNullAsDefault: true,
}

4 – Crie uma pasta src, dentro dela cria outra chamada database e crie o arquivo connection.ts

import knex from 'knex'
import path from 'path'
const db = knex({
    client: 'sqlite3',
    connection: {
        filename: path.resolve(__dirname, 'database.sqlite')
    },
    useNullAsDefault: true,
})
export default db

5 – Dentro da pasta database, crie outra chamada migrations e crie o arquivo 00_create_appointments.ts

import Knex from 'knex'
async function up(knex: Knex) {
    return knex.schema.createTable('appointments', (table) => {
        table.increments('id').primary(),
            table.string('description').notNullable(),
            table.timestamp('datetime').notNullable()
    })
}
async function down(knex: Knex) {
    return knex.schema.dropTable('appointments')
}
module.exports = { up, down }

5.1 – Em seguida, crie o banco de dados executando:

 npx knex --knexfile knexfile.ts migrate:latest 

Criando a interpretação de mensagens e o armazenamento de lembretes

1- Crie o arquivo PastaDoProjeto/src/functions/interpretsMessage.ts com a função que irá interpretar a mensagem recebida e direcionar para demais outras funções:

import sendMessage from './sendMessage'
import createAppointment from './createAppointment'
 
const interpretsMessage = (message: any) => {
    switch (message.toLowerCase().trim()) {
        case 'ajuda': // Verifica se a mensagem enviada foi "ajuda"
            sendMessage(`
                Olá! Digite algum dos comandos para saber mais:\n \t*lembrete*
            `)
            break
        case 'lembrete': // Verifica se a mensagem enviada foi "lembrete"
            sendMessage(
                `Entendido. Mande uma mensagem com o seguinte formato:\n Me lembre de _____ dia __/__/____ às __:__`
            )
            break
        default: // Se não foi nenhuma das anteriores
            if (message.split(' ')[1] === 'lembre') { // Verifica se é para armazenar o compromisso
                const description = message.split('Me lembre de ')[1].split(' dia')[0] // Armazena a descrição em uma variável
                const date = message.split('dia ')[1].split(' às')[0].split('/') // Armazena a data em uma variável
                const time = message.split('às ')[1] // Armazena o horário em uma variável
                const when = `${date[2]}-${date[1]}-${date[0]} ${time}` // Junta a data e o horário em uma variável
                const appointment = { // Armazena a descrição e quando o deve ser enviado o lembrete do compromisso em um objeto
                    description,
                    when,
                }
                createAppointment(appointment) // Chama a função de criar o compromisso no banco de dados (será criada logo a seguir)
            } else {
                // Se não, mande a seguinte mensagem
                sendMessage(
                    'Me desculpe, não entendi. Digite *ajuda* para saber todos os comandos.'
                )
                break
            }
    }
}
export default interpretsMessage

2 – No index.ts importe a função interpretsMessage, remova a importação da função sendMessage e altere a rota /hooks:

import express, { Request, Response } from 'express'
import bodyParser from 'body-parser'
import interpretsMessage from './src/functions/interpretsMessage'
// Inicializa o express e define uma porta
const app = express()
const PORT = 3000
// Indica para o express usar o JSON parsing do body-parser
app.use(bodyParser.json())
app.post('/hook', (req: Request, res: Response) => {
    const message = req.body.message.contents[0].text // Armazena em uma variável a mensagem
    interpretsMessage(message)
    res.status(200).end() // Responde quem solicitou nosso webhook com status 200
})
// Inicia o express na porta definida anteriormente
app.listen(PORT, () => console.log(`Server running on port ${PORT}`))

3 – Crie o arquivo PastaDoProjeto/src/functions/createAppointment.ts com a função de criação de um novo lembrete:

import db from '../database/connection' // Importação da conexão com o Banco de Dados
interface Appointment { // Formato do parâmetro appointment
    description: string
    when: string
}
async function createAppointment(appointment: Appointment) {
    const { description, when } = appointment // Coletando as informações do parâmetro
    await db('appointments').insert({ // Inserindo no banco de dados o compromisso
        description,
        when,
    })
}
export default createAppointment

Enviando o lembrete do compromisso

1- Vamos criar uma função que executa a cada 1 minuto e faz uma consulta ao banco de dados verificando se existe algum compromisso para aquele momento. Instale o node-cron e importe ele no index.ts para criarmos o laço

npm i node-cron
npm i @types/node-cron -D
yarn add node-cron 
yarn add @types/node-cron -D
import express, { Request, Response } from 'express'
import bodyParser from 'body-parser'
import interpretsMessage from './src/functions/interpretsMessage'
import cron from 'node-cron'
// Inicializa o express e define uma porta
const app = express()
const PORT = 3000
// Indica para o express usar o JSON parsing do body-parser
app.use(bodyParser.json())
app.post('/hook', (req: Request, res: Response) => {
    const message = req.body.message.contents[0].text // Armazena em uma variável a mensagem
    interpretsMessage(message)
    res.status(200).end() // Responde quem solicitou nosso webhook com status 200
})
cron.schedule('* * * * *', () => { // Laço que executa a cada 1 minuto
    checkAndSendReminder() // Função que será criada a seguir
})
// Inicia o express na porta definida anteriormente
app.listen(PORT, () => console.log(`Server running on port ${PORT}`))

– Mova o arquivo sendMessage.ts para o diretório PastaDoProjeto/src/functions/

3 – Devemos criar a função que verifica no banco de dados se há um compromisso e mandar um lembrete. Crie o arquivo no seguinte caminho PastaDoProjeto/src/functions/checkAndSendAppointment.ts

import db from '../database/connection' // Importação da conexão com o Banco de Dados
import sendMessage from './sendMessage' // Importação da função de envio de mensagem
const fixZero = (datetime: string) => {
    //Função para corrigir 0 no horário
    if (datetime.split(':')[0].substr(-2, 1) === ' ') {
        return `${datetime.substr(0, 11)}0${datetime.substr(11, 4)}`
    } else {
        return datetime
    }
}
export const checkAndSendReminder = async () => { // Função que verica a existência de compromisso e envia lembrete se houver
    // Captura a data e o horário atual
    const generatedDatetime = fixZero(new Date().toLocaleString('pt-BR')).substr(0, 16).split(' ')
 
    // Adequa a data para o formato guardado no bando de dados
    const datetime = `${generatedDatetime[0].split('/')[2]}-${generatedDatetime[0].split('/')[1]}-${generatedDatetime[0].split('/')[0]} ${generatedDatetime[1]}`
    const appointments = await db('appointments').where('datetime', '=', datetime).select('*') // Busca no Banco de Dados se existe um compromisso agora
    if (appointments.length !== 0) { // Se houver algum compromisso envia uma mensagem de lembrete
        const message = `Lembre-se que você precisa: ${appointments.map(
            (appointment) => `\n*${appointment.description}*`
        )}`
        sendMessage(message)
    }
}

4 – Vamos criar uma função que remove compromissos do banco de dados. Crie o arquivo  PastaDoProjeto/src/functions/removeAppointments.ts com o seguinte código:

import db from '../database/connection' // Importação da conexão do Banco de Dados
import sendMessage from './sendMessage' // Importação da função de envio de mensagem
async function removeAppointments(datetime: string, notificateUser: boolean) {
    const removedAppointment = await db('appointments').where('datetime', datetime).del() // Tenta remover do banco de dados os compromissos na data e hora especificadas
    if (notificateUser === true && typeof removedAppointment === 'number') { // Caso seja para notificar o usuario
        if (removedAppointment === 1) {    // Verifica se foi removido apenas um compromisso
            sendMessage('Lembrete apagado com sucesso.')
        }
        if (removedAppointment > 1) {    // Verifica se foram removidos diversos compromissos
            sendMessage('Lembretes apagados com sucesso.')
        }
    }
}
export default removeAppointments

5 – Para evitar que acumule informações desnecessárias, sempre que o usuário receber o lembrete, vamos apagar o compromisso no banco de dados. Para isto, vamos alterar o arquivo checkAndSendReminder.ts:

import db from '../database/connection' // Importação da conexão com o Banco de Dados
import sendMessage from './sendMessage' // Importação da função de envio de mensagem
import removeAppointments from './removeAppointments' // Importação da função de remoção de compromisso
const fixZero = (datetime: string) => {    //Função para corrigir 0 no horário
    if (datetime.split(':')[0].substr(-2, 1) === ' ') {
        return `${datetime.substr(0, 11)}0${datetime.substr(11, 4)}`
    } else {
        return datetime
    }
}
export const checkAndSendReminder = async () => {    // Função que verica a existência de compromisso e envia lembrete se houver
    // Captura a data e o horário atual
    const generatedDatetime = fixZero(new Date().toLocaleString('pt-BR')).substr(0, 16).split(' ')
 
    // Adequa a data para o formato guardado no bando de dados
    const datetime = `${generatedDatetime[0].split('/')[2]}-${generatedDatetime[0].split('/')[1]}-${generatedDatetime[0].split('/')[0]} ${generatedDatetime[1]}`
    const appointments = await db('appointments').where('datetime', '=', datetime).select('*') // Busca no Banco de Dados se existe um compromisso agora
    if (appointments.length !== 0) {        // Se houver algum compromisso envia uma mensagem de lembrete
        const message = `Lembre-se que você precisa: ${appointments.map(
            (appointment) => `\n*${appointment.description}*`
        )}`
        sendMessage(message)
        removeAppointments(datetime, false) // Remove o compromisso no banco de dados e não notifica o usuário
    }
}

6 – Vamos agora confirmar ao usuário quando um compromisso for agendado com sucesso. Altere o arquivo createAppointment.ts:

import db from '../database/connection'
import sendMessage from './sendMessage'
interface Appointment {
    description: string
    datetime: string
}
async function createAppointment(appointment: Appointment) {
    const { description, datetime } = appointment
    const insertedAppointment = await db('appointments').insert({
        description,
        datetime,
    })
    
    if (typeof insertedAppointment[0] === 'number') {
        sendMessage('Compromisso agendado com sucesso.')
    }
}
export default createAppointment

7- Agora precisamos permitir que o usuário remova compromissos, para isto vamos alterar o arquivo interpretsMessage.ts

import sendMessage from './sendMessage'
import createAppointment from './createAppointment'
import removeAppointments from './removeAppointments'
 
const interpretsMessage = (message: any) => {
    switch (message.toLowerCase().trim()) {
        case 'ajuda':    // Verifica se a mensagem enviada foi "ajuda"
            sendMessage(`
                Olá! Digite algum dos comandos para saber mais:\n\t*lembrete*\n\t*esqueça*
            `)
            break
        case 'lembrete':    // Verifica se a mensagem enviada foi "lembrete"
            sendMessage(
                `Entendido. Mande uma mensagem com o seguinte formato:\n Me lembre de _____ dia __/__/____ às __:__`
            )
            break
        case 'esqueça':    // Verifica se a mensagem enviada foi "esqueça"
            sendMessage(
                `Entendido. Mande uma mensagem com o seguinte formato:\n Desmarque tudo no dia __/__/____ às __:__`
            )
            break
        default: // Se não foi nenhuma das anteriores
            if (message.split(' ')[1] === 'lembre') { // Verifica se é para armazenar o compromisso
                const description = message.split('Me lembre de ')[1].split(' dia')[0] // Armazena a descrição em uma variável
                const date = message.split('dia ')[1].split(' às')[0].split('/') // Armazena a data em uma variável
                const time = message.split('às ')[1] // Armazena o horário em uma variável
                const datetime = `${date[2]}-${date[1]}-${date[0]} ${time}` // Junta a data e o horário em uma variável
                const appointment = {
                    description,
                    datetime,
                }
                createAppointment(appointment) // Chama a função de criar o compromisso no banco de dados
            } else if (message.substr(0, 9) === 'desmarque') { // Verifica se é para remover o compromisso
                const date = message.split('dia ')[1].split(' às')[0].split('/')
                const time = message.split('às ')[1]
                removeAppointments(`${date[2]}-${date[1]}-${date[0]} ${time}`, true)
            } else {
                // Se não, mande a seguinte mensagem
                sendMessage('Digite *ajuda* para saber todos os comandos.')
                break
            }
    }
}
export default interpretsMessage

8 – Teste e veja seu Assistente Pessoal funcionando:

9 – Vamos criar a função que liste todos os compromissos no arquivo indexAppointments.ts:

import db from '../database/connection' // Importação da conexão do Banco de Dados
import sendMessage from './sendMessage' // Importação da função de envio de mensagem
const showDate = (datetime: string) => { // Altera a exibição da data e da hora
    const date_time = datetime.split(' ')
    const date = date_time[0].split('-')
    return `${date[2]}/${date[1]}/${date[0]} às ${date_time[1]}`
}
async function indexAppointments() {
    const indexedAppointment = await db('appointments').select('*') // Busca no banco de dados os compromissos na data e hora especificadas
    if (indexedAppointment.length !== 0) { // Verifica se encontrou dados
        const message = `*Seus compromissos são:*${indexedAppointment.map(
            (appointment) => `\n\t${showDate(appointment.datetime)} - ${appointment.description}`
        )}`
        sendMessage(message) // Manda mensagem com os agendamentos
    } else {
        sendMessage('Você não possui compromissos marcados.') 
    }
}
export default indexAppointments

10 – Altere mais uma vez o arquivo interpretsMessage.ts para adicionar a função de agenda

import sendMessage from './sendMessage'
import createAppointment from './createAppointment'
import removeAppointments from './removeAppointments'
import indexAppointments from './indexAppointments'
//...
        case 'esqueça':    // Verifica se a mensagem enviada foi "esqueça"
            sendMessage(
                `Entendido. Mande uma mensagem com o seguinte formato:\n Desmarque tudo no dia __/__/____ às __:__`
            )
            break
        case 'agenda': // Verifica se a mensagem enviada foi "agenda"
            indexAppointments()
            break
        default:
//...

Agora seu Assistente Pessoal está pronto para guardar seus compromissos, te lembrar quando chegar o momento, listar todos os compromissos agendados e remover compromissos em uma determinada hora e data.

Conheça mais o potencial do RCS na página da Zenvia e através do seu curso online clicando aqui.

Leia Também:

Zenvia API's
Escrito por

Zenvia