RecruitingBot — Telegram come strumento aziendale

Angelo Capozzi
weBeetle
Published in
7 min readJul 15, 2019

Come creare un Bot Telegram che raccoglie curricula per la tua azienda

Introduzione

In questo tutorial creeremo un semplice Bot che si occuperà di raccogliere i curricula delle persone.

Per renderci la vita più semplice (*ironia*) abbiamo scelto di non utilizzare librerie che gestiscono le API di Telegram bensì farlo alla “vecchia” maniera.

Per creare questo bot, come anche tanti altri è necessario:

  • Avere un pc con installato Nodejs;
  • Avere un account Telegram.

Creiamo il Bot

La prima cosa da fare per poter creare il nostro Bot è accedere all’applicazione Telegram e cercare “BotFather” nella barra di ricerca.

Dopo averlo trovato, digitiamo all’interno della chat il comando: /newbot.

Il BotFather, dunque, ci chiederà di inserire dapprima il nome del bot e successivamente l’username.

Noi, per questo esempio, abbiamo scelto rispettivamente “WeBeetle” e “WeBeetleBot”. Tu necessariamente dovrai sceglierne un altro.

NB: il BotFather ci vincolerà a scegliere un username che termini con la parola “bot”.

Inizializziamo il progetto

Ora che il nostro bot è stato creato sarà necessario configurare il progetto su cui lavoreremo e su cui scriveremo il core del nostro Bot!

Assicuriamoci dapprima di aver installato Node, fatto? Perfetto!

Creiamo una cartella, noi la chiameremo “webeetle-bot”, e dopo averlo fatto apriamo il terminale. Eseguiamo al suo interno i comandi:

npm init

NB: Questo comando è un’utility che ti permette di inizializzare un nuovo package.json, necessario per i progetti node.

In questo tutorial lasceremo la configurazioni di default del package.json, quindi ci basterà battere una serie di “invio” sulla tastiera per poterci ritrovare con un output del genere:

Il nostro progetto è quasi pronto, mancano solo alcune dipendenze che installeremo con il comando:

npm install —-save fastify axios

Le dipendenze installate:

- fastify, (qui l’articolo precedente sul perchè lo abbiamo scelto) è un framework per le applicazioni web che fornisce una serie di strumenti per la creazione di server HTTP, siti web e API pubbliche;

- axios, è un modulo che fornisce strumenti per effettuare chiama HTTP in modo semplice e veloce.

Start!

Adesso che abbiamo terminato la parte configurativa, dobbiamo creare nella nostra cartella un file nominato “server.js” ed iniziare a scrivere all’interno:

//Includo la dipendenza fastify
const fastify = require('fastify')({logger: true})


//Esegue il server sulla porta 3000
const start = async() => {
try {
await fastify.listen(3000)
fastify.log.info(`server listening on ${fastify.server.address().port}`)
}
catch (err) {
fastify.log.error(err)
process.exit(1)
}
}
start()

In questo modo abbiamo dapprima incluso la dipendenza “fastify” e successivamente abbiamo definito che la nostra applicazione deve rimanere in ascolto (“aspettare”) sulla porta 3000.

Per far partire il nostro server e poterlo prova è necessario eseguire nel nostro terminale il comando:

npm start

Se tutto è andato bene avremo un output del genere:

Adesso possiamo verificare se il nostro server è pronto. Apriamo il nostro browser e digitiamo nella barra degli indirizzi: “http://localhost:3000”. Se abbiamo fatto tutto e siamo fortunati (*ironia*) ci mostrerà qualcosa del genere:

Ha funzionato? Perfetto! Possiamo continuare.

Definizione della logica

Al momento abbiamo configurato il nostro progetto, ora non ci resta che dare vita al nostro bot insegnandogli a rispondere ai messaggi!

Il codice che segue permetterà al nostro bot, interrogato su uno specifico path (“/new-message”) con metodo (“POST”), di eseguire determinate azioni.

