Chatbot + Crawler
Com
Clóvis Neto
Front End Engineer
"Sou entusiasta, não especialista."
Chatbots
"Eles já fazem parte do nosso dia a dia sem mesmo que possamos nos dar conta"
"Falando com Robôs"
Teste de TURING
BOTS vs. CHATBOTS
Eles entraram no jogo!
1- Adicionar um novo aplicativo
2- Instale o serviço do messenger
3- Selecione a página e copie o seu token de acesso
Webhooks
Com o token da página em posse, configuramos o webhook
- url de verificação
- token que será passado pelo facebook
Webhooks
Done! Sua aplicação agora está recebendo notificações do messenger
Time to code
Messenger Docs
Messenger Docs
Botão de começar + texto de apresentação
NodeJS - Request
npm install --save request
request({
url: 'https://graph.facebook.com/v2.6/me/messenger_profile',
qs: {access_token: fbToken},
method: 'POST',
json: {
"get_started":{
"payload":"GET_STARTED"
}
}
}, RequestUtils.checkErrors);
request({
url: 'https://graph.facebook.com/v2.6/me/messenger_profile',
qs: {access_token: fbToken},
method: 'POST',
json: {
"greeting":{
"locale":"default",
"text":"Chatbot da comunidade do FEMUG-PE. Se prepare, pois este botsinho vai mudar a sua vida!"
}
}
}, RequestUtils.checkErrors);
Say Ping - Pong
Webhook.js
class WebHook {
constructor(){}
static init(app){
app.post('/webhook/', (req, res) => webhook.checkWebhook(req, res));
}
checkWebhook(req, res){
let instance = this;
let data = req.body;
if (data) {
data.entry.forEach(instance.checkEvent.bind(instance));
res.sendStatus(200);
} else {
res.status(401).send('Error, wrong message');
}
}
checkEvent(entry){
entry.messaging.forEach(event => {
Endpoints.checkMessages(event);
})
}
}
Endpoints.js
class Endpoints {
static checkMessages({message, sender}){
let Bot = new BotClass(fbToken, sender);
if(message.text == "Ping"){
return Bot.sendPong();
}else{
return Bot.sendTextOfApresentation();
}
}
{...}
}
class Bot {
{...}
sendPong(){
let sender = this.sender;
RequestUtils.sendMessage(sender, {
"text": "Pong"
}, RequestUtils.checkErrors);
}
{...}
}
Bot.js
const fbToken = require('../config/config').fb.page_token;
const request = require('request');
class RequestUtils {
static sendMessage(sender, messageData, callback) {
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token: fbToken},
method: 'POST',
json: {
recipient: {id: sender.id},
message: messageData,
}
}, (error, response) => {
this.checkErrors(error, response);
if(callback){
return callback();
}
})
}
}
module.exports = RequestUtils;
RequestUtils.js
<Postback>
Enviando um botão
let options = {
{...}
navigation_buttons: [
{
"type":"postback",
"title":"👌 Sugerir tema novo",
"payload":"USER_DEFINED_OPINION"
},
{
"type":"postback",
"title":"🤘 BrazilJS WEEKLY",
"payload":"USER_DEFINED_BRASILJS_WEEKLY"
},
{
"type":"postback",
"title":"🇧🇷 Post's do CSS Brasil.org",
"payload":"USER_DEFINED_CSSBRASIL_WEEKLY"
}
]
};
module.exports = options;
BotOptions.js
const botOptions = require('./bot-options');
const navButtons = botOptions.navigation_buttons;
class Bot {
{...}
sendTextOfApresentation(){
let sender = this.sender;
RequestUtils.sendMessage(sender, {
"attachment":{
type:"template",
payload:{
template_type:"button",
text:'Olá jovem padawan, meu nome é chico e sou o novo mascote do FEMUG-PE!\nEstou aqui para lhe ajudar a interagir com o nosso grupo e lhe manter atualizado com as novidades do mundo da web! Escolha uma das opções abaixo para que eu possa interagir com você:',
buttons: navButtons
}
}
}, RequestUtils.checkErrors);
}
}
Bot.js
And... Done!
Recebendo um postback
class WebHook {
{...}
checkEvent(entry){
entry.messaging.forEach(event => {
if(event.message){
Endpoints.checkMessages(event);
}else if(event.postback){
Endpoints.checkPostbacks(event);
}
})
}
}
module.exports = WebHook;
Webhook.js
const BotClass = require('../entities/bot/Bot');
class Endpoints {
{...}
static checkPostbacks({postback, sender}){
let Bot = new BotClass(fbToken, sender);
const checkPayload = ( payload ) => {
const cases = {
'GET_STARTED': Bot.sendTextOfApresentation.bind(Bot),
'USER_DEFINED_OPINION': Bot.askForOpinion.bind(Bot),
'USER_DEFINED_CSSBRASIL_WEEKLY': Bot.searchCSSWeekly.bind(Bot),
'USER_DEFINED_BRASILJS_WEEKLY': Bot.searchBRASILJSWeekly.bind(Bot)
};
return cases[payload]();
};
return checkPayload(postback.payload);
}
}
module.exports = Endpoints
Endpoints.js
Outras possibilidades...
Imagens, vídeos, audios e outros formatos de arquivos
Botão Compartilhar
Botão Comprar
WebView
Modelos de Recibos
E muito mais!
Unindo forças
Crawler
Básicamente, é um robô usado para encontrar, e capturar informações das páginas de um site.
NodeJS - Crawler
npm install --save Crawler
var Crawler = require("crawler");
var c = new Crawler({
maxConnections : 10,
// This will be called for each crawled page
callback : function (error, res, done) {
if(error){
console.log(error);
}else{
var $ = res.$;
// $ is Cheerio by default
//a lean implementation of core jQuery designed specifically for the server
console.log($("title").text());
}
done();
}
});
// Queue just one URL, with default callback
c.queue('http://www.amazon.com');
http://cssbrasil.org
Bot.js
searchCSSWeekly(){
let instance = this;
let _$, data = [];
let c = new Crawler({
maxConnections : 10,
callback: (err, res, done) => {
_$ = res.$;
_$('.box').each((i, el)=> data.push(instance._formatCSSWeekly(_$(el))));
instance.sendWeekly(CSS_WEEKLY_TEXT, data).then(done);
}
});
c.queue(`${CSS_BRASIL_URL}/articles/`);
}
_formatCSSWeekly(obj){
let data = {
title: obj.find('h3').text(),
link: `${CSS_BRASIL_SECURE_URL}${obj.find('a').attr('href')}`,
imgUrl: `${CSS_BRASIL_URL}${obj.find('img').attr('src')}`,
subtitle: obj.find('p').text()
};
return botOptions.formatWeeklyInformations(data)
}
Exemplo
"Mais de 85% das interações com clientes serão gerenciadas sem a presença de um humano até 2020. Por isso, os serviços automatizados / humanizados se tornaram extremamente útil para engajar o consumidor."
- Apple
Dúvidas?
Obrigado!
@clovissneto
facebook.com/ClovisDaSilvaNeto
Chatbot + Crawler com Nodejs
By Clóvis Neto
Chatbot + Crawler com Nodejs
- 960