<file_sep>const dotenv = require('dotenv').config();

const ACC_SID = process.env.TWILIO_ACCOUNT_SID;
const TOKEN = process.env.TWILIO_AUTH_TOKEN;
const PORT = process.env.PORT;
const TO_PHONE = process.env.TO_PHONE;
const FROM_PHONE = process.env.FROM_PHONE;
const DB_PWD = <PASSWORD>;
const DB_USER = process.env.DB_USER;
const DB_URL = process.env.DB_URL;

module.exports = {
  ACC_SID,
  TOKEN,
  PORT,
  TO_PHONE,
  FROM_PHONE,
  DB_PWD,
  DB_USER,
  DB_URL
}<file_sep>const twilio = require('twilio');
const config = require('../config');
const cliente = twilio(config.ACC_SID, config.TOKEN);
const messagingResponse = twilio.twiml.MessagingResponse;

module.exports = {

  async enviarMensagem(request, response, mensagem) {

    cliente.messages.create({

      from: config.FROM_PHONE,
      to: config.TO_PHONE,
      body: mensagem || 'Olá! Deseja verificar disponibilidade em minha agenda?'

    }).then(console.log);
  },

  async responderAposProvocacao(request, response) {
    const msgRecebida = request.body.Body;
    const msgResposta = new messagingResponse();
    
    msgResposta.message(`Certo, você digitou '${msgRecebida}'. Aguarde enquanto acerto alguns detalhes ...`);
    response.send(msgResposta.toString());
  }

}<file_sep># AtendeAI
> A simple Bot Service: _**Scheduling done autonomously**_.

Bot application that performs scheduling activities with some of Twilio's APIs

## A que se propõe:

Desenvolvido em resposta ao Desafio MEGAHACK proposto pela Shawee e Sebrae, esta aplicação tem por objetivos:
- [ ] Integrar-se com a plataforma popular de mensagem _WhatsApp_;
- [ ] Utilizar essa integração para responder a pedidos de agendamento;

## Status do MVP

O projeto se baseia em APIs da ***Twilio*** que facilitam duas integrações:
- Uso de mensageria atravéis do WhatsApp ([ref](https://www.twilio.com/whatsapp));
- Plataforma **Autopilot**, que usa inteligência artificial para construir e treinar os Bots ([ref](https://www.twilio.com/autopilot)).

É possível integrar o Autopilot com chamadas a uma API externa, que então interage com banco de dados. Assim, neste repositório ficará a API REST desenvolvida em Node e aliada a um banco de dados MongoDB, cujas funções são:
- [x] [Cadastro de um agendamento](https://github.com/thiagojacinto/atende-ai-bot-service/blob/10f0cc62beba0f17fabe8be378cf2921e4318ff8/src/Controllers/AgendaController.js#L10) a partir de um número de telefone;
- [x] Exibir informações sobre um agendamento [[1]](https://github.com/thiagojacinto/atende-ai-bot-service/blob/10f0cc62beba0f17fabe8be378cf2921e4318ff8/src/Controllers/AgendaController.js#L5), [[2]](https://github.com/thiagojacinto/atende-ai-bot-service/blob/10f0cc62beba0f17fabe8be378cf2921e4318ff8/src/Controllers/AgendaController.js#L38) previamente cadastrado.
- [x] Realizar a [confirmação ou desmarcação](https://github.com/thiagojacinto/atende-ai-bot-service/blob/10f0cc62beba0f17fabe8be378cf2921e4318ff8/src/Controllers/AgendaController.js#L59) do agendamento.

## Como usar

A partir de configuração - do banco de dados MongoDB e da porta selecionada - realizada em um arquivo separado [`config.js`](https://github.com/thiagojacinto/atende-ai-bot-service/blob/master/src/config.js), é somente necessário usar o comando:

```javascript
npm start
```

e então a API estará rodando localmente, cujo teste simples pode ser realizado digitando e esperando um status `200`:

```curl
curl http://localhost:3000/v1/agendamentos
```
<file_sep>const mongoose = require("mongoose");

const AgendamentoSchema = new mongoose.Schema({
  telefone: String,
  data: Date,
  observacoes: String,
  confirmacao: Boolean,
  maps: String,
}, {
  timestamps: {
    createdAt: 'created_at',
    updatedAt: 'updated_at',
  }
});

module.exports = mongoose.model("Agendamento", AgendamentoSchema);
<file_sep>// const axios = require('axios');
const Agendamento = require("../Models/Agendamento");

module.exports = {
  async index(request, response) {
    const todosAgendamentos = await Agendamento.find();
    return response.json(todosAgendamentos);
  },

  async store(request, response) {
    const { telefone, observacoes, confirmacao, maps } = request.body;

    await Agendamento.findOne(
      { telefone: telefone },
      async (err, duplicata) => {
        if (err) console.error(err);
        if (duplicata) {
          console.log(`Telefone ${telefone} já contem registro.`);
          return response.json({});
        }

        let data = new Date();
        let agend = await Agendamento.create({
          telefone,
          data,
          observacoes,
          confirmacao,
          maps,
        })
          .then(console.log("Agendamento realizado com sucesso."))
          .catch(console.error);

        return response.json(agend);
      }
    );
  },

  async show(request, response) {
    const { telefone } = request.body;

    let result = await Agendamento.findOne({ telefone: telefone })
      .then(response.status(200))
      .catch(console.error);

    return response.json(result);
  },

  async destroy(request, response) {
    const { telefone } = request.body;
    await Agendamento.findOneAndDelete(
      { telefone: telefone },
      (err, removido) => {
        if (err) return response.status(500).send(err);
        return response.status(200).json(removido);
      }
    );
  },

  async toggleConfirmation(request, response) {
    const { telefone } = request.body;
    let agendamento = await Agendamento.findOne({ telefone: telefone }).catch(
      console.error
    );

    // updating information:
    agendamento.confirmacao = !agendamento.confirmacao;
    agendamento.observacoes = agendamento.observacoes.concat(
      `, ${
        agendamento.confirmacao ? "confirmado" : "desmarcado"
      } em ${new Date().toLocaleDateString("pt-BR")}`
    );
    await agendamento
      .save()
      .then(
        response
          .status(200)
          .send(
            `Agendamento ${
              agendamento.confirmacao ? "confirmado" : "desmarcado"
            }.`
          )
      )
      .catch(console.error);

    return response;
  },
};
<file_sep>const { Router } = require("express");
const config = require("./config");
const twilio = require("twilio");

const rotas = Router();
const ManualController = require("./Controllers/ManualController");
const AgendaController = require("./Controllers/AgendaController");

rotas.post("/v1/agendar", AgendaController.store);
rotas.get("/v1/agendamentos", AgendaController.index);
rotas.post("/v1/agendamento", AgendaController.show);
rotas.delete("/v1/agendamento", AgendaController.destroy);
rotas.post("/v1/confirmacao", AgendaController.toggleConfirmation);

// Rotas manuais

rotas.get("/alpha/saudar", ManualController.enviarMensagem);
rotas.post("/alpha/resposta", ManualController.responderAposProvocacao);

module.exports = rotas;
<file_sep>const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');

const { PORT, DB_URL } = require('./config');
const rotas = require('./rotas');

const app = express();

mongoose.connect(DB_URL, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useFindAndModify: false
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.use(rotas);

app.listen(PORT, () => console.log(`Applicacao rodando na porta: ${PORT}`));