26 Gennaio, 2018 | Di

Come integrare le Telegram Bot API in Drupal 8 (Parte 1)

Come integrare le Telegram Bot API in Drupal 8 (Parte 1)

Ad oggi sono poche le persone che non conoscono Telegram (valida piattaforma di messaggistica istantanea), di molte spanne sopra il colosso Whatsapp... per svariate ragioni. Tra queste vi sono le sue Bot Api: ovvero un'interfaccia HTTP-based creata per gli sviluppatori di bot. Questi altro non sono che programmi risultanti come utenti su telegram, progettati per svolgere determinati compiti. Ad esempio:

  • @TrackBot: bot che permette di tener traccia di tutte le tue spedizioni degli acquisti online.
  • @tadam_bot: bot che permette di conoscere i dettagli di un brano inviandogli i primi 10sec di registrazione audio.
  • @ytbot: bot che permette di cercare video sul portale di Google a partire da una parola o da una frase.

 

Nel corso di questa breve serie di articoli:

  • creeremo un bot telegram;
  • implementeremo, mediante una classe "servizio" Drupal, un'interfaccia per le Telegram Bot API (sfruttando Telegram Bot API PHP SDK);
  • creeremo un blocco custom, con form configurabile, al submit della quale, il bot ci notificherà su telegram l'avvenuto contatto;

 

Requisiti

Lo scopo principale di questi articoli è quello di esplorare le nuove possibilità offerte da Drupal 8 e di come queste aumentino la manutenibilità e la qualità del codice sviluppato. Affinchè si possa seguire senza intoppi la serie, è necessario conoscere la programmazione PHP orientata agli oggetti e, ovviamente, il CMS Drupal 8. Per installare Drupal e Telegram Bot PHP SDK useremo composer(strumento adoperato da Drupal 8 per la gestione delle dipendenze PHP). Quindi, per lo sviluppo del nostro modulo, avremo bisogno di:

  • Composer
  • Client / Server MySQL installato (se non è possibile, seguire le indicazioni per installare drupal su SQLite)
  • Un account Telegram

Setup

