4 settembre 2018

tutorial: come utilizzare e cosa è possibile fare ora con le instagram api per creare app o bot su raspberry pi


Benvenuti!
Questo tutorial vi fornirà una panoramica sulle Instagram API, lo stato attuale delle cose e come esse possano essere utilizzate via python su Raspberry Pi per recuperare contenuti presenti sul social network.

Nota: il presente articolo contiene una infarinatura generale ed alcuni dettagli sono stati tralasciati. Inoltre Instagram sta lentamente abbandonando le API in favore delle Graph API, come analizzato in seguito. Se volete approfondire, non esitate a lasciare un commento o a contattarmi sui canali social.

Prima di addentrarci, vi riporto il video di supporto a questa guida che ho pubblicato sul mio canale YouTube:


Inoltre vi segnalo che nella pagina dedicata troverete tutti i tutorial da me pubblicati.


1. l'attrezzatura minima per iniziare


Per adoperare le API Instagram occorrono:
  • un Raspberry Pi qualsiasi (in questo tutorial viene utilizzato il modello Zero) + una microSD + un alimentatore (da almeno 2.1A)
  • Raspbian OS Lite
  • un PC per accedere via SSH al pi e sviluppare
  • una connessione ad Internet per dialogare con il social network
Per quanto riguarda il primo punto non occorre altro: il Raspberry Pi verrà acceduto via SSH per la configurazione generale. Sarà invece indispensabile avere un alimentatore che eroghi in uscita almeno 2.1A.
Raspbian OS Lite è probabilmente la scelta migliore poiché è un sistema leggero, consuma poche risorse ed ha la possibilità di farci installare dai repository tutto il necessario.
Il PC sarà lo strumento con cui svilupperemo le applicazioni che saranno poi eseguite sul pi.
La connessione ad internet serve perché chiaramente si dovrà interagire con Instagram.


2. developer account


Per poter interagire con Instagram tramite App o BOT esterni è necessaria la creazione di una o più Client App. Queste applicazioni devono essere utilizzate dagli utenti del social network (cioè essi devono autorizzarle ad accedere ai propri dati) e tramite esse le App o BOT esterni possono accedere alle API esposte.
Il primo passo quindi è quello di accedere alla URL https://www.instagram.com/developer/ con il proprio utente (o crearne uno nuovo) e seguire il wizard di creazione di una nuova Client App.

Ogni Client App deve avere un nome che rispetti le regole imposte da Instagram stesso, quindi non deve contenere parole come IG, insta, gram o similari; deve esserci una descrizione di che cosa faccia; deve essere abbinata ad almeno una URL valida verso cui Instagram possa redirezionare le richieste; e deve essere specificata una email che il social network possa utilizzare per inviare informazioni importanti relative alla Client App stessa. In più ci sono delle opzioni di sicurezza aggiuntive che possono essere abilitate o meno a seconda delle necessità.

Nota: una volta registrata una Client App, saranno assegnati un Client ID, un Client Secret ed uno stato. Il Client Secret deve ovviamente rimanere nascosto e non deve essere comunicato a terzi per nessun motivo. In ogni caso esso può comunque essere rigenerato ogni volta che si vuole.

Le applicazioni in partenza hanno tutte uno stato Sandbox cioè sono limitate e possono essere utilizzate da al più 10 utenti, i quali devono essere invitati esplicitamente dal creatore della Client App. Inoltre, per far sì che il social network accetti come pubblica la Client App appena creata occorrerà specificare un nome di azienda, un contatto email ed indicare la URL a cui fa riferimento la privacy policy. Per gli scopi di questo tutorial, e se non si vuole diffondere l'app come pubblica, è possibile ignorare tali dettagli.


3. accedere alle API


Una volta creata almeno una Client App, ci sono due possibili approcci per sfruttarla ed accedere alle Instagram API:
  1. utilizzare in modo diretto gli Endpoints delle API con tutte le operazioni possibili attorno cui sviluppare la propria App o BOT
  2. ciò che è trattato in questa guida, utilizzare una libreria open-source già esistente e scritta in python (quindi perfetta per Raspberry Pi) che fa da client alle REST e Seach API del social network
Raspbian OS Lite ha di base tutto l'occorrente per poter sfruttare la suddetta libreria ed integrarla nel codice della propria applicazione. Sarà sufficiente lanciare il comando pip install python-instagram per scaricare la libreria, e in mancanza di pip basterà prelevarlo dai repository di Raspbian con il comando sudo apt-get install python-pip che lo installerà.

