#OpenData Francavilla – il codice sorgente del Bot Telegram
Conoscete già la storia, molto bella, di alternanza scuola lavoro per il Comune di Francavilla Fontana, realizzata dall’Istituto Fermi e coordinata dai professori Giorgia Martina e Gianluca Pisani, in sinergia con il responsabile della Transizione Digitale del Comune, Dott. Francesco Taurisano che ha portato alla realizzazione e popolamento di dataset, per il portale dati.comune.francavillafontana.br.it . Caso replicabile e che è il simbolo di una “Buona Scuola con un Buona Amministrazione“.
Come chicca finale, i bravissimi ragazzi che in queste ore stanno studiando per diplomarsi, hanno realizzato un automa dimostrativo su Telegram. I famosi Bot.
Aprite Telegram e cercate opendatafrancavillabot o OpenDataFrancavillaFontana.
Vi ripropongo il codice sorgente usato (ricordate la licenza che è la CC-BY-SA). Per la procedura di interoperabilità e interfacciamento vi rimando a questo post
Dopo aver richiesto la registrazione a @botfather del vostro bot, vi verrà inviato un TOKEN. Inseritelo dove indicato:
API_TOKEN = ”; // INSERIRE IL TOKEN
function Myindexof(s,text)
{
var lengths = s.length;
var lengtht = text.length;
for (var i = 0;i < lengths – lengtht + 1;i++)
{
if (s.substring(i,lengtht + i) == text)
return i;
}
return -1;
}
function doGetDataset(ID,GID,CAT)
{
var ss = SpreadsheetApp.openById(ID);
var metaSheet = ss.getSheetByName(GID);
var count=metaSheet.getLastRow();
var RSSFeedTitle=”;
for (var i=1; i <= count; i++) { if (i>1) RSSFeedTitle += metaSheet.getRange(i,1).getValue()+’ – *Clicca:* /’+CAT+”+i+’\n’;
}
return RSSFeedTitle;
}
function doGetDatasetDaeElenco(ID,GID,CAT)
{
var ss = SpreadsheetApp.openById(ID);
var metaSheet = ss.getSheetByName(GID);
var count=metaSheet.getLastRow();
var RSSFeedTitle=”;
for (var i=1; i <= count; i++) { if (i>1) RSSFeedTitle += metaSheet.getRange(i,2).getValue()+’-‘+metaSheet.getRange(i,3).getValue()+’ – *Clicca:* /’+CAT+”+i+’\n’;
}
return RSSFeedTitle;
}
function doGetDatasetRicettive(ID,GID,ROW)
{
var ss = SpreadsheetApp.openById(ID);
var metaSheet = ss.getSheetByName(GID);
var RSSFeedTitle=”;
RSSFeedTitle += ‘*Nome: *’+metaSheet.getRange(ROW,1).getValue()+’\n’;
RSSFeedTitle += ‘*Tipologia: *’+metaSheet.getRange(ROW,2).getValue()+’\n’;
RSSFeedTitle += ‘*Ubicazione: *’+metaSheet.getRange(ROW,3).getValue()+’\n’;
if (metaSheet.getRange(ROW,4).getValue() !=””) RSSFeedTitle += ‘*Civico: *’+metaSheet.getRange(ROW,4).getValue()+’\n’;
RSSFeedTitle += ‘*Posti Letto: *’+metaSheet.getRange(ROW,5).getValue()+’\n’;
RSSFeedTitle += ‘*Mappa: *http://www.openstreetmap.org/#map=19/’+metaSheet.getRange(ROW,6).getValue()+’/’+metaSheet.getRange(ROW,7).getValue()+’\n’;
return RSSFeedTitle;
}
function doGetDatasetDae(ID,GID,ROW)
{
var ss = SpreadsheetApp.openById(ID);
var metaSheet = ss.getSheetByName(GID);
var lun=metaSheet.getRange(ROW,8).getValue().replace(‘_’,’-‘);
var mar=metaSheet.getRange(ROW,9).getValue().replace(‘_’,’-‘);
var merc=metaSheet.getRange(ROW,10).getValue().replace(‘_’,’-‘);
var giov=metaSheet.getRange(ROW,11).getValue().replace(‘_’,’-‘);
var ven=metaSheet.getRange(ROW,12).getValue().replace(‘_’,’-‘);
var sab=metaSheet.getRange(ROW,13).getValue().replace(‘_’,’-‘);
var dom=metaSheet.getRange(ROW,14).getValue().replace(‘_’,’-‘);
var RSSFeedTitle=”;
RSSFeedTitle += ‘*Plesso: *’+metaSheet.getRange(ROW,2).getValue()+’\n’;
RSSFeedTitle += ‘*Proprietà: *’+metaSheet.getRange(ROW,3).getValue()+’\n’;
RSSFeedTitle += ‘*Indirizzo: *’+metaSheet.getRange(ROW,4).getValue()+’ ‘+metaSheet.getRange(ROW,5).getValue()+’, ‘+metaSheet.getRange(ROW,6).getValue()+’\n’;
RSSFeedTitle += ‘*Lunedi: *’+lun+’\n’;
RSSFeedTitle += ‘*Martedi: *’+mar+’\n’;
RSSFeedTitle += ‘*Mercoledi: *’+merc+’\n’;
RSSFeedTitle += ‘*Giovedi: *’+giov+’\n’;
RSSFeedTitle += ‘*Venerdi: *’+ven+’\n’;
RSSFeedTitle += ‘*Sabato: *’+sab+’\n’;
RSSFeedTitle += ‘*Domenica: *’+dom+’\n’;
RSSFeedTitle += ‘*Mappa: *http://www.openstreetmap.org/#map=19/’+metaSheet.getRange(ROW,15).getValue()+’/’+metaSheet.getRange(ROW,16).getValue()+’\n’;
return RSSFeedTitle;
}
function doGet() {
var ss = SpreadsheetApp.openById(ID_SPREADSHEET);
var metaSheet = ss.getSheetByName(‘Foglio1′);
var RSSFeedTitle=”;
for (var i=1; i < 11; i++) { RSSFeedTitle += metaSheet.getRange(i,getRandomArbitrary(2,7)).getValue()+’ ‘; } return RSSFeedTitle; } function info(chatid){ var keyboard = []; var payload = { ‘method’: ‘sendMessage’, ‘chat_id’: String(chatid), ‘text’: ‘clicca /start per istruzioni’, ‘reply_markup’: JSON.stringify({ inline_keyboard: keyboard }) } var data = { “method”: “post”, “payload”: payload, } // Replace with your token UrlFetchApp.fetch(‘https://api.telegram.org/bot’ + API_TOKEN + ‘/’, data); } function doPost(e) { var update = JSON.parse(e.postData.contents); // Replace with your token // Make sure this is update is a type message if (update.hasOwnProperty(‘message’)) { var msg = update.message; var chatId = msg.chat.id; // Make sure the update is a command. if (msg.hasOwnProperty(‘entities’) && msg.entities[0].type == ‘bot_command’) { if (msg.text == ‘/info’ || msg.text == ‘/start’ || msg.text == ‘info’) { var quote = ‘Benvenuto nell\’automa dimostrativo che utilizza i dati aperti del Comune di Francavilla Fontana (dati.comune.francavillafontana.br.it) .\nQuesto BOT è stato realizzato all\’interno del progetto di Alternanza Scuola Lavoro tra l\’Ente, l\’Istituto Fermi e la società Ricerca e Sviluppo.\nPuoi digitare alcuni comandi:\n/ricettive (per avere l\’elenco delle strutture ricettive)\n/dae (per i defibrillatori)\n/spese seguito da cosa vuoi cercare come spese correnti (esempio /spese carta).\nDigitando /start puoi riavere questo messaggio’; var payload = { ‘method’: ‘sendMessage’, ‘chat_id’: String(chatId), ‘text’: quote, ‘parse_mode’: ‘Markdown’ } var data = { “method”: “post”, “payload”: payload } // Replace with your token UrlFetchApp.fetch(‘https://api.telegram.org/bot’ + API_TOKEN + ‘/’, data); } var messaggio=msg.text; if (messaggio.indexOf(“/ricettive”)>-1){
// if (msg.text == ‘/ricettive’) {
var newmsg=messaggio.replace(‘/ricettive’,”);
var cat=’ricettive’;
var key=’1oYmd88g_FWZ9hZDWvs6ERZxAflpAPDoCKYFX1E5rwaQ’;
var gid=’Foglio1′;
var cat=’ricettive’;
var text=doGetDataset(key,gid,cat);
if (newmsg !=””){
text=doGetDatasetRicettive(key,gid,newmsg);
}
var payload = {
‘method’: ‘sendMessage’,
‘chat_id’: String(chatId),
‘text’: text,
‘parse_mode’: ‘Markdown’,
‘disable_web_page_preview’:’TRUE’
}
var data = {
“method”: “post”,
“payload”: payload
}
UrlFetchApp.fetch(‘https://api.telegram.org/bot’ + API_TOKEN + ‘/’, data);
info(chatId);
}
var messaggio=msg.text;
if (messaggio.indexOf(“/dae”)>-1){
var newmsg=messaggio.replace(‘/dae’,”);
var key=’12v2TdW9AJOCS0ockf39KFYh3CApOVIx9ctcRak9vuEg’;
var gid=’Foglio1′;
var cat=’dae’;
var text=doGetDatasetDaeElenco(key,gid,cat);
if (newmsg !=””){
text=doGetDatasetDae(key,gid,newmsg);
}
var payload = {
‘method’: ‘sendMessage’,
‘chat_id’: String(chatId),
‘text’: text,
‘parse_mode’: ‘Markdown’,
‘disable_web_page_preview’:’TRUE’
}
var data = {
“method”: “post”,
“payload”: payload
}
UrlFetchApp.fetch(‘https://api.telegram.org/bot’ + API_TOKEN + ‘/’, data);
info(chatId);
}
var messaggio=msg.text;
if (messaggio.indexOf(‘/spese’) > -1) {
var quote =”;
var check=messaggio.replace(‘ ‘,”);
if (check== ‘/spese’ )
{
quote +=’Puoi cercare una spesa corrente digitando /spese descrizione della spesa.\nEsempio */spese carta*’;
}else
{
var tmp=messaggio.replace(‘/spese ‘,”);
var check=messaggio.replace(‘/spese’,”);
var messfinale=tmp.toUpperCase();
var url = ‘http://dati.comune.francavillafontana.br.it/dataset/c9a82c39-a47f-4c32-95f7-ee1ba7d8172e/resource/9d0de408-7038-41e4-8dd0-40efba10788a/download/spese.json’;
var data = UrlFetchApp.fetch(url);
var posts = JSON.parse(data);
for (var i=1;i<1517;i++) { if (Myindexof(posts.data[i][‘descrizione_codice’].toUpperCase(),messfinale) > -1)
{
var spese1=posts.data[i][‘imp_uscite_att’]/100;
var spese2=posts.data[i][‘importo_2017’]/100;
var spese3=posts.data[i][‘importo_2018’]/100;
if (posts.data[i][‘imp_uscite_att’]==null) spese1=’non presente’;
if (posts.data[i][‘importo_2017′]==null) spese2=’non presente’;
quote +=’\n’;
quote +=’*Descrizione:* ‘+posts.data[i][‘descrizione_codice’]+’\n*Codice SIOPE:* ‘+posts.data[i][‘codice_siope’]+’\n’;
quote += ‘*Importo progessivo mese precedente: *’+spese1+’\n’+’*Importo totale anno 2017:* ‘+spese2+’\n’+’*Importo totale anno 2018:* ‘+spese3;
quote +=’\n———‘;
}
}
}
var payload = {
‘method’: ‘sendMessage’,
‘chat_id’: String(chatId),
‘text’: quote,
‘parse_mode’: ‘Markdown’
}
var data = {
“method”: “post”,
“payload”: payload
}
UrlFetchApp.fetch(‘https://api.telegram.org/bot’ + API_TOKEN + ‘/’, data);
info(chatId);
}
}
}
}
Il codice permette di interrogare alcuni dataset. In particolare il dataset sulle strutture ricettive, quello delle spese correnti e quello per i defibrillatori.
Ogni funzione fa una query su un google sheet (con relativo gid o foglio) che è quello rilasciato sul portale opendata. Nel caso di /dae espone tutti i defibrillatori e poi facendo /daeX il sistema comprende che non vuole tutti i DAE ma solo il numero X. Per cui viene esposta solo la riga X. Idem per le strutture ricettive. Trovate il tutto nelle funzioni doGetDatasetDae, doGetDatasetDaeElenco , doGetDatasetRicettive etc
Per le spese correnti invece viene interrogato il json presente sul portale e viene richiesto di digitare /spese spesadacercare. Il sistema cancella /spese nel testo e cerca nel json “spesedacercare”.
Infine digitando /start appare il messaggio di benvenuto.
E’ un esempio semplice e banale ma replicabile in ogni pubblica amministrazione, senza necessità di server dedicati. Ovviamente ci vogliono gli OpenData prima :).
Non sapete da dove iniziare ad unire Scuola e PA? seguitevi il mio webinar e le slides
Buono studio.
Lic. CC-BY-SA