Installeremo drupal mediante un template Composer (per maggiori informazioni vedi il progetto su GitHub). Eseguiamo i seguenti passaggi:

  1. Dopo essersi spostati, da terminale, con cd nome-cartella, eseguiamo il seguente comando: composer create-project drupal-composer/drupal-project:8.x-dev drupalgram --stability dev --no-interaction --prefer-dist
  2. Procedere quindi con la creazione del database e l'installazione, con profilo Standard, di Drupal 8
  3. Installare Telegram Bot SDK con il seguente comando (lanciato all'interno della cartella drupalgram): composer require irazasyed/telegram-bot-sdk ^2.0

Creazione del bot Telegram

Per la creazione di un bot telegram i passi da seguire sono davvero pochi e semplici: basta, infatti, aggiungere ai propri contatti telegram un bot, BotFather, messo a disposizione dal team di sviluppo di telegram, che ci guiderà nella creazione del nostro bot. Avviando la chat con BotFather è sufficiente:

  1. digitare il comando /newbot
  2. digitare il nome che vogliamo dare al bot
  3. digitare un username (che termini col suffisso “_bot”, es: ilmioprimo_bot)

Al termine di questa procedura BotFather ci notificherà l’avvenuta creazione ed il token di accesso alle API HTTP (mettiamolo da parte, ci servirà in seguito!).

Il nostro chat_id

Per poterci inviare messaggi su telegram, sarà necessario ottenere il nostro chat_id. È possibile ottenerlo velocemente aggiungendo il bot @get_id_bot e inviandogli il comando /my_id. Mettiamo da parte il "Your Chat ID"!

Creazione del modulo drupalgram

Come prima cosa, creiamo, se non l'abbiamo ancora, la cartella custom all'interno di drupalgram/web/modules con al suo interno i 2 file drupalgram.info.yml e drupalgram.module, come da screenshot:

Come integrare le Telegram Bot API in Drupal 8 (Parte 1)

Il file drupalgram.info.yml conterrà quanto segue:

name: drupalgram
type: module
description: Embed Telegram Bot Api into Drupal 8
core: 8.x
package: Custom

Attiviamolo.

Creazione del Servizio TelegramAPI

Una delle grandi novità di Drupal 8 è quella di aver integrato nel core buona parte del framework Symfony dal quale eredita anche il concetto di servizio. Nella documentazione di Symfony, viene definito come segue:

Un servizio è un qualsiasi oggetto PHP che esegue un certo compito “globale”. Si tratta di un nome volutamente generico che in informatica si usa per descrivere oggetti creati per uno scopo specifico (es: l’invio di email)

Per esempio Drupal 8 ha definito svariati servizi come: logger (per il db logging), plugin.manager.mail(per l'invio di mail), ecc... Sempre Symfony:

Ogni servizio presente all’interno della nostra app risiede all’interno di un oggetto molto speciale chiamato services container. Questo permette di standardizzare il modo con il quale gli oggetti vengono costruiti...

Non mi soffermerò ulteriormente sul concetto di service e service container, per un approfondimento vi rimando all'articolo Come utilizzare il Service Container in Drupal 8.

Creiamo il servizio TelegramAPI:

All'interno della cartella del nostro modulo (./drupalgram) creiamo il file drupalgram.services.yml con al suo interno la seguente definizione:

services:
  drupalgram.telegram_api:
    class: Drupal\drupalgram\Services\TelegramAPI\TelegramAPI

La riga 1. indica a Drupal che ad essa segue una lista di definizione di servizi. La riga 2., "drupalgram.telegram_api", definisce il nome del servizio, quello che useremo per richiamarlo con:

  <?php
    ...
    $telegramService = \Drupal::service('drupalgram.telegram_api');
    ...
  ?>

La riga 3., invece, indica a Drupal (che usa lo standard PSR-4 per l'autoloading) il path della classe corrispondente al servizio.

All'interno della cartella del nostro modulo (./drupalgram) creiamo la cartella src, al suo interno ancora la cartella Services e infine creiamo in quest'ultima la cartella TelegramAPI come da screenshot:

Come integrare le Telegram Bot API in Drupal 8 (Parte 1)

Risiederà qui, infine, il file TelegramAPI.php con all'interno la classe che definirà il nostro servizio. Per ora si limiterà ad inviarci un messaggio su telegram nel momento in cui visiteremo un path specifico (lo vedremo subito dopo la definizione del servizio).

<?php
 
namespace Drupal\drupalgram\Services\TelegramAPI;
use Telegram\Bot\Api;
 
// All'inizio dell'articolo ci siamo appuntati il token che
// @botfather ci ha fornito. Per ora lo hard-codiamo
// all'interno di una costante (brutto brutto). Nella parte
// seconda, quando definiremo il blocco con form, sposteremo
// in configurazione questo valore.
define('TELEGRAM_TOKEN', '******************************');
// Lo stesso vale per il nostro Chat ID (quello ottenuto
// tramite @get_id_bot).
define('TELEGRAM_CHAT_ID', '********');
 
/**
 * Class TelegramAPI
 *
 * La classe TelegramAPI implementerà le funzioni che
 * richiameranno le API del Telegram Bot API SDK
 */
class TelegramAPI {
  // Proprietà che conterrà l'istanza dell'oggetto Api.
  private $telegram;
 
  function __construct() {
    $this->telegram = new Api(TELEGRAM_TOKEN);
  }
 
  /**
  * Il seguente metodo sarà quello che si occuperà di recapitarci
  * il messaggio su telegram!
  *
  * Il parametro $message conterrà il testo da inviarci
  * Il parametro $parse_mode si riferisce alla possibilità di
  * passare del testo formattato secondo le regole del linguaggio
  * di markup Markdown
  */
  public function sendMessage($message, $parse_mode = 'MARKDOWN') {
    $this->telegram->sendMessage([
      'chat_id' => TELEGRAM_CHAT_ID,
      'text' => $message,
      'parse_mode' => $parse_mode,
    ]);
  }
 
  /**
   * Il metodo seguente verrà usato, solo nella prima parte di
   * questa serie di articoli, per inviare un messaggio nel
   * momento in cui verrà seguita la rotta
   * /drupalgram/send-message/<messaggio>
   */
  public function sendMessageRoute($message) {
    $this->sendMessage($message);
    return [
      '#markup' => 'Messaggio inviato! Forse... :|',
    ];
  }
}

Passiamo ora alla definizione di una rotta (un URI) alla visita del quale ci verrà recapitato un messaggio. Per la costruzione della rotta, bisogna definirla, come al solito, all'interno di un file .routing.yml (nella root del modulo, ./drupalgram), nel nostro caso drupalgram.routing.yml, come da screenshot:  

Come integrare le Telegram Bot API in Drupal 8 (Parte 1)

Con all'interno il seguente contenuto:

drupalgram.sendMessage:
  path: '/drupalgram/send-message/{message}'
  defaults:
    _controller: 'drupalgram.telegram_api:sendMessageRoute'
  requirements:
    _permission: 'access content'
  options:
    parameters:
      message:
        type: String

La riga 1. assegna alla nostra rotta un nome. La 2. definisce qual è il path a cui corrisponde la rotta; da notare che tra le parentesi graffe stiamo definendo il parametro che useremo come valore del messaggio da inviare (alla riga 7. definiamo che il parametro message è di tipo stringa). La riga 4., invece, indica quale metodo eseguire nel momento in cui si segue la rotta. Come potrete notare, abbiamo usato, il nome del servizio seguito da un suo metodo, in questo caso quello che fa Drupal è:

  1. Converte il nome del servizio nel suo path (PSR-4) ovvero: Drupal\drupalgram\Services\TelegramAPI\TelegramAPI
  2. Esegue il metodo sendMessageRoute() classe telegramAPI

Ora abbiamo, più o meno, tutto ciò che ci serve per testare il nostro servizio. Nel caso qualcosa non funzionasse, verificate di aver disabilitato il caching, o comunque pulite le cache.

L'URL da seguire, per attivare il metodo sendMessageRoute associato alla rotta, è: http://IL-VOSTRO-HOST/drupalgram/send-message/IL-TESTO-DEL-MESSAGGIO-DA-...

Se avete incollato il testo dell'esempio, riceverete su telegram un messaggio dal nostro bot che ci dice: "IL-TESTO-DEL-MESSAGGIO-DA-INVIARE" (Il senso del doppio underscore, è per indicare lo stile corsivo del testo) e sulla pagina Drupal dovreste vedere come contenuto il testo: "Messaggio inviato! Forse... :|"

Nel prossimo articolo

Nel prossimo articolo ci occuperemo di costruire un custom block ed una custom form. Usando il servizio TelegramAPI, ad ogni submit della form, il bot ci notificherà del contatto.