Nota 1: ad oggi la libreria non è più mantenuta, quindi nel qual caso Instagram dovesse cambiare qualcosa (e su questo si veda più avanti) essa potrebbe non funzionare più correttamente, ma per gli scopi di questa guida si può continuare ad utilizzarla perché è davvero semplice da integrare ed utilizzare.

Nota 2: prima di lanciarsi nello sviluppo, occorre eseguire un importantissimo passaggio! Una volta creata una Client App su Instagram, si avrà il Client ID ed il Client Secret che la identificano. Ma queste due chiavi da sole non permettono più l'utilizzo delle API di Instragram. Tali API, infatti, sono state modificate più e più volte nel corso del tempo, ed ora per funzionare richiedono necessariamente la presenza di un access_token.
L'access_token è un ID alfanumerico associato ad ogni utente che ha accettato l'utilizzo dell'app e sta eseguendo tramite essa delle richieste al social network. Quindi è indispensabile generare fin da subito almeno un access_token, altrimenti sarà impossibile proseguire. Il token, come detto, viene creato quando un utente accetta di utilizzare una app e occorrerebbe tenerlo segreto.

La libreria permette di generare velocemente l'access_token associato all'utente con cui si utilizza Instagram, semplicemente usando il codice contenuto all'interno dello script get_access_token.py presente nel repository GitHub del progetto. Questo script chiederà Client ID e Client Secret della Client App Instagram creata poc'anzi, ed una delle URL che sono state indicate come valide nella configurazione dell'app stessa. Questa URL sarà utilizzata da Instagram per rispondere alla richiesta di get_access_token, e verrà fatto inviando proprio a tale URL un CODE che deve essere utilizzato per prelevare l'access_token.
Tale procedura "contorta" consente agli sviluppatori di App e BOT Instagram di immagazzinare tutti gli access_token degli utenti che hanno acconsentito all'utilizzare della rispettiva app, senza che tali token viaggino in chiaro sul web. Il social network girerà la richiesta di get_access_token alla URL specificata (presumibilmente una web app in grado di sfruttare il CODE per recuperare il relativo access_token con una successiva richiesta server side).

Lo script get_access_token.py è in grado di svolgere tutto questo lavoro: durante la sua esecuzione mostrerà un link che è necessario accedere dal browser web per catturare il CODE generato da Instagram, quindi tornare sullo script inserendolo ed ottenendo indietro il bramato access_token.

Nota: c'è un piccolo bug all'interno della libreria, probabilmente dovuto a dei cambiamenti effettuati da Instagram nel corso del tempo. Per risolverlo va modificato il file oauth2.py della libreria (potete trovarlo con un locate oauth2.py ma dovrebbe essere in /home/pi/.local/lib/python2.7/site-packages/instagram/oauth2.py) alla linea che contiene il seguente codice:

response, content = http_object.request(url, method="POST", body=data)

Essa va sostituita con le seguenti due righe:

headers = {"Content-Type": "application/x-www-form-urlencoded"}
response, content = http_object.request(url, method="POST", body=data, headers=headers)

Fatto ciò sarà possibile generare l'access_token, il quale deve essere salvato perché andrà aggiunto a tutte le chiamate alle API.

Nota: gli access_token non sono validi a vita. In generale non vengono modificati, ma potrebbero scadere al cambio password da parte dell'utente oppure se Instagram decidesse per qualche motivo di generarne di nuovi o, ancora, se un utente dovesse annullare l'iscrizione all'app. In tali casi le chiamate alle API restituiranno uno specifico errore (OAuthAccessTokenException) e quindi occorrerà richiedere un nuovo access_token da capo.


4. interrogare le API


Sulla pagina GitHub della libreria è possibile dare uno sguardo alle possibili operazioni per ogni API Endpoint presente, ma occorre fare attenzione poiché, come detto, la libreria non è più mantenuta ed alcuni dei comandi riportati non funzionano più per via delle restrizioni che Instagram ha introdotto...

Nota: ci sono altri bug noti (oltre a quello visto in precedenza), ad esempio se una foto non ha commenti il recupero della stessa manderà in crash la libreria. Per risolvere questo problema si può cercare il file models.py (come in precedenza con un locate ma dovrebbe essere in /home/pi/.local/lib/python2.7/site-packages/instagram/models.py) e trovare le linee seguenti:

for comment in entry['comments']['data']:
    new_media.comments.append(Comment.object_from_dictionary(comment))

Quindi sostituirle con il seguente blocco di codice:

if "data" in entry["comments"]:
    for comment in entry['comments']['data']:
        new_media.comments.append(Comment.object_from_dictionary(comment))

Fatta questa modifica non dovrebbero verificarsi più problemi di sorta.


