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

  • 897