12 Settembre, 2018 | Di

Twilio - Chiamate ed SMS per sviluppatori

Twilio - Chiamate ed SMS per sviluppatori

In questo articolo vedremo insieme cos’è Twilio, quali servizi offre e come iniziare ad usare la sua piattaforma per realizzare un piccolo monitoraggio di una pagina web.  

Cos’è Twilio?

Twilio è una piattaforma online in grado di fornire numerosi servizi legati all’ambito della comunicazione (sms, mms, chiamate…).

Nato nel 2007, negli ultimi anni la sua popolarità è cresciuta esponenzialmente sia grazie alle società che hanno scelto di avvalersi dei suoi servizi (Uber e Netflix in primis), sia soprattutto grazie alle sue scelte tecnologiche (il debito tecnologico per poter iniziare a sfruttare le sue potenzialità è ridotto al minimo) e di comunicazione (sfruttando numerosi hackathon riescono a sfruttare il Platform evangelism per diffondere la loro soluzione).

Per questi motivi, e sicuramente per molti altri, è stata riconosciuta come una delle 10 società più innovative del 2007.

I servizi offerti vantano la possibilità di essere erogati globalmente e vanno dall’invio di sms alle chiamate vocali, dalla verifica di una identità telefonica alla registrazione di numeri virtuali.

Primo passo: registrazione su Twilio

Per prima cosa è necessario registrarsi al servizio.

Partendo dalla Homepage di Twilio possiamo cliccare sul pulsante “Get a free API key” che ci permette di iniziare a “giocare” con buona parte delle funzionalità.

Per accedere alla console (o dashboard) da dove potremo gestire tutte le nostre risorse ed i nostri progetti dovremo verificare il nostro account via sms. Al termine della registrazione, seguendo le istruzioni che ci verranno date sullo schermo saremo pronti ad usare il servizio.

Il Trial-Account appena creato avrà a disposizione crediti per un valore di $15. Sufficienti a farci provare buona parte delle funzionalità offerte.

Twilio - Chiamate ed SMS per sviluppatori

Secondo passo: creazione di un numero

Prima di fare una qualsiasi telefonata, sarà necessario creare un numero di telefono in grado di effettuarla.

Dal menu a scomparsa selezioniamo “Phone Numbers” e cerchiamo un numero disponibile (in Italia) con la possibilità di eseguire chiamate vocali, spuntando la casella “Voice” vicino all’etichetta “Capabilities”.

Twilio - Chiamate ed SMS per sviluppatori

Dopo aver inviato il modulo, avremo a disposizione una lista di tutti i numeri di telefono disponibili per il nostro paese (Italia) con le caratteristiche richieste (chiamate Vocali).

Twilio - Chiamate ed SMS per sviluppatori

Scegliamo un numero che ci piace (per questioni legali un numero italiano è acquistabile previa registrazione aggiuntiva di altri dati. Per comodità registreremo un numero americano che non ha bisogno di altre informazioni).

Con un popup riceveremo conferma della registrazione avvenuta e verremo indirizzati verso la pagina di gestione del nostro nuovo numero di telefono.

Nota: Una peculiarità non indifferente del servizio Twilio è il prezzo. Come si può vedere per l’utilizzo per un mese di un numero di telefono è davvero irrisorio: 1 dollaro.

Terzo passo: programmable api

Dopo pochi minuti possiamo già procedere con la scrittura di un piccolo script per testare il nuovo servizio attivato.

Per Twilio sono state scritte centinaia di librerie, nei più diversi linguaggi.

Per la nostra prova useremo una libreria scritta in golang chiamata “gotwilio” che si definisce “The start of a library for Twilio. Gotwilio supports making voice calls and sending text messages.”.

➜ $ go get "github.com/sfreiberg/gotwilio"

Dopo aver installato gotwilio, usiamo l’esempio fornito per testare:

package main
 
import (
"log"
 
"github.com/sfreiberg/gotwilio"
)
 
func main() {
accountSid := "<Twilio-accountSid>"
authToken := "<Twilio-authToken>"
twilio := gotwilio.NewTwilioClient(accountSid, authToken)
 
from :="<Twilio-number>"
to := "<my-number>"
callbackParams := gotwilio.NewCallbackParameters("http://demo.twilio.com/docs/voice.xml")
_, exception, err := twilio.CallWithUrlCallbacks(from, to, callbackParams)
if exception != nil {
log.Fatal(*exception)
}
if err != nil {
log.Fatal(err)
}
 
}

Nota: per l’esempio è molto più semplice ed utile scrivere le nostre credenziali direttamente nel codice. In produzione (o prima di condividerle il codice su un repository) è buona norma spostare tali segreti in variabili di sistema per mantenerle segrete.

Come possiamo vedere dal codice, le API di Twilio hanno bisogno di alcuni parametri fondamentali:

accountSid e authToken: le credenziali di accesso per autenticarsi a Twilio