A questo punto è possibile testare uno dei tanti comandi messi a disposizione dalla libreria e vedere le risposte. Si può creare un file di test in cui inserire il codice di prova.

Nota: non è possibile chiamare il file come instagram.py altrimenti la libreria non funzionerà.


Un primo passo può essere quello di recuperare le ultime immagini pubblicate dall'utente del quale si conosce l'access_token (presumibilmente il proprio account). Il seguente codice fa proprio ciò:

from instagram.client import InstagramAPI

access_token = "ACCESS_TOKEN"
client_secret = "CLIENT_SECRET"

api = InstagramAPI(access_token=access_token, client_secret=client_secret)

recent_media, next_ = api.user_recent_media()

for media in recent_media:
    print media.images['standard_resolution'].url


Eseguendo il codice con il comando python instagram_example.py (se è questo il nome utilizzato per il programma di esempio) ecco che appariranno a video le URL associate alle ultime immagini caricate dall'utente corrispondente all'access_token specificato. Aprendo le URL sul browser si può rapidamente verificare la correttezza del risultato.

Tramite la libreria e quindi le API di Instagram sarà possibile accedere ai like dell'utente, alle sue foto, ai suoi commenti e quant'altro. Insomma operare sul social network al posto suo ed in base ai permessi che lui ha accettato a fornire. Un esempio molto semplice come quello precedente serve a capire quali siano i primi passi per iniziare ad accedere alle API, quali siano quelle offerte, e cosa sia possibile fare. Una volta ottenute le informazioni desiderate, si può iniziare a costruire la logica attorno ad esse che abbia senso per ciò che si vuole realizzare.


5. API Private "morenti" vs Graph API


Instagram ha in passato modificato il funzionamento delle proprie API ed in futuro è stato pianificato un nuovo aggiornamento. Al momento le API esposte e la libreria sembrano ancora funzionare, ma il social network sta spostando tutta la logica verso l'uso delle Graph API, seguendo il modello imposto da Facebook. Nel giro di 1-2 anni le cose cambieranno sensibilmente e le poche operazioni ad oggi ancora disponibili non funzioneranno più, così come è già accaduto in passato per gran parte delle funzioni che esistevano (e che la libreria tenta senza successo di eseguire ancora oggi).

Volendo è già possibile utilizzare le Graph API, anche se al momento sono limitate ad i soli account Business e presto dovrebbero essere aperte a tutti. Queste API sono molto più potenti di quelle Private, infatti consentono di caricare immagini, cercare nei profili pubblici, fare una marea di operazioni in più... Ma bisognerà attendere il 2019 (o chissà quando) affinché vengano rese disponibili per tutti, e con maggiori funzionalità.
In alternativa esistono metodi più o meno "creativi" assolutamente non ufficiali e che non interagiscono direttamente tramite API con il social network ma simulano chiamate tradizionali per recuperare i contenuti; alternative che possono essere bloccate in qualsiasi momento e che sono altamente sconsigliate poiché possono portare al ban dell'account che si utilizza per eseguirle.


6. conclusioni ed ultime note


Lo scopo di questo tutorial è quello di far capire quale è la logica di funzionamento generale delle Instagram API, per lo meno di quello che ne rimane ad oggi, per avere un input per la creazione di App o BOT in python in esecuzione su Raspberry Pi che sfruttino i dati estratti dal social network.

Una volta capito come interagire con le API sarà possibile creare tante tipologie di App, ad esempio un BOT che recuperi le foto recenti dell'utente e le salvi poi da qualche altra parte (magari le ripubblichi su Twitter o altri social); oppure, avendo più di un utente abilitato (quindi avendo più access_token) si potrebbero raggruppare in automatico tutte le foto associate ad un certo tag oppure scattate in un determinato luogo (magari quando si è tutti assieme in vacanza). O ancora il pi potrebbe compiere determinate operazioni in seguito alla pubblicazione di una foto in un dato luogo od orario del giorno, e così via.

Purtroppo le API ad oggi non permettono di fare molte cose se non cercare contenuti già pubblicati e solo dagli utenti di cui si conoscano gli access_token. Per fare di più, come anticipato, sono necessarie le Graph API, le quali richiedono un profilo Facebook associato ad un account Instagram Business ed ogni App realizzata dovrà essere autorizzata esplicitamente dal social network.


Bene: come indicato ad inizio guida, alcuni aspetti sono stati lasciati in secondo piano, ma se siete interessati ad approfondirli non esitate a contattarmi nei commenti di questo tutorial o del video ad esso correlato, oppure sui canali social!

Spero che la guida vi sia stata utile. Al prossimo tutorial!

Nessun commento:

Posta un commento