const fastify = require('fastify')({logger: true})
const axios = require('axios');

const TOKEN = "<TOKEN OTTENUTO DAL BOTFATHER>";
const BOT_URL = `https://api.telegram.org/bot${TOKEN}`;
const BOT_URL_FILE_CONTENT = `https://api.telegram.org/file/bot${TOKEN}`;

const welcome = async(message) => {
const {first_name = ''} = message.chat;

return await axios.post(`${BOT_URL}/sendMessage`, {
chat_id: message.chat.id,
text: `Ciao ${first_name}, io sono il WeBeetleBot! Come posso aiutarti?`,
parse_mode: 'Markdown',
reply_markup: {
keyboard: [
['Voglio lavorare con voi!'],
['Chi siete?'],
],
resize_keyboard: true,
one_time_keyboard: false
}
});
};

const stupidAnswer = async(message) => {
return await axios.post(`${BOT_URL}/sendMessage`, {
chat_id: message.chat.id,
text: `Ancora non so rispondere a questa domanda \u{1F62D}`,
parse_mode: 'Markdown',
reply_markup: {
keyboard: [
['Voglio lavorare con voi!'],
['Chi siete?'],
],
resize_keyboard: true,
one_time_keyboard: false
}
});
};

const whoAreYou = async(message) => {
return await axios.post(`${BOT_URL}/sendMessage`, {
chat_id: message.chat.id,
text: `Siamo un'azienda...`,
parse_mode: 'Markdown',
reply_markup: {
keyboard: [
['Wow, voglio lavorare con voi!'],
],
resize_keyboard: true,
one_time_keyboard: false
}
});
};

const iWantToWorkWithYou = async(message) => {
return await axios.post(`${BOT_URL}/sendMessage`, {
chat_id: message.chat.id,
text: `Perfetto, adesso dovrai caricare il tuo curriculum! Sei pronto?`,
parse_mode: 'Markdown',
reply_markup: {
keyboard: [
['Si, sono pronto!'],
['Non sono ancora pronto...'],
],
resize_keyboard: true,
one_time_keyboard: false
}
});
};

const ImNotReady = async(message) => {
return await axios.post(`${BOT_URL}/sendMessage`, {
chat_id: message.chat.id,
text: `Forza, chi stai aspettando! \u{1F621}\u{1F621}\u{1F621}`,
parse_mode: 'Markdown',
reply_markup: {
keyboard: [
['Ora, sono pronto!'],
['Non sono ancora pronto...'],
],
resize_keyboard: true,
one_time_keyboard: false
}
});
};

const ImReady = async(message) => {
return await axios.post(`${BOT_URL}/sendMessage`, {
chat_id: message.chat.id,
text: `È arrivato il momento, carica il curriculum! \u{1F929}\u{1F929}\u{1F929}`,
parse_mode: 'Markdown',
reply_markup: {
remove_keyboard: true
}
});
};

const getFileInfo = async(file_id) => {
if (!file_id) {
return;
}

return await axios.get(`${BOT_URL}/getFile?file_id=${file_id}`);
};

const getFileContent = async(file_path) => {
if (!file_path) {
return;
}

return await axios.get(`${BOT_URL_FILE_CONTENT}/${file_path}`);
};

const sendDocument = async(message, file_id) => {
return await axios.post(`${BOT_URL}/sendDocument`, {
chat_id: message.chat.id,
document: file_id, //Per questo esempio utilizziamo il contentuto del file e non il file_id per verificare che il contenuto file non sia corrotto.
reply_markup: {
remove_keyboard: true
}
});
};

const OK = async(message) => {
const {first_name = ''} = message.chat;

return await axios.post(`${BOT_URL}/sendMessage`, {
chat_id: message.chat.id,
text: `Grazie ${first_name}, valuteremo la tua candidatura! \u{270C}\u{1F61C}`,
parse_mode: 'Markdown',
reply_markup: {
remove_keyboard: true
}
});
};