from e to: i numeri di telefono del chiamante e del ricevente.

Nota: se, come noi, si usa un account di prova di Twilio sarà possibile eseguire chiamate solamente verso il numero di telefono comunicato in fase di registrazione o altri numeri verificati dal servizio. È possibile aggiungerne tramite la console “Verified Caller IDs”.

callbackParams: il parametro di callback punta ad un TwiML. TwiML è un linguaggio (XML) usato da Twilio per gestire un evento, come ad esempio una chiamata telefonica. Questo TwiML in particolare dopo aver chiamato il numero selezionato, risponde con un messaggio ed eseguendo un mp3 specifico “classic.mp”.

Esempio di file TwiML:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
   <Say voice="alice">Thanks for trying our documentation. Enjoy!</Say>
   <Play>http://demo.twilio.com/docs/classic.mp3</Play>
</Response>

Sostituiamo i numeri di telefono e le credenziali con le nostre, ben visibili sulla nostra dashboard:

Twilio - Chiamate ed SMS per sviluppatori

Salviamo ed eseguiamo il nostro programma:

➜ $ go run main.go
➜ $

Nota: se dovesse comparire un errore, Twilio fornisce oltre al codice dell’errore anche una spiegazione chiara ed esaustiva del problema. Nel nostro caso alla prima esecuzione ci è stato segnalato di dover abilitare le chiamate internazionali al link: https://www.twilio.com/console/voice/calls/geo-permissions

Nessun messaggio di errore.

Ora aspettiamo un attimo e… rispondiamo alla chiamata.

Passo Bonus: integrazione

Proviamo ora ad applicare quanto imparato ad un esempio più concreto. Si tratterà solo di poche righe di codice “giocattolo”, ma ci permetterà di vedere una applicazione pseudo-reale.

Voglio realizzare un piccolo script di controllo per il mio sito: quando il sito non sarà raggiungibile, il sistema dovrà chiamarmi per avvertirmi (ovviamente una volta sola).

Per questo esempio ci serviranno due componenti:

  1. Lato server: il mio sito, che andrà online e che, terminandolo, andrà offline

  2. Lato client: lo script che controllerà il server e ci avviserà di conseguenza

Server: il mio sito

package main
 
import (
"net/http"
)
 
func main() {
http.Handle("/", http.FileServer(http.Dir("./")))
http.ListenAndServe(":3000", nil)
}

Ed eseguiamo:

➜  $ go run main.go

Quando dovremo terminarlo, basterà fermarne l’esecuzione (ctrl+c).

Client: lo script che controllerà il server

package main
 
import (
"log"
"net"
"time"
 
"github.com/sfreiberg/gotwilio"
)
 
// isCall variable check if a call is not already started.
var (
isNotCall = true
)
 
// main function
func main() {
// check every 10 seconds.
doEvery(10*time.Second, checkOnline)
}
 
// doEvery accept the time duration and the function to exec
func doEvery(d time.Duration, f func(time.Time)) {
for x := range time.Tick(d) {
f(x)
}
}
 
// checOnline open a tcp connection on localhost:3000 and start a call() if
// the site is unreachable.
func checkOnline(t time.Time) {
var status string
 
timeout := time.Duration(5 * time.Second)
 
_, err := net.DialTimeout("tcp", "localhost:3000", timeout)
 
// If site is unreachable
if err != nil {
status = "DOWN"
log.Println("Site unreachable, error: ", err)
 
// Call only one time
if isCall {
isNotCall = false
log.Println("Call started...")
call()
}
 
} else {
status = "UP"
}
 
// Print Status.
log.Printf("Site is: %s\n", status)
 
}
 
//call function calls the Twilio apis
func call() {
accountSid := "<Twilio-accountSid>"
authToken := "<Twilio-authToken>"
twilio := gotwilio.NewTwilioClient(accountSid, authToken)
 
from := "<Twilio-number>"
to := "<my-number>"
callbackParams := gotwilio.NewCallbackParameters("http://demo.twilio.com/docs/voice.xml")
_, exception, err := twilio.CallWithUrlCallbacks(from, to, callbackParams)
if exception != nil {
log.Fatal(*exception)
}
if err != nil {
log.Fatal(err)
}
 
}

Ed eseguiamo:

➜  $ go run main.go

Dopo qualche secondo dovremo iniziare a vedere alcuni messaggi positivi:

2018/03/11 15:06:29 Site is: UP 2018/03/11 15:06:39 Site is: UP …

Ma appena termineremo l’esecuzione del nostro server, ecco il messaggio:

2018/03/11 15:06:29 Site is: UP 2018/03/11 15:06:39 Site is: UP 2018/03/11 15:06:49 Site unreachable, error:  dial tcp 127.0.0.1:3000: connect: connection refused 2018/03/11 15:06:49 Call started...

E riceveremo la telefonata di esempio scoprendo così che il sito è andato offline.