fastify.post('/new-message', async(request) => {
const body = request.body;
const {message = {}} = body;
const {document = {}} = message;
const {file_id} = document;

if (file_id) {
let fileInfo = await getFileInfo(file_id);
if (fileInfo && fileInfo.data) {
let {file_path} = fileInfo.data.result;
if (file_path) {
//Da qui in poi puoi continuare a giocare come più preferisci

let fileContent = await getFileContent(file_path); //Recuperiamo il contenuto del file
if (fileContent) {
// await sendDocument(message, file_id);
await OK(message);
}
}
}

return {};
}

switch (body.message.text) {
case "/start":
await welcome(message);
break;
case "Wow, voglio lavorare con voi!":
case "Voglio lavorare con voi!":
await iWantToWorkWithYou(message);
break;
case "Chi siete?":
await whoAreYou(message);
break;
case "Si, sono pronto!":
case "Ora, sono pronto!":
await ImReady(message);
break;
case "Non sono ancora pronto...":
await ImNotReady(message);
break;
default:
await stupidAnswer(message);
}

return {};
})

const start = async() => {
try {
await fastify.listen(3000)
fastify.log.info(`server listening on ${fastify.server.address().port}`)
}
catch (err) {
fastify.log.error(err)
process.exit(1)
}
}
start()

NB: Tutti i metodi invocati e disponibili li può trovare qui: https://core.telegram.org/bots/api.

Recuperiamo il Token

Il nostro Bot è pronto, ora non ci resta che pubblicarlo!

Prima di farlo, però, è necessario recuperare il token del Bot.

Questo token può essere recuperato al momento della creazione, quando viene generato il bot, o digitando /mybots nella chat del BotFather.

Il token servirà sia per sottoscrivere il nostro Bot al Webhook di Telegram, in modo che possa rispondere ai messaggi in entrata.

Sostituito il token, all’interno del nostro codice, non ci resta altro che pubblicarlo!

Pubblichiamo il Bot

Come accennato prima il token ci servirà per sottoscrivere il nostro Bot al Webhook di Telegram. Prima di farlo però è necessario pubblicare il nostro progetto.

E’ possibile fare questo velocemente utilizzando un servizio offerto dal pacchetto npm now. Installiamolo globalmente con questo comando.

npm install -g now

Dopo averlo installato, eseguiamo nella cartella in cui stavamo lavorando il comando now. Questo comando pubblicherà online il nostro bot. Al termine della pubblicazione avremo questa schermata:

In questa schermata la cosa che ci interessa è l’url in https evidenziato con il colore azzurro. Questo url ci servirà per sottoscrivere la nostra applicazione. La sottoscrizione avverrà eseguendo nel nostro terminale il seguente comando, dopo aver opportunamente sostituito url e il token:

curl -F “url=<url-pubblicazione-generato>/new-message” https://api.telegram.org/bot<tuo-token>/setWebhook

Ora non ci resta che provare il nostro Bot!

Proviamolo

Apriamo la chat del nostro Bot e proviamolo!

“Il mio Bot non funziona!”

Se il tuo bot non funziona ho due suggerimenti per te:

1. Verifica che i tuoi messaggi siano stati processati correttamente e che non siano rimasti in attesa per un errore. Digita nella barra degli indirizzi del tuo browser questo url:

https://api.telegram.org/bot<tuo-token>/getWebhookInfo

2. Vuoi verificare se ci sono problemi all’interno del deploy? Esegui questo comando all’interno del tuo terminale:

now logs -f <url-pubblicazione-generato>

Spero tu ora abbia qualche strumento per risolvere il problema!

Questo è un semplice esempio di cosa puoi fare, ora non resta che dare spazio alla tua immaginazione!

Alla prossima!

Letture consigliate

Fastify, le ragioni di una scelta di Davide D’Antonio x weBeetle

--

--