


[{"content":"","date":"August 12, 2026","externalUrl":null,"permalink":"/it/tags/affitti-brevi-firenze/","section":"Tags","summary":"","title":"Affitti Brevi Firenze","type":"tags"},{"content":"","date":"12 August 2026","externalUrl":null,"permalink":"/tags/alloggiati/","section":"Tags","summary":"","title":"Alloggiati","type":"tags"},{"content":"","date":"12 August 2026","externalUrl":null,"permalink":"/tags/carbon-free/","section":"Tags","summary":"","title":"Carbon Free","type":"tags"},{"content":" L\u0026rsquo;arte dell\u0026rsquo;ospitalità a Firenze # Gestire una struttura ricettiva nel cuore di Firenze, a due passi dal Duomo o dagli Uffizi, è un\u0026rsquo;esperienza unica ma anche una grande sfida. Negli ultimi anni il mercato degli affitti brevi e dei B\u0026amp;B è esploso, richiedendo ai proprietari e ai property manager un\u0026rsquo;organizzazione impeccabile.\nLe recensioni a 5 stelle si conquistano con dettagli curati, pulizia perfetta e un check-in accogliente. Tuttavia, la burocrazia italiana si mette spesso di traverso, trasformando quello che dovrebbe essere il momento dell\u0026rsquo;accoglienza in un freddo passaggio di scartoffie. Parliamo, ovviamente, delle schedine alloggiati.\nIl peso della burocrazia per chi fa Property Management # Che tu abbia un solo appartamento in Oltrarno o che gestisca dieci case vacanza sparse per il centro storico, la regola è sempre la stessa: entro 24 ore dall\u0026rsquo;arrivo dell\u0026rsquo;ospite, i suoi dati vanno comunicati alla Polizia di Stato.\nPer chi non ha strumenti adeguati, il processo è snervante:\nRaccogliere i passaporti o le carte di identità (spesso sbiadite o difficili da leggere). Accedere al portale istituzionale Alloggiati Web, che a volte risulta lento o temporaneamente fuori servizio. Inserire a mano ogni singolo dato: nome, cognome, cittadinanza, tipo e numero di documento, luogo di rilascio. Un errore di distrazione è facile, soprattutto dopo una giornata passata a correre tra un check-in e l\u0026rsquo;altro. E le sanzioni per mancato o errato invio non sono da sottovalutare.\nDimentica l\u0026rsquo;inserimento manuale con Send to Alloggiati # Perché continuare a perdere ore preziose davanti allo schermo quando la tecnologia può fare il lavoro sporco per te? Send to Alloggiati è l\u0026rsquo;applicazione creata per risolvere definitivamente questo problema.\nCon Send to Alloggiati, il processo di registrazione diventa istantaneo:\nScansione Intelligente: Durante il check-in, apri l\u0026rsquo;app e inquadri il documento dell\u0026rsquo;ospite. L\u0026rsquo;algoritmo di riconoscimento ottico (OCR) estrae tutti i dati necessari in frazioni di secondo, direttamente sul tuo dispositivo e nel pieno rispetto della privacy. Esportazione CSV per ISTAT (Ross1000): Non solo Polizia di Stato! L\u0026rsquo;app ti permette anche di esportare un flusso dati in formato CSV, pronto per essere caricato sul portale Ross1000 per l\u0026rsquo;adempimento ISTAT. In alternativa, puoi usare l\u0026rsquo;invio diretto tramite Web Service (WS) con un solo tasto per completare le pratiche in un attimo. Ritorna a fare l\u0026rsquo;Host # Delegare la burocrazia a un\u0026rsquo;app affidabile significa riappropriarsi del proprio tempo. Immagina di finire il tuo giro di check-in a Firenze e poter finalmente goderti un aperitivo in Piazza Santo Spirito, senza il pensiero di dover accendere il computer per registrare i turisti arrivati nel pomeriggio.\nMettiti al passo con i tempi e scegli una soluzione moderna, veloce e a prova di errore.\n👉 Inizia subito a risparmiare tempo: vai su schedinesmart.it per scoprire tutte le funzionalità e scaricare l\u0026rsquo;app.\n","date":"August 12, 2026","externalUrl":null,"permalink":"/it/alloggiati/invio-schedine-alloggiati-firenze/","section":"Alloggiati","summary":"Gestisci appartamenti o B\u0026amp;B a Firenze? Evita lo stress del portale Alloggiati Web. Scopri come inviare i dati alla Questura in un click o esportando un file CSV per l\u0026rsquo;ISTAT.","title":"Firenze e gli Affitti Brevi: Semplifica l'Invio Schedine Alloggiati","type":"Alloggiati"},{"content":"","date":"12 August 2026","externalUrl":null,"permalink":"/tags/green-tech/","section":"Tags","summary":"","title":"Green Tech","type":"tags"},{"content":"","date":"12 August 2026","externalUrl":null,"permalink":"/","section":"Luciosoft Blog","summary":"","title":"Luciosoft Blog","type":"page"},{"content":"","date":"12 August 2026","externalUrl":null,"permalink":"/alloggiati/","section":"Police","summary":"","title":"Police","type":"Alloggiati"},{"content":"","date":"12 August 2026","externalUrl":null,"permalink":"/tags/privacy/","section":"Tags","summary":"","title":"Privacy","type":"tags"},{"content":"","date":"August 12, 2026","externalUrl":null,"permalink":"/it/tags/property-manager/","section":"Tags","summary":"","title":"Property Manager","type":"tags"},{"content":" The Importance of Sustainable Software # Today, when we talk about pollution, we immediately think of transportation or industries. But did you know that the digital world also has a massive impact on the environment? Always-on servers, continuous data transfers, and energy-hungry data centers consume incredible amounts of power.\nAs a developer, I believe everyone must do their part. That is why, when designing and developing Schedine Smart (the app that automates guest registration submissions to the Italian State Police portal), I focused not only on privacy and ease of use, but also on eco-sustainability.\nA Carbon-Free Infrastructure # Schedine Smart is proudly a carbon-free application. How did we achieve this milestone?\n1. On-Device Processing # The core of the app is its Optical Character Recognition (OCR) system. Most of the magic happens directly on your smartphone, using machine learning models executed locally (on-device).\nWhat does this mean for the environment? It means we are not sending heavy photos back and forth across the network, and we are not keeping expensive, energy-hungry servers running 24/7 just to extract data from a document. This choice not only reduces network energy consumption to zero but also guarantees absolute privacy.\n2. Zero Intermediary Servers # Many apps use intermediary servers to collect data, process it, and then forward it. Schedine Smart does not. The app communicates directly from your phone to the Alloggiati Web portal.\nFewer servers mean less physical hardware needed, less energy consumed for data center cooling, and a much lighter, more ecological infrastructure.\n3. Cloud Services (Only When Strictly Necessary) # The only exception is the optional use of artificial intelligence (Gemini Flash) as a last resort for unreadable documents. For this, we rely on Google Cloud, a provider that has been carbon neutral since 2007 and today powers its facilities with 100% renewable energy, aiming to operate entirely on clean energy at all times by 2030.\nA Paperless Approach: Zero Paper # Traditionally, managing a B\u0026amp;B or holiday home means accumulating dozens of photocopies of ID documents, paper notes, and physical registers that will inevitably end up being pulped.\nWith Schedine Smart, the entire process is digitized. You scan the document, the app reads the data, and sends it. No photocopies, no paper waste, no printer toner. The environment thanks you.\nMake a Green Choice for Your B\u0026amp;B # Using modern tools doesn\u0026rsquo;t just mean saving time and reducing typos; it can also be a concrete way to reduce the environmental impact of your accommodation business.\nWith Schedine Smart, you make a secure choice for your guests\u0026rsquo; privacy and an eco-sustainable choice for our planet.\nDownload Schedine Smart for Android\nThe iOS version is in the works and will be arriving soon!\n","date":"12 August 2026","externalUrl":null,"permalink":"/alloggiati/send-to-police-ecosostenibile/","section":"Police","summary":"Discover how the Schedine Smart app manages guest registration in an eco-sustainable way, featuring a carbon-free and paperless infrastructure.","title":"Schedine Smart: The Carbon-Free and Eco-Sustainable Guest Registration App","type":"Alloggiati"},{"content":"","date":"August 12, 2026","externalUrl":null,"permalink":"/it/tags/send-to-alloggiati/","section":"Tags","summary":"","title":"Send To Alloggiati","type":"tags"},{"content":"","date":"August 12, 2026","externalUrl":null,"permalink":"/it/tags/sostenibilit%C3%A0/","section":"Tags","summary":"","title":"Sostenibilità","type":"tags"},{"content":"","date":"12 August 2026","externalUrl":null,"permalink":"/tags/sustainability/","section":"Tags","summary":"","title":"Sustainability","type":"tags"},{"content":"","date":"12 August 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"August 7, 2026","externalUrl":null,"permalink":"/it/tags/bb-lecce/","section":"Tags","summary":"","title":"B\u0026B Lecce","type":"tags"},{"content":" Ospitare a Lecce: il fascino del Barocco e l\u0026rsquo;accoglienza del Sud # Lecce e tutto il Salento sono diventati un punto di riferimento internazionale per il turismo. Le masserie, i Bed and Breakfast incastonati nella pietra leccese e le case vacanza tra i vicoli storici offrono esperienze autentiche che i turisti amano. L\u0026rsquo;accoglienza qui è un\u0026rsquo;arte fatta di sorrisi, pasticciotti caldi e consigli sulle spiagge migliori.\nMa anche qui, dove il tempo sembra scorrere più lentamente, i gestori devono fare i conti con le rigide scadenze della burocrazia: l\u0026rsquo;invio delle schedine alloggiati alla Polizia di Stato.\nL\u0026rsquo;estate salentina e i check-in infiniti # Chi gestisce una struttura ricettiva nel Sud Italia sa bene che i mesi estivi (e non solo) possono trasformarsi in un vero e proprio tour de force. Tra le pulizie delle camere, la preparazione delle colazioni e l\u0026rsquo;accoglienza di ospiti che arrivano scaglionati durante tutta la giornata, la sera si è spesso esausti.\nEppure, proprio in quel momento, bisogna mettersi al PC. Bisogna decifrare i documenti, fare l\u0026rsquo;accesso al portale Alloggiati Web e inserire i dati a mano per ogni singola persona. Un lavoro ripetitivo, soggetto a errori, che rischia di rovinare la tranquillità che rende speciale questo lavoro.\nLa soluzione smart: Send to Alloggiati # Perché sprecare energie quando la tecnologia può semplificarti la vita? L\u0026rsquo;app Send to Alloggiati è lo strumento che sta cambiando le abitudini di molti host pugliesi, permettendo loro di gestire la burocrazia in pochi istanti.\nEcco i vantaggi concreti:\nLettura Automatica dei Documenti: Non hai bisogno di scanner o computer portatili. Inquadra il documento del tuo ospite con la fotocamera dello smartphone durante il check-in. L\u0026rsquo;app estrae i dati in modo intelligente e sicuro (tutto in locale, senza cloud) e li invia direttamente al portale della Questura. Finito. Esportazione CSV per ISTAT (Ross1000): Non solo Polizia di Stato! L\u0026rsquo;app ti permette anche di esportare un flusso dati in formato CSV, pronto per essere caricato sul portale Ross1000 per l\u0026rsquo;adempimento ISTAT. In alternativa, puoi usare l\u0026rsquo;invio diretto tramite Web Service (WS) con un solo tasto per completare le pratiche in un attimo. Goditi la bellezza del tuo lavoro # Automatizzare l\u0026rsquo;invio delle schedine alloggiati ti permette di recuperare tempo prezioso. Tempo da dedicare alla cura dei dettagli della tua struttura o, semplicemente, per goderti una serata estiva leccese senza l\u0026rsquo;ansia delle scadenze.\n👉 Fai un regalo a te stesso e al tuo B\u0026amp;B: vai su schedinesmart.it per scoprire tutte le funzioni dell\u0026rsquo;app e scaricarla subito!\n","date":"August 7, 2026","externalUrl":null,"permalink":"/it/alloggiati/invio-schedine-alloggiati-lecce/","section":"Alloggiati","summary":"Il turismo in Puglia non si ferma mai. Scopri come gestire l\u0026rsquo;invio delle schedine alloggiati a Lecce e nel Salento in pochi secondi, tramite smartphone e file CSV per ISTAT.","title":"B\u0026B nel Salento: Schedine Alloggiati a Lecce senza Stress","type":"Alloggiati"},{"content":"","date":"August 7, 2026","externalUrl":null,"permalink":"/it/tags/host/","section":"Tags","summary":"","title":"Host","type":"tags"},{"content":"","date":"August 7, 2026","externalUrl":null,"permalink":"/it/tags/salento/","section":"Tags","summary":"","title":"Salento","type":"tags"},{"content":" Ospitare a Milano: la città che non si ferma mai # Milano è il motore d\u0026rsquo;Italia, una città frenetica che vive di grandi eventi internazionali: la Design Week, le Settimane della Moda, le fiere e un turismo business costante tutto l\u0026rsquo;anno. Se gestisci un appartamento su Airbnb o un B\u0026amp;B in città, sai benissimo che i tuoi ospiti si aspettano un servizio impeccabile, veloce e all\u0026rsquo;altezza di una metropoli europea.\nMa mentre tutto intorno a te va alla velocità della luce, c\u0026rsquo;è un momento della giornata in cui il tempo sembra fermarsi: l\u0026rsquo;invio delle schedine alloggiati.\nIl \u0026ldquo;collo di bottiglia\u0026rdquo; del portale istituzionale # I Property Manager milanesi spesso si trovano a gestire decine di check-in al giorno, magari distribuiti in quartieri diversi, da Isola ai Navigli. Raccogliere i dati, tornare in ufficio (o a casa), accedere ad Alloggiati Web e inserire manualmente ogni singola anagrafica è un\u0026rsquo;attività anacronistica.\nInoltre, il portale della Polizia di Stato richiede precisione assoluta. Se sbagli a trascrivere un nome o il numero di un documento rilasciato da un paese straniero con un formato insolito, devi ricominciare da capo. E le scadenze (entro le 24 ore dall\u0026rsquo;arrivo) non ammettono ritardi.\nEfficienza meneghina con Send to Alloggiati # Il mercato milanese degli affitti brevi richiede soluzioni smart e automatizzate. È qui che entra in gioco Send to Alloggiati, un\u0026rsquo;app pensata per tagliare i tempi della burocrazia in modo sicuro e professionale.\nCome migliorerà il tuo flusso di lavoro?\nUpload CSV dai Channel Manager: Se utilizzi software gestionali avanzati per sincronizzare le prenotazioni, Send to Alloggiati ti permette di importare il file CSV dei tuoi ospiti. Con pochi clic elabori e invii massivamente le schedine, eliminando del tutto l\u0026rsquo;inserimento manuale. Esportazione CSV per ISTAT (Ross1000): Non solo Polizia di Stato! L\u0026rsquo;app ti permette anche di esportare un flusso dati in formato CSV, pronto per essere caricato sul portale Ross1000 per l\u0026rsquo;adempimento ISTAT. In alternativa, puoi usare l\u0026rsquo;invio diretto tramite Web Service (WS) con un solo tasto per completare le pratiche in un attimo. Automatizza e scala il tuo business # A Milano, il tempo è denaro. Ogni ora spesa a litigare con un portale web per inserire dati a mano è un\u0026rsquo;ora sottratta allo sviluppo del tuo business, all\u0026rsquo;acquisizione di nuovi appartamenti o, più semplicemente, al tuo tempo libero.\nL\u0026rsquo;ottimizzazione dei processi è il segreto dei migliori host. Fai il salto di qualità.\n👉 Migliora subito la gestione del tuo B\u0026amp;B: vai su schedinesmart.it per tutti i dettagli tecnici e per iniziare a usare l\u0026rsquo;applicazione.\n","date":"August 2, 2026","externalUrl":null,"permalink":"/it/alloggiati/invio-schedine-alloggiati-milano/","section":"Alloggiati","summary":"Scopri la soluzione definitiva per i Property Manager e gli host di Milano per inviare i dati ad Alloggiati Web tramite foto e file CSV per ISTAT in modo automatico e veloce.","title":"Airbnb a Milano: Come Automatizzare l'Invio delle Schedine alla Polizia","type":"Alloggiati"},{"content":"","date":"August 2, 2026","externalUrl":null,"permalink":"/it/tags/airbnb-milano/","section":"Tags","summary":"","title":"Airbnb Milano","type":"tags"},{"content":"","date":"August 2, 2026","externalUrl":null,"permalink":"/it/tags/check-in/","section":"Tags","summary":"","title":"Check-in","type":"tags"},{"content":"","date":"July 28, 2026","externalUrl":null,"permalink":"/it/tags/bb-napoli/","section":"Tags","summary":"","title":"B\u0026B Napoli","type":"tags"},{"content":" L\u0026rsquo;energia contagiosa di Napoli (e i suoi turisti) # Negli ultimi anni, Napoli ha vissuto un vero e proprio rinascimento turistico. Dalle vie del centro storico a Spaccanapoli, fino ai quartieri più panoramici, l\u0026rsquo;apertura di nuovi Bed and Breakfast e case vacanza non accenna a diminuire. Ospitare in questa città significa regalare calore, ottimi consigli culinari e un\u0026rsquo;atmosfera indimenticabile.\nEppure, quando la sera cala sul Golfo, c\u0026rsquo;è un momento in cui l\u0026rsquo;entusiasmo dell\u0026rsquo;host si spegne: il collegamento al portale Alloggiati Web per l\u0026rsquo;invio delle schedine degli ospiti.\nQuando la burocrazia frena l\u0026rsquo;ospitalità # Gestire un B\u0026amp;B a conduzione familiare o una serie di appartamenti nel caos vitale di Napoli richiede molta energia. Tornare a casa dopo aver accolto gli ospiti, mettersi al computer e iniziare a digitare a mano i dati dei documenti di identità è frustrante.\nLa Questura richiede precisione e tempestività (invio entro 24 ore dall\u0026rsquo;arrivo). Se hai un gruppo di quattro turisti, tra nomi, cognomi, date e luoghi di rilascio dei documenti, rischi di passare mezz\u0026rsquo;ora incollato allo schermo, pregando che la connessione al portale di Stato non si interrompa proprio sul più bello.\nSend to Alloggiati: la soluzione \u0026ldquo;Zero Stress\u0026rdquo; # Perché continuare a fare a mano quello che l\u0026rsquo;intelligenza artificiale può fare in pochi decimi di secondo? Send to Alloggiati è l\u0026rsquo;app progettata per farti dimenticare il problema delle schedine.\nEcco perché sta conquistando gli host partenopei:\nLa fotocamera diventa il tuo assistente: Durante il check-in, apri l\u0026rsquo;app e inquadri il documento dell\u0026rsquo;ospite. L\u0026rsquo;app legge i dati automaticamente e li compila per te. Tu controlli, premi invio e il gioco è fatto. Nessun dato personale viene salvato sui nostri server, garantendo la totale privacy dei tuoi ospiti. Esportazione CSV per ISTAT (Ross1000): Non solo Polizia di Stato! L\u0026rsquo;app ti permette anche di esportare un flusso dati in formato CSV, pronto per essere caricato sul portale Ross1000 per l\u0026rsquo;adempimento ISTAT. In alternativa, puoi usare l\u0026rsquo;invio diretto tramite Web Service (WS) con un solo tasto per completare le pratiche in un attimo. Goditi la tua città # Il successo del tuo B\u0026amp;B dipende dall\u0026rsquo;attenzione che dedichi ai tuoi ospiti, non dal tempo che passi a inserire dati su un sito web anni \u0026lsquo;90. Ottimizza la tua routine di check-in e riprenditi il piacere dell\u0026rsquo;ospitalità.\n👉 Non aspettare oltre: visita schedinesmart.it per capire come funziona l\u0026rsquo;app e per scaricarla. Semplificati la vita da host!\n","date":"July 28, 2026","externalUrl":null,"permalink":"/it/alloggiati/invio-schedine-alloggiati-napoli/","section":"Alloggiati","summary":"Il turismo a Napoli è in crescita esponenziale. Non farti fermare dalla burocrazia: scopri come inviare le schedine alloggiati in pochi secondi con lo smartphone o via CSV.","title":"Il Boom dei B\u0026B a Napoli: Risolto il Problema delle Schedine Alloggiati","type":"Alloggiati"},{"content":"","date":"July 23, 2026","externalUrl":null,"permalink":"/it/tags/bb-palermo/","section":"Tags","summary":"","title":"B\u0026B Palermo","type":"tags"},{"content":" L\u0026rsquo;ospitalità siciliana senza ostacoli # Palermo è una città che travolge i sensi, e chi apre un Bed and Breakfast qui lo sa bene. I turisti arrivano desiderosi di perdersi tra i mercati storici di Ballarò e Vucciria, di assaggiare lo street food e di scoprire le meraviglie arabo-normanne. Il compito di un host palermitano è farli sentire subito a casa.\nMa c\u0026rsquo;è un ostacolo che spesso spezza questa magia dell\u0026rsquo;accoglienza: l\u0026rsquo;obbligo di registrare i documenti sul portale Alloggiati Web della Polizia di Stato.\nIl problema dei check-in serali # Molti voli per la Sicilia arrivano nel tardo pomeriggio o in serata. Accogli gli ospiti, mostri loro la camera, dài qualche consiglio su dove andare a mangiare e\u0026hellip; poi devi ritirarti per sbrigare le scartoffie. Il portale istituzionale richiede l\u0026rsquo;inserimento manuale di tutti i dati anagrafici e degli estremi del documento.\nSe i documenti sono tanti, o se hai più check-in nella stessa giornata, questa procedura si trasforma in un vero e proprio \u0026ldquo;lavoro extra\u0026rdquo; non retribuito. Aggiungi il fatto che il portale a volte è lento o in manutenzione, e lo stress è garantito.\nSend to Alloggiati: la soluzione a portata di mano # Non lasciare che la burocrazia rovini la tua passione per l\u0026rsquo;ospitalità. Send to Alloggiati è l\u0026rsquo;applicazione creata appositamente per chi gestisce strutture ricettive e vuole ottimizzare i tempi.\nPerché sceglierla per il tuo B\u0026amp;B a Palermo?\nOCR Veloce e Sicuro: Inquadra il documento dell\u0026rsquo;ospite (carta d\u0026rsquo;identità o passaporto) direttamente con la fotocamera del tuo telefono. L\u0026rsquo;intelligenza artificiale estrae i dati in locale in modo istantaneo. Tu controlli la correttezza e con un tap invii tutto alla Questura. Niente login continui e niente caricamenti infiniti. Esportazione CSV per ISTAT (Ross1000): Non solo Polizia di Stato! L\u0026rsquo;app ti permette anche di esportare un flusso dati in formato CSV, pronto per essere caricato sul portale Ross1000 per l\u0026rsquo;adempimento ISTAT. In alternativa, puoi usare l\u0026rsquo;invio diretto tramite Web Service (WS) con un solo tasto per completare le pratiche in un attimo. Più tempo per i tuoi ospiti, zero pensieri # Semplificare la gestione delle pratiche significa dedicare più energie alla cura della tua struttura e dei tuoi ospiti, elementi fondamentali per ottenere recensioni eccellenti e far crescere il tuo B\u0026amp;B a Palermo.\n👉 Inizia a risparmiare tempo fin dal prossimo check-in: scopri come funziona l\u0026rsquo;app su schedinesmart.it e scaricala per rivoluzionare il tuo modo di lavorare!\n","date":"July 23, 2026","externalUrl":null,"permalink":"/it/alloggiati/invio-schedine-alloggiati-palermo/","section":"Alloggiati","summary":"Scopri come semplificare l\u0026rsquo;invio delle schedine alloggiati a Palermo. Usa il tuo smartphone per scansionare i documenti o esporta i dati per l\u0026rsquo;ISTAT via CSV in pochi clic.","title":"Gestire le Schedine Alloggiati a Palermo: Meno Burocrazia per il tuo B\u0026B","type":"Alloggiati"},{"content":" Pisa: molto più della Torre Pendente # Pisa è una delle mete turistiche italiane più amate dai visitatori stranieri e un importante snodo aeroportuale. Questo si traduce in un flusso continuo di turisti \u0026ldquo;mordi e fuggi\u0026rdquo; che si fermano spesso per una o due notti prima di proseguire il loro viaggio in Toscana.\nPer chi gestisce un B\u0026amp;B o una casa vacanze in città, questo alto turnover significa una sola cosa: molti check-in in poco tempo. E con i check-in arrivano inevitabilmente gli obblighi di legge, primo fra tutti la registrazione degli ospiti sul portale Alloggiati Web.\nIl peso dei soggiorni brevi sulla burocrazia # Se un ospite si ferma per una settimana, il tempo impiegato per registrarlo viene \u0026ldquo;ammortizzato\u0026rdquo;. Ma se gestisci ospiti che cambiano ogni giorno, la trasmissione dei dati alla Polizia di Stato diventa un\u0026rsquo;incombenza quotidiana pesante.\nMolti host si ritrovano la sera a dover inserire manualmente decine di nomi, numeri di passaporto e luoghi di nascita, lottando contro un portale istituzionale non sempre intuitivo e veloce. Un errore di digitazione su un documento straniero può costringere a rifare la procedura, rubando tempo prezioso che potrebbe essere dedicato al riposo o alla cura della struttura.\nAutomatizza i tuoi Check-in con Send to Alloggiati # Per far fronte a questo ritmo frenetico, la tecnologia viene in tuo soccorso. Send to Alloggiati è l\u0026rsquo;applicazione definitiva per azzerare i tempi burocratici e lavorare in modo più intelligente.\nI vantaggi per gli host di Pisa sono immediati:\nScansione da Smartphone: Ti basta inquadrare il documento dell\u0026rsquo;ospite con la fotocamera del tuo telefono. Grazie al sistema OCR integrato (che lavora offline per garantire la massima privacy), l\u0026rsquo;app estrae i dati all\u0026rsquo;istante e li invia direttamente ad Alloggiati Web con un solo tap. Esportazione CSV per ISTAT (Ross1000): Non solo Polizia di Stato! L\u0026rsquo;app ti permette anche di esportare un flusso dati in formato CSV, pronto per essere caricato sul portale Ross1000 per l\u0026rsquo;adempimento ISTAT. In alternativa, puoi usare l\u0026rsquo;invio diretto tramite Web Service (WS) con un solo tasto per completare le pratiche in un attimo. Lavora in modo più intelligente # Non lasciare che la burocrazia diventi il limite alla crescita del tuo B\u0026amp;B. Scegliere strumenti digitali moderni ti permette di offrire un\u0026rsquo;accoglienza più rilassata e professionale.\n👉 Smetti di copiare a mano i documenti: visita il sito schedinesmart.it per scoprire tutti i dettagli tecnici e scaricare l\u0026rsquo;app che semplificherà le tue serate!\n","date":"July 18, 2026","externalUrl":null,"permalink":"/it/alloggiati/invio-schedine-alloggiati-pisa/","section":"Alloggiati","summary":"Pisa è una meta gettonatissima per soggiorni brevi. Scopri come automatizzare l\u0026rsquo;invio delle schedine alloggiati alla Questura usando un\u0026rsquo;app intelligente o l\u0026rsquo;esportazione CSV per l\u0026rsquo;ISTAT.","title":"B\u0026B a Pisa: Gestire il Flusso Turistico e le Schedine Alloggiati","type":"Alloggiati"},{"content":"","date":"July 18, 2026","externalUrl":null,"permalink":"/it/tags/bb-pisa/","section":"Tags","summary":"","title":"B\u0026B Pisa","type":"tags"},{"content":"","date":"July 13, 2026","externalUrl":null,"permalink":"/it/tags/bb-roma/","section":"Tags","summary":"","title":"B\u0026B Roma","type":"tags"},{"content":" La vita frenetica di un host a Roma # Roma è una città magnifica, ma chi gestisce un Bed and Breakfast o una casa vacanze nella Capitale sa bene che dietro alla Grande Bellezza c\u0026rsquo;è un lavoro immenso. Tra turisti che arrivano in ritardo, la pulizia delle camere, le pratiche per la tassa di soggiorno e l\u0026rsquo;eterno problema del traffico, il tempo per rilassarsi sembra non esserci mai.\nUna delle attività che ruba più tempo e genera più stress per i gestori è l\u0026rsquo;invio delle schedine alloggiati. La legge italiana è chiara: i dati degli ospiti devono essere trasmessi alla Polizia di Stato tramite il portale Alloggiati Web entro 24 ore dal loro arrivo.\nIl problema del portale Alloggiati Web # Immagina la scena: sono le 22:00, hai appena finito di fare il check-in a una famiglia di turisti stranieri. Sei stanco e vorresti solo chiudere la giornata. Invece ti tocca sederti al computer, accedere al portale (sperando che non sia in manutenzione o bloccato) e iniziare a inserire a mano i dati.\nNome, cognome, data di nascita, cittadinanza, tipo e numero di documento\u0026hellip; Tutto rigorosamente copiato dalle foto sgranate dei passaporti che ti sei fatto inviare su WhatsApp. Un errore di battitura, un documento non riconosciuto e la procedura si blocca. Per chi gestisce un alto volume di prenotazioni come succede a Roma, specialmente in alta stagione o in prossimità del Giubileo, questo lavoro manuale diventa un incubo ricorrente che porta via ore preziose ogni settimana.\nLa soluzione definitiva: Send to Alloggiati # E se ti dicessi che puoi risolvere questo problema in pochi secondi? Nata proprio dall\u0026rsquo;esigenza reale di un host, l\u0026rsquo;applicazione Send to Alloggiati è stata progettata per eliminare lo stress dell\u0026rsquo;inserimento manuale.\nEcco come questa app rivoluziona il lavoro quotidiano del tuo B\u0026amp;B:\nScansione e Invio Diretto: Tramite la fotocamera del tuo smartphone, l\u0026rsquo;app legge in modo intelligente (grazie all\u0026rsquo;intelligenza artificiale e al riconoscimento OCR avanzato) i documenti di identità ed estrae i dati in millisecondi. Controlli che sia tutto corretto e, con un solo pulsante, i dati vengono trasmessi in modo sicuro alla Polizia. Nessun passaggio su portali lenti e macchinosi.\nEsportazione CSV per ISTAT (Ross1000): Non solo Polizia di Stato! L\u0026rsquo;app ti permette anche di esportare un flusso dati in formato CSV, pronto per essere caricato sul portale Ross1000 per l\u0026rsquo;adempimento ISTAT. In alternativa, puoi usare l\u0026rsquo;invio diretto tramite Web Service (WS) con un solo tasto per completare le pratiche in un attimo.\nPiù tempo per i tuoi ospiti, meno burocrazia # Automatizzare l\u0026rsquo;invio delle schedine non è solo una comodità tecnica; è una scelta strategica per riprendersi il proprio tempo libero e migliorare l\u0026rsquo;esperienza dei clienti. Meno tempo passato davanti al PC a combattere con il portale della Questura significa più tempo per consigliare un buon ristorante a Trastevere ai tuoi ospiti o, più semplicemente, per riposare.\nSe gestisci una struttura a Roma e vuoi smettere di ricopiare passaporti a mano ogni sera, è arrivato il momento di passare a un metodo più smart.\n👉 Scopri come semplificarti la vita e prova subito la soluzione: Visita schedinesmart.it per tutti i dettagli e per scaricare l\u0026rsquo;app.\n","date":"July 13, 2026","externalUrl":null,"permalink":"/it/alloggiati/invio-schedine-alloggiati-roma/","section":"Alloggiati","summary":"Gestisci un B\u0026amp;B a Roma? Scopri come automatizzare l\u0026rsquo;invio delle schedine alloggiati al portale ISTAT e della Polizia di Stato con un semplice click o esportando un file CSV per l\u0026rsquo;ISTAT.","title":"Gestire le Schedine Alloggiati a Roma: Salva le Tue Serate (Guida per B\u0026B)","type":"Alloggiati"},{"content":"","date":"July 8, 2026","externalUrl":null,"permalink":"/it/tags/bb-venezia/","section":"Tags","summary":"","title":"B\u0026B Venezia","type":"tags"},{"content":" L\u0026rsquo;unicità (e la fatica) di ospitare a Venezia # Venezia non ha eguali nel mondo. Per un turista, soggiornare in Laguna tra canali, calli e campielli è pura magia. Ma per chi gestisce un Bed and Breakfast o un appartamento turistico, la realtà è fatta anche di grande impegno: accogliere gli ospiti ai moli, spiegare come muoversi senza perdersi, gestire le alte maree e, ovviamente, assolvere a tutti gli obblighi burocratici.\nTra questi, la trasmissione dei dati alla Polizia di Stato tramite il sistema Alloggiati Web è spesso vissuta come la parte più noiosa e stressante della giornata.\nIl problema dell\u0026rsquo;inserimento dati per gli host veneziani # Immagina questa situazione: hai appena accolto un gruppo di turisti arrivati con il vaporetto, hai spiegato loro tutto il necessario e finalmente torni alla tua base. Manca solo una cosa: registrare le schedine alloggiati.\nApri il portale ISTAT/Polizia di Stato e inizi a decifrare i documenti: carte d\u0026rsquo;identità usurate, passaporti con nomi incomprensibili, formati stranieri a cui non sei abituato. E se il sito web decide di fare i capricci, i tempi si allungano a dismisura. Per chi gestisce un B\u0026amp;B a Venezia, dove i ritmi sono dettati anche dalla logistica complessa della città, perdere tempo prezioso per copiare a mano dei dati è inaccettabile.\nLa svolta: l\u0026rsquo;app Send to Alloggiati # Nata dall\u0026rsquo;esperienza diretta di chi conosce queste problematiche, l\u0026rsquo;app Send to Alloggiati è la soluzione definitiva per snellire le pratiche di check-in.\nPerché questa app è perfetta per i property manager veneziani?\nMassima Mobilità: Sei sempre in movimento tra un sestiere e l\u0026rsquo;altro? Non ti serve il computer. Ti basta il tuo smartphone. Fai una foto al documento di identità e l\u0026rsquo;intelligenza artificiale estrae i dati all\u0026rsquo;istante, in locale, tutelando la privacy. Con un solo clic, i dati vengono trasmessi alla Questura. Esportazione CSV per ISTAT (Ross1000): Non solo Polizia di Stato! L\u0026rsquo;app ti permette anche di esportare un flusso dati in formato CSV, pronto per essere caricato sul portale Ross1000 per l\u0026rsquo;adempimento ISTAT. In alternativa, puoi usare l\u0026rsquo;invio diretto tramite Web Service (WS) con un solo tasto per completare le pratiche in un attimo. Riprenditi il tuo tempo in Laguna # Automatizzare la burocrazia significa poter offrire un servizio migliore ai tuoi ospiti e vivere il tuo lavoro con più serenità. Smetti di stressarti ogni sera davanti al portale Alloggiati Web e unisciti a centinaia di host che hanno già scelto la comodità.\n👉 Risolvi il problema delle schedine alloggiati oggi stesso: visita la pagina ufficiale schedinesmart.it per scoprire come l\u0026rsquo;app può cambiare il tuo modo di lavorare e per scaricarla sul tuo smartphone.\n","date":"July 8, 2026","externalUrl":null,"permalink":"/it/alloggiati/invio-schedine-alloggiati-venezia/","section":"Alloggiati","summary":"Scopri come semplificare l\u0026rsquo;invio delle schedine alloggiati a Venezia. Usa il tuo smartphone per acquisire i documenti o carica un file CSV per dire addio all\u0026rsquo;inserimento manuale.","title":"Gestione B\u0026B a Venezia: Dimentica lo Stress del Portale Alloggiati Web","type":"Alloggiati"},{"content":"","date":"1 June 2026","externalUrl":null,"permalink":"/coding/","section":"Coding","summary":"","title":"Coding","type":"Coding"},{"content":"","date":"1 June 2026","externalUrl":null,"permalink":"/tags/crm/","section":"Tags","summary":"","title":"CRM","type":"tags"},{"content":"","date":"1 June 2026","externalUrl":null,"permalink":"/tags/ddd/","section":"Tags","summary":"","title":"DDD","type":"tags"},{"content":"","date":"1 June 2026","externalUrl":null,"permalink":"/tags/flutter/","section":"Tags","summary":"","title":"Flutter","type":"tags"},{"content":"","date":"1 June 2026","externalUrl":null,"permalink":"/tags/graphql/","section":"Tags","summary":"","title":"GraphQL","type":"tags"},{"content":"","date":"1 June 2026","externalUrl":null,"permalink":"/tags/luciosoft/","section":"Tags","summary":"","title":"Luciosoft","type":"tags"},{"content":"","date":"1 June 2026","externalUrl":null,"permalink":"/tags/mobile/","section":"Tags","summary":"","title":"Mobile","type":"tags"},{"content":"","date":"1 June 2026","externalUrl":null,"permalink":"/tags/opensource/","section":"Tags","summary":"","title":"OpenSource","type":"tags"},{"content":"","date":"1 June 2026","externalUrl":null,"permalink":"/tags/riverpod/","section":"Tags","summary":"","title":"Riverpod","type":"tags"},{"content":"","date":"1 June 2026","externalUrl":null,"permalink":"/tags/twentymobile/","section":"Tags","summary":"","title":"TwentyMobile","type":"tags"},{"content":" The Article I Promised # In my last post I told you why I decided to make TwentyMobile open source. Today I\u0026rsquo;m taking you behind the scenes: how the app is built, the architectural choices, and all those \u0026ldquo;why doesn\u0026rsquo;t this work?\u0026rdquo; moments that every developer knows too well.\nThe Architecture: DDD and Connector Pattern # When I started writing TwentyMobile, I knew I didn\u0026rsquo;t want an app that worked only with Twenty CRM. The idea was to create a mobile client that could, in the future, connect to any CRM. Ambitious? Maybe. But the right architecture makes the difference between a project that scales and one that dies under its own weight.\nI chose Domain-Driven Design (DDD) combined with a Feature-First approach. In practice, the project structure looks like this:\nlib/ ├── core/ # DI, Router, Theme, Notifications ├── domain/ # Models (Contact, Company, Note, Task, Workflow) │ └── repositories/ # The abstract CRMRepository interface ├── data/ # TwentyConnector (the GraphQL client) ├── presentation/ # UI organized by feature │ ├── onboarding/ │ ├── home/ │ ├── contacts/ │ ├── companies/ │ ├── tasks/ │ ├── workflows/ │ └── ... └── shared/ # Shared widgets At the heart of everything is the Connector Pattern: an abstract CRMRepository interface that defines all necessary methods (30+ methods!) to interact with a generic CRM. The concrete implementation is TwentyConnector, a GraphQL client that talks to Twenty\u0026rsquo;s APIs.\nIf tomorrow I wanted to support HubSpot or Salesforce? I\u0026rsquo;d just need to create a HubSpotConnector implementing the same interface. The UI wouldn\u0026rsquo;t change one bit. That\u0026rsquo;s the magic of DDD done right.\nThe Tech Stack # Let me tell you about the technology choices and why I made them:\nRiverpod for state management. After years of Provider and BLoC, Riverpod was a breath of fresh air. Code generation with riverpod_annotation reduces boilerplate to a minimum.\nGoRouter for navigation. Supports deep linking, typed parameters, and integrates well with Riverpod for authentication redirects.\nFreezed for domain models. Guaranteed immutability, automatic copyWith, and especially those .fromTwenty() factory constructors that let me map Twenty\u0026rsquo;s GraphQL responses to my domain models.\nGraphQL Flutter for APIs. Twenty CRM exposes everything through GraphQL, and I have to say, once you understand how it works, it\u0026rsquo;s much more powerful than REST for a mobile app. You ask for exactly the data you need, nothing more.\nThe Features That Drove Me Crazy # The Business Card Scanner # This was one of the most fun features to implement. The idea: point your camera at a business card, the app reads the text with MLKit, and automatically creates the contact in the CRM.\nThe reality? Business cards are a nightmare. Creative fonts, non-standard layouts, information scattered in seemingly random ways. I had to write a custom parser (BusinessCardParser) that tries to figure out what\u0026rsquo;s a first name, what\u0026rsquo;s a last name, what\u0026rsquo;s an email, and what\u0026rsquo;s a phone number. It works 90% of the time. For that remaining 10%\u0026hellip; well, there\u0026rsquo;s always manual entry.\nSlide-to-Execute for Workflows # This is the feature I\u0026rsquo;m most proud of from a UI perspective. When you execute a manual Twenty CRM workflow from the app, the confirmation button isn\u0026rsquo;t a simple \u0026ldquo;Tap\u0026rdquo;. It\u0026rsquo;s an iOS-style slider that you have to drag from left to right.\nThe reason is simple: workflows can do important things (send emails, update records, trigger webhooks). You don\u0026rsquo;t want to execute them by accident because you touched the phone with your thumb while pulling it out of your pocket.\nThe implementation includes:\n85% drag threshold for activation Progressive haptic feedback at 25%, 50%, 75% Shake animation if something goes wrong Anti-fat-finger threshold to prevent accidental activations Voice Notes # In a meeting you can\u0026rsquo;t start typing notes on your phone without looking rude. But you can record a voice note after. I integrated speech_to_text for automatic transcription and save it as a note in the CRM. Fast, practical, and you don\u0026rsquo;t even have to look at the screen.\nThe Problems Nobody Tells You About (Part 2) # The 52KB TwentyConnector — Yes, I know. It\u0026rsquo;s a huge file. Over 50 thousand bytes of GraphQL queries, mutations, and parsing logic. Every time I open it, the IDE takes a second too long. Refactoring has been on my list for a while, but as they say\u0026hellip; \u0026ldquo;if it ain\u0026rsquo;t broke, don\u0026rsquo;t fix it\u0026rdquo;. And it works. Terrible as code quality, excellent as functionality.\nTwo-factor authentication — Implementing the 2FA flow with OTP was\u0026hellip; an adventure. Twenty CRM supports TOTP, and the app has to handle the case where the user has 2FA enabled. I had to create a dedicated OTP screen that slots into the login flow only when needed. All with a timer that invalidates the code every 30 seconds. Nothing earth-shattering, but those UX details make the difference.\nToken refresh — The app has to handle the case where the user puts the app in the background for hours and then reopens it. The JWT token will have expired, and if you don\u0026rsquo;t handle the refresh correctly, the user sees errors everywhere. I implemented an AppLifecycleHandler that automatically re-authenticates when the app comes back to the foreground. Sounds trivial, but the number of apps that get this wrong is staggering.\nAI as Co-Developer # One thing that surprised me is how much AI agents contributed to the project. I\u0026rsquo;m not talking about using Copilot for autocomplete. I\u0026rsquo;m talking about autonomous agents that open PRs, fix bugs, and optimize performance.\nIf you look at the commit history on GitHub, you\u0026rsquo;ll find branches like jules/optimize-country-code-search — created automatically by the Jules agent I integrated into my development workflow. The agent analyzes issues, scans the code, proposes solutions, and if tests pass, opens a PR.\nThe PRs I\u0026rsquo;ve received include:\n🔒 Security fix: PII data protection in logs 🧹 Cleanup of swallowed exceptions in vCard generator ⚡ Avatar URL parsing optimization 🔧 Added autofill hints to login forms Not bad for a co-developer who never sleeps and never asks for vacation.\nThe Numbers (for the Curious) # Some numbers about the project:\n85+ commits on the main branch 28+ branches for features and fixes Version 1.0.5, build 31 30+ methods in the CRMRepository interface iOS and Android support with responsive layout for tablets 0 data collected — privacy first How to Try It # If you want to try TwentyMobile, here are the links:\n📱 Google Play Store 🍎 App Store (search \u0026ldquo;TwentyMobile\u0026rdquo;) 💻 Source code on GitHub 🌐 Official website The app supports two access modes: API Token for administrators and Email/Password for standard users. There\u0026rsquo;s also a Demo Mode to explore the interface without configuring anything.\nFinal Thoughts # Building TwentyMobile has been an incredible experience. I learned a ton about GraphQL, about DDD applied to Flutter, and about managing an open-source project. But above all, I learned that the best way to solve a problem is to share the solution.\nIf you have a Twenty CRM instance and you\u0026rsquo;re missing a mobile app, give it a try. If you\u0026rsquo;re a Flutter developer and want to contribute, the code is there. And if you have questions, open an issue on GitHub or reach out.\nUntil next time.\n","date":"1 June 2026","externalUrl":null,"permalink":"/coding/twentymobile-mobile-crm-flutter/","section":"Coding","summary":"Behind the scenes of TwentyMobile: DDD architecture, Connector Pattern, manual workflows with slide-to-execute, and the late nights debugging GraphQL.","title":"TwentyMobile: How I Built a Mobile CRM with Flutter, DDD, and a Bit of Madness","type":"Coding"},{"content":"","date":"15 May 2026","externalUrl":null,"permalink":"/tags/gpl/","section":"Tags","summary":"","title":"GPL","type":"tags"},{"content":" The Problem Nobody Was Solving # Let me tell you something. I\u0026rsquo;d been using Twenty CRM for a while — for those who don\u0026rsquo;t know it, it\u0026rsquo;s a beautiful, modern, open-source CRM with an active community. Works great in the browser. But I\u0026rsquo;m a mobile developer. And I do my job on the go: between meetings, at the airport, at the client\u0026rsquo;s office. Every time I needed to check a contact or update a note, I had to open the browser, log in, wait for it to load\u0026hellip; and if I was on the subway with half a bar of signal, good luck.\nI was looking for a native mobile app for Twenty CRM. It didn\u0026rsquo;t exist. I looked for alternatives. Nothing decent. At that point I told myself: I guess I have to build it myself.\nFrom Personal Project to Open Source # The first few weeks of development I spent in classic mode: closed source, private repo, nobody sees anything until it\u0026rsquo;s ready. The typical approach of a developer who\u0026rsquo;s afraid someone will see their spaghetti code.\nBut then something happened. I was using Twenty CRM, which is open source. I was using Flutter, which is open source. I was using Riverpod, GraphQL Flutter, Freezed\u0026hellip; all open source. My project was literally standing on the shoulders of dozens of developers who had decided to share their work for free.\nAnd what was I doing? Keeping my code closed. It felt hypocritical.\nChoosing the License: GPL-3.0 # When I decided to make the project open source, the first question was: which license? I evaluated the options:\nMIT — Too permissive for my taste. Someone could take the code, close it, and sell it as their own. No thanks. Apache 2.0 — Similar to MIT but with patent protection. Better, but still too permissive. GPL-3.0 — Strong copyleft. If someone modifies the code and distributes it, they must release their modifications under the same license. That\u0026rsquo;s what I wanted. GPL-3.0 protects the project so it always remains open source. If someone wants to contribute, perfect. If someone wants to fork and improve it, perfect. But they can\u0026rsquo;t take my work and close it. Seems fair to me.\nWhat This Means in Practice for TwentyMobile # TwentyMobile is a mobile client for Twenty CRM built with Flutter. What it does is simple to explain but not trivial to implement:\nContact and company management with fast search, comprehensive details, and optimistic updates Notes and voice notes to capture information on the fly Tasks with notifications so you never forget a follow-up Business card scanner with integrated OCR Manual workflows to execute automations directly from your phone Everything connects to your self-hosted Twenty CRM instance. Zero data collected, zero proprietary cloud, everything travels directly between your phone and your server.\nThe Fears of Making Code Public # I\u0026rsquo;ll be honest with you: before pressing that \u0026ldquo;Make public\u0026rdquo; button on GitHub, I had a moment of panic. The typical thoughts:\n\u0026ldquo;The code isn\u0026rsquo;t perfect\u0026rdquo; — And when is it ever? I released with things that still make me cringe. The TwentyConnector is a 52KB file. Fifty-two thousand bytes of GraphQL code in a single file. I know, it\u0026rsquo;s too big. But it works. And the refactoring will come. In the meantime, the world can see how I solved certain problems, and maybe someone finds a better way.\n\u0026ldquo;Someone will copy everything\u0026rdquo; — With GPL-3.0, they can copy. But they must keep the license and release their modifications. And honestly, if someone takes my code and improves it, all the better for everyone.\n\u0026ldquo;Who will ever contribute?\u0026rdquo; — This was the biggest surprise. Through integration with AI agents like Jules, I\u0026rsquo;ve already received automatic PRs for security fixes, performance optimizations, and code cleanup. It\u0026rsquo;s not the traditional human-made community, but it\u0026rsquo;s a community that works.\nThe Side Effect I Didn\u0026rsquo;t Expect # Making the project open source forced me to write better code. Not because someone was actually reading it — at least not right away — but because I knew someone could read it.\nI started commenting more. Structuring commits better. Writing a decent README. Documenting the architecture. Things I should have been doing anyway, but that the laziness of a solo developer tends to skip.\nAnd then there\u0026rsquo;s the portfolio advantage. When someone asks me \u0026ldquo;what can you do?\u0026rdquo;, I send them the GitHub link. Actions speak louder than résumés.\nAdvice for Those Considering It # If you have a personal project and you\u0026rsquo;re thinking about making it open source, here\u0026rsquo;s what I\u0026rsquo;d tell you from my experience:\nDon\u0026rsquo;t wait for perfection. Perfect code doesn\u0026rsquo;t exist. Release when it works, improve later. The community (human or AI) will help you.\nChoose the license carefully. It\u0026rsquo;s not a bureaucratic detail. The license defines what others can do with your work. Do your research before choosing.\nWrite a good README. It\u0026rsquo;s the first thing people see. If the README is poor, nobody will look at the code.\nPrepare for weird issues. On any open-source project, sooner or later someone will open an issue like \u0026ldquo;doesn\u0026rsquo;t work\u0026rdquo; without giving any context. It\u0026rsquo;s part of the game.\nUse CI/CD from day one. Automated tests, automated builds, linting. If the project is open source, these things are not optional.\nWhat\u0026rsquo;s Next? # TwentyMobile is on GitHub, on Google Play, and on the App Store. The project is active, features keep coming, and the code is there for anyone who wants to take a look, contribute, or simply learn something.\nIf you want to know more about the project, check out the official website. And if you\u0026rsquo;d like to contribute, PRs are open. Even AI agent PRs are welcome, apparently.\nNext time I\u0026rsquo;ll tell you in detail how the app is built from a technical perspective. Spoiler: Flutter, DDD, Connector Pattern, and a whole lot of GraphQL.\n","date":"15 May 2026","externalUrl":null,"permalink":"/coding/why-i-made-twentymobile-open-source/","section":"Coding","summary":"The story of how a project born to solve my own problem became open source. Spoiler: it wasn\u0026rsquo;t an easy decision.","title":"Why I Made TwentyMobile Open Source (and Why You Should Too)","type":"Coding"},{"content":"","date":"19 February 2026","externalUrl":null,"permalink":"/tags/ai/","section":"Tags","summary":"","title":"AI","type":"tags"},{"content":" It all started with a complaint # Let me tell you something. About a year ago I was scrolling through the reviews of Send to Kindle — my app for sending documents to Kindle — and I stumbled upon a review that said something like: \u0026ldquo;The app works but the converted PDF is garbage, completely unreadable.\u0026rdquo; One star, obviously.\nNow, PDF conversion has always been a pain. Anyone who works with documents knows: a PDF can contain anything. Text, images, tables, insane layouts. And converting it into a readable format for Kindle without losing formatting is a nightmare. For years I used Calibre on the server side to do the heavy lifting, and it worked\u0026hellip; sort of.\nBut that review got me thinking. Maybe it\u0026rsquo;s time to level up.\nThe epiphany: AI isn\u0026rsquo;t just for chatbots # Let\u0026rsquo;s be honest: when people hear \u0026ldquo;artificial intelligence\u0026rdquo; they immediately think ChatGPT, chatbots, those things that write your emails. But AI is so much more, especially for mobile app developers.\nI figured this out while working on Schedine Smart, my app for submitting guest registration forms to Italian police. I had already integrated Google MLKit for reading identity documents and Gemini Flash as a fallback for the most desperate cases. And it worked beautifully. So I thought: if AI can read a crumpled 1987 paper ID card with a faded photo, why can\u0026rsquo;t it help me with PDFs?\nWhat I actually did # I started integrating AI at strategic points in my Flutter apps, without rewriting everything from scratch. This is the key point: you don\u0026rsquo;t need to throw away your existing code. AI plugs in as an additional layer.\n1. Smart document recognition # In Schedine Smart I built a cascading system:\nFirst attempt: MLKit on-device, fast and private. Works great for passports and electronic ID cards. Second attempt: proprietary algorithm for old Italian paper ID cards (the ones even your grandmother can\u0026rsquo;t read). Third attempt: Gemini Flash via API, only with user consent. The beauty of Flutter is that managing this cascade is natural. A well-structured try-catch, some async/await, and you\u0026rsquo;re done. The user doesn\u0026rsquo;t notice anything: they take a photo and the data appears.\n2. Smarter PDF conversion # In Send to Kindle I added a pre-conversion analysis layer. Before sending the PDF to the Calibre container, the app now analyzes the document to determine if it\u0026rsquo;s a scanned PDF (basically an image), a PDF with real text, or a mix of both. This analysis determines what type of conversion to apply.\nFor scanned PDFs I integrated OCR with AI support, which recognizes text in images. The result? Conversions that were previously unreadable now come out clean. That one-star review might be worth at least three stars now. Maybe.\n3. Firebase as the glue # One thing I\u0026rsquo;ve learned over the years is that Firebase is the indie developer\u0026rsquo;s best friend. In both apps I use:\nFirebase Remote Config to manage feature flags without releasing updates Cloud Functions for lightweight backend Firebase Storage for file management Pub/Sub to communicate with conversion containers The integration with Flutter is flawless thanks to FlutterFire plugins. If you haven\u0026rsquo;t checked them out yet, I highly recommend giving them a try.\nIf you\u0026rsquo;re curious about how I use these tools in my projects, stop by luciosoft.it.\nThe problems nobody tells you about # But it\u0026rsquo;s not all sunshine and rainbows. Let me share some mishaps:\nMemory explosion — When I deployed the PDF conversion container on Cloud Run, large files crashed everything. I had to go from 2GB to 4GB of RAM, and for really huge files you need 8GB. At one point I thought: I\u0026rsquo;m running a nuclear power plant just to convert a PDF. But it works.\nThe -1017 bug — Firebase Storage has a mysterious error, code -1017, that pops up when you upload files downloaded from Google Drive. I spent two days debugging before realizing the issue was in how iOS handles temporary files. The solution? Use putData instead of putFile. Two lines of code, two days of work. Classic.\nGrandpa\u0026rsquo;s ID cards — My recognition algorithm for old paper IDs works well in 90% of cases. But that remaining 10%\u0026hellip; people with documents folded in four, kept in their wallet for twenty years, with a photo that looks like an impressionist painting. For those, there\u0026rsquo;s Gemini Flash, which sometimes manages to extract data even from those desperate situations.\nTips for those who want to get started # If you develop Flutter apps and want to integrate AI, here\u0026rsquo;s what I suggest from my experience:\nStart with the problem, not the technology. Don\u0026rsquo;t add AI because it\u0026rsquo;s trendy. Add it where it solves a real user problem.\nUse a cascading approach. AI isn\u0026rsquo;t infallible. Having a fallback (or two, or three) is essential. On-device first, cloud second.\nPrivacy first. Especially with sensitive data like identity documents. Data should travel as little as possible.\nFirebase Remote Config is your friend. You can toggle AI features on and off without releasing an update. Trust me, you\u0026rsquo;ll need this.\nTest with real files. Tests with perfect files always pass. But then a user shows up with a 50MB PDF generated by a 2003 scanner and everything explodes.\nWhat\u0026rsquo;s next? # I\u0026rsquo;m working on new integrations. The idea is to use lighter AI models directly on-device for certain tasks, without going through the cloud. Flutter with its plugins and the growing community makes all of this possible.\nIf you want to try my apps:\nSend to Kindle — to send articles and documents to your Kindle Schedine Smart — for guest registration without going crazy And if you feel like it, stop by luciosoft.it to see what else I\u0026rsquo;m up to. Spoiler: more apps, more experiments, and probably more bugs to fix.\n","date":"19 February 2026","externalUrl":null,"permalink":"/coding/flutter-and-ai-app-revolution/","section":"Coding","summary":"From document recognition to intelligent PDF conversion: how AI transformed my Flutter apps without overhauling the codebase.","title":"Flutter and AI: how I revolutionized my apps without rewriting them from scratch","type":"Coding"},{"content":"","date":"19 February 2026","externalUrl":null,"permalink":"/tags/geminiai/","section":"Tags","summary":"","title":"GeminiAI","type":"tags"},{"content":"","date":"19 February 2026","externalUrl":null,"permalink":"/tags/sendtokindle/","section":"Tags","summary":"","title":"SendToKindle","type":"tags"},{"content":"","date":"19 February 2026","externalUrl":null,"permalink":"/tags/sendtopolice/","section":"Tags","summary":"","title":"SendToPolice","type":"tags"},{"content":" The Frustration That Got Me Here # Let me tell you something. When I was a mid-level developer, I spent a ridiculous amount of time doing issue triage. Analyze the context, figure out which files were involved, estimate if it was a 5-minute fix or a 5-day saga. Wasted time, I always thought. But hey, it\u0026rsquo;s part of the job.\nThen I became senior. And the triage work increased. Because now I not only had to do it, but I also had to explain it to juniors. Great.\nNow I\u0026rsquo;m an architect. And guess what? Triage is still there. Except now I also have to make sure the proposed solutions are consistent with the overall system architecture. Turns out this problem follows me wherever I go.\nBut something interesting happened over these years: AI agents actually became usable. And I started asking myself: can\u0026rsquo;t I delegate at least part of this work?\nJules Orchestrator # I built an architecture I called Jules Orchestrator. The name comes from Google\u0026rsquo;s AI agent that I use under the hood: Jules.\nThe idea is simple: when an issue comes in on GitHub, a webhook triggers the orchestrator which analyzes the context, passes everything to AI, and if the AI proposes a sensible solution, it implements it and opens a PR. If tests pass, the PR is ready for review.\nHere\u0026rsquo;s the diagram:\ngraph TD A[User Report / Issue] --\u003e|Webhook| B(Ingestion) B --\u003e|Trigger| C{Analysis Module} C --\u003e|Scan Codebase| D[Context Extraction] D --\u003e|Prompts + Context| E[Jules Agent] E --\u003e|Reasoning| F[Proposed Solution] F --\u003e|Code Generation| G[Implementation] G --\u003e|Run Tests| H{Verification} H --\u003e|Pass| I[Create Pull Request] H --\u003e|Fail| E I --\u003e|Review| J[Developer Review] J --\u003e|Approve \u0026 Merge| K[CI/CD Pipeline] K --\u003e|Automatic Deploy| L[Production] L --\u003e|Feedback Loop| A How It Works in Practice # Ingestion - An issue or bug report comes in, the webhook fires. Analysis - The devtriage module reads the report and scans the codebase to understand context. Agent Activation - Jules receives everything and starts reasoning. The interesting part is that it can understand dependencies between files and evaluate the impact of changes. Implementation - If it finds a solution, it generates the code. Verification - Tests run automatically. Pull Request - If tests pass, PR opened. Otherwise, it retries. What I Learned # This stuff doesn\u0026rsquo;t replace the developer—at least not yet. But it freed up my time. The trivial bugs, the ones you already know how to fix but that steal half an hour each, are now handled by AI. I do PR reviews and focus on architectural problems, which are the ones that actually require my experience.\nThe other thing I noticed is that AI can also handle routine maintenance: library updates, small refactors, minor security fixes. Stuff I used to pile up in the backlog for months.\nFinal Thoughts # We\u0026rsquo;re just at the beginning of this story. Jules Orchestrator works well for Luciosoft, but every project is different. If you\u0026rsquo;re interested in experimenting, the code is on GitHub.\nOh, and if you\u0026rsquo;re thinking \u0026ldquo;but this makes developers useless\u0026rdquo;: no. It makes them more efficient. Which is different. At least as long as someone still needs to figure out what to build and why.\n","date":"3 February 2026","externalUrl":null,"permalink":"/coding/apps-developed-and-maintained-by-ai/","section":"Coding","summary":"How I delegated bug triage to AI and finally started sleeping better.","title":"Apps Developed and Maintained by AI: Where Are We Heading?","type":"Coding"},{"content":"","date":"3 February 2026","externalUrl":null,"permalink":"/tags/automation/","section":"Tags","summary":"","title":"Automation","type":"tags"},{"content":"","date":"3 February 2026","externalUrl":null,"permalink":"/tags/devops/","section":"Tags","summary":"","title":"DevOps","type":"tags"},{"content":"","date":"3 February 2026","externalUrl":null,"permalink":"/tags/devtriage/","section":"Tags","summary":"","title":"DevTriage","type":"tags"},{"content":"","date":"3 February 2026","externalUrl":null,"permalink":"/tags/jules/","section":"Tags","summary":"","title":"Jules","type":"tags"},{"content":"","date":"22 January 2026","externalUrl":null,"permalink":"/tags/mlkit/","section":"Tags","summary":"","title":"MLKit","type":"tags"},{"content":"","date":"22 January 2026","externalUrl":null,"permalink":"/tags/ocr/","section":"Tags","summary":"","title":"OCR","type":"tags"},{"content":" How It All Started # A few years ago, my mom started running a small B\u0026amp;B. Naturally, as the \u0026ldquo;tech-savvy son\u0026rdquo;, I became her unofficial IT support. You know how it goes. Among the many things she asked me to \u0026ldquo;fix\u0026rdquo;, there was this guest registration process. For context: in Italy, every accommodation must report guest data to the State Police within 24 hours of arrival.\nI\u0026rsquo;m not gonna lie, the first time I watched her manually copy passport data into the Alloggiati Web portal, I nearly lost it. I thought: it\u0026rsquo;s 2026 and we\u0026rsquo;re still doing this by hand? There has to be a better way.\nThe Technical Problem # The Alloggiati Web portal works, don\u0026rsquo;t get me wrong, but manual entry is slow and error-prone. Especially when you have foreign guests with complicated names, or those old Italian paper ID cards—the ones so worn out that even a handwriting expert would struggle to read them.\nAs a software architect now, I couldn\u0026rsquo;t resist: I started thinking about how to automate the whole thing. The basic idea was simple: scan the document, extract the data, format it, send it to the portal. Easy to say, a bit harder to do. As a software architect now, I couldn\u0026rsquo;t resist: I started thinking about how to automate the whole thing. The basic idea was simple: scan the document, extract the data, format it, send it to the portal. Easy to say, a bit harder to do.\nUnder the Hood # I built a multi-layer recognition system. This wasn\u0026rsquo;t a random choice—it came from real-world experience:\nGoogle MLKit (On-Device) - Works great for passports and electronic ID cards. It reads MRZ codes (those character strips at the bottom of documents) in milliseconds, all on-device so no data leaves the phone. This was a top priority for me.\nCustom Local Algorithm - But MLKit alone isn\u0026rsquo;t enough. I had to develop a specific algorithm for old Italian paper ID cards. I know those things well because I\u0026rsquo;ve seen every type come through my mom\u0026rsquo;s place. Reflections, folds, faded ink\u0026hellip; I had to handle it all.\nGemini Flash as Fallback - And when everything else fails? I integrated Gemini Flash as a last resort. Only if the user consents, the image gets analyzed by Google\u0026rsquo;s AI which can figure out even the most desperate cases. I think it\u0026rsquo;s a good balance between automation and privacy.\nA Note on Privacy # I want to be clear about something: data never passes through my servers. The app reads the document, extracts data locally, and sends it straight to the Police portal. No intermediate clouds, no databases. I made this choice from day one because it seemed like the only sensible thing to do with such sensitive data.\nTry It Out # The app is called Schedine Smart and it\u0026rsquo;s free. I built it first for my mom, then figured it might be useful for others too. If you run an accommodation and you\u0026rsquo;re tired of copying data by hand, let me know what you think.\nDownload for Android\niOS version is in the works, coming soon.\n","date":"22 January 2026","externalUrl":null,"permalink":"/alloggiati/send-to-police-guest-registration/","section":"Police","summary":"How a personal frustration turned into an app. OCR, MLKit, and a bit of AI to solve the guest registration nightmare.","title":"Schedine Smart: Guest Registration Made Actually Bearable","type":"Alloggiati"},{"content":"","date":"26 June 2020","externalUrl":null,"permalink":"/tags/plugin/","section":"Tags","summary":"","title":"plugin","type":"tags"},{"content":"","date":"26 June 2020","externalUrl":null,"permalink":"/tags/youtube/","section":"Tags","summary":"","title":"youtube","type":"tags"},{"content":"With this article I want to explain how to build an app for your personal youtube channel in 10 minutes. I did this basic project to create Italiano con Eli app, created for the YouTube channel Italiano con Eli. While I was developing the app I decided to generalize the solution so that it can retrieve any video to any Youtube channel. The complete and working application is available at the following link github. You can make a Fork or a Clone or use it as it or by modifying it as you like. If you like you can also put a like to my git project.\nRequired configuration # The only thing to do to be able to use it is to configure the connection to the Youtube API so that you can use the search for your channel videos. For a correct configuration you can follow the following steps:\nLog in to the Google Api Console with your Google Account if you don\u0026rsquo;t have it, create a new account.\nGo under projects and click on NEW PROJECT, enter the name and wait for google to create project.\nClick on the link in the Google API library and search or select the youtube API as highlighted in the photo below\nClick on the link in the Google API library and search or select the youtube API as highlighted in the photo below\nafter click ability and go under the credentials menu item Select Youtube Api v3, select public data and confirm\nNow Google will create your api key\nthe api key recovered in step 6 will be inserted within the application and replaced the page main.dart instead of the key as follows:\nstatic String key = \u0026#34;\u0026#34;; // ** ENTER YOUTUBE API KEY HERE ** static String channelid = \u0026#34;UC_8mNVpafplqHNy85No4O2g\u0026#34;; // ** ENTER YOUTUBE CHANNEL ID HERE ** the channel id must refer to your youtube channel. You can simply extract it from the link of your youtube channel, taking the final part of the link:\nThe configuration is finished, you have just created your App for your personal Youtube channel! Yehaa!\nSome references to the code # To facilitate the development of the application I used the following two flutter plugins that you can find on flutter packages pages.\nThe plugins used are the following:\nyoutube player Flutter\nyoutube API\nthe application code is very simple and I have given apage division structure\nfairly clear:\nModel contains the model of data recovered from API youtube. Now the class also does something more, there is a method that also retrieves the data from youtube and inserts it in the model and some method to recover the data. There is also a system that recovers data only if it is not cached using the shared preference flutter. This mechanism is very useful as the Google API is paid according to the use. Using the cache will save you drastically in calls. if you have never used the cache in flutter you can read this mine other article: flutter shared preferences in depth.\nPages contains the APP pages\nhome page\ncategory page\nplay video page\nUI contains a widget to represent the list of videos. I created it separately as a widget to create a view that can be used on both the home page and category and I could also use it in other pages in the future.\n**Main.dart ** just to initialize view, the model class, load the youtube data and pass it to the respective pages.\nUsing this structure, the code is very simple to maintain, for example the home page contains only the following code:\nimport \u0026#39;package:flutter/material.dart\u0026#39;; import \u0026#39;package:youtubeapichannel/Model/YoutubeData.dart\u0026#39;; import \u0026#39;package:youtubeapichannel/UI/YoutubeVideoList.dart\u0026#39;; YoutubeData youtubeData; class Home extends StatefulWidget { Home(YoutubeData inyoutubeData) { youtubeData = inyoutubeData; } @override _HomeState createState() =\u0026gt; new _HomeState(); } class _HomeState extends State\u0026lt;Home\u0026gt; { callAPI() async { setState(() {print(\u0026#39;UI Updated\u0026#39;); }); } @override void initState() { super.initState(); //callAPI(); } @override Widget build(BuildContext context) { if(youtubeData!=null) return new YoutubeVideoList(youtubeData.getHomeList()); else return new Container(child:new Text(\u0026#34;problem loading data from youtube!\u0026#34;)); } } Then simply receive the class containing the list of videos as input and call the YoutubeVideoList plugin that is under the UI to represent them in the form of a list of YouTube videos.\nThe only flaw is that when I made it I was not so expert and I decided to pass the data as a parameter. Today flutter offers better technical provisions for passing data from one view to another, in fact I should make an update and do the usual refactor.\n","date":"26 June 2020","externalUrl":null,"permalink":"/coding/youtube_channel_android_and_ios_app_in_ten_minute_with_flutter/","section":"Coding","summary":"Create an Android and iOS app for any YouTube channel in 10 minutes with Flutter. Full source code, YouTube API setup, and caching included.","title":"Youtube Channel Android and Ios APP in ten minute with Flutter","type":"Coding"},{"content":"","date":"18 June 2020","externalUrl":null,"permalink":"/tags/optimization/","section":"Tags","summary":"","title":"optimization","type":"tags"},{"content":"We as programmers have different skills and we use lot of patterns, but I think the thing that we mature over time and we have more in common is the resources optimization for time saving. Everyone knows that time is the most important thing! The same way of saying it: time is money. The saying is based on human time. Human time must be used as an additional value for creativity, invention, construction innovation and implementation. We programmers are lucky, we have another measurement time unit, nowadays almost tending to infinity. This is machine time and we have to make the most of it.\nOnce we used slaves, then horses, mules, engines motor. Today we have evolved, culturally and mentally. The slaves of this era are machines. By machines I mean our PCs, or better yet our servers, the cloud or robots.\nI decided to write this article to report useful techniques to make our work more efficient and consequently have more time. My main technique to be used to obtain this result is:\nwrite down the manual steps that we perform to do a task\nsearch for possible alternative solutions\nreflect on how we can automate each single step\nreflect on how we can automate each single step\nput everything together\nstarting from point 1 if our time for the task is not equal to 0\nAn example # Often to speed up our work we write scripts, these scripts are necessary otherwise we would have to write n command statements. Daily or monthly or after doing something else, we have to do it. So let\u0026rsquo;s open the terminal and run the scripts. To avoid launching manual the script, which implies remembering, finding the script and launching it, we can proceed in the following way:\nif it is something that must be done with a fixed date\nSchedule it using a scheduler\nWith linux, we can make a cron\nWe can use atrigger to execute the scheduling in the event that our script is on a server to which we do not have access to server side\nIf instead there is no fixed scheduling date and we have to execute it as needed\nWe can use a keyboard shortcut. In linux but also on Windows it is very simple to set a shortcut. In my case using Ubuntu just go under *settings *-\u0026gt; keyboard shortcuts and add our new parameter that will count the path to our script and the desired shortcut. As you can see in the following image, I use it for example to debug my blog and then to deploy:\nas beautiful as it may seem and can help us make us more efficient, with two buttons, you\u0026rsquo;re done, yes can always optimize. Will you say, what else you can do to optimize this? and why? The reason is simple, in order to run it I necessarily need to have my machine available and turned on. So it would be better where you can always use a server or the cloud in order to do everything remotely so that you can have more control and above all not depend on a local machine.\nToday there are many tools available for us to run scripts or create small web pages or small applications or showcase sites, the free plan of these services, provides many tools including:\nHosting space\nDatabase space\nFunctions for microservices\nContainer\nVirtual machines\nand whoever has more put them\nThere are so many that sometimes we tend not to see them, despite being under our noses. The ones I use most are:\nFirebase\nGoogle Cloud\nAmazon AWS\nGoogle Script\nThe last service unlike the others is not a cloud service but simply an engine of functions that can be scheduled or activated in relation on google service. They are very integrated with our Google account and it will really give great potential to automate:\nmailing\ndata synchronization\ndocument editing\ncalling external API\nstoring data in excel\netc etc \u0026hellip; it\u0026rsquo;s bad to say etc etc but really, the list would be too long, it allows you to automate everything which is Google.\nThe other three are the top three best cloud providers. To begin with I recommend using Firebase because it offers so many services and it is simler and with a faster learning line.\nConclusions # We have to pay more attention to what we all do without thinking on it. If we do something repetitive every day, even if we take very little time to do it, let\u0026rsquo;s take it into consideration and think about it. After years, repetitive things can become many and we risk saturating all our time by doing only repetitive things. I leave you and greet you with a phrase that has come to me now. It probably doesn\u0026rsquo;t make sense or maybe it\u0026rsquo;s already of someone\u0026rsquo;s but I don\u0026rsquo;t know. It is better to create a system that solves a problem than to solve the problem itself!\n","date":"18 June 2020","externalUrl":null,"permalink":"/coding/save_time__do_more_things/","section":"Coding","summary":"Automate repetitive tasks with scripts, cron jobs, and cloud services like Firebase and Google Cloud. Practical tips to reclaim your time.","title":"save time = do more things","type":"Coding"},{"content":"","date":"18 June 2020","externalUrl":null,"permalink":"/tags/script/","section":"Tags","summary":"","title":"script","type":"tags"},{"content":"","date":"18 June 2020","externalUrl":null,"permalink":"/tags/timing/","section":"Tags","summary":"","title":"timing","type":"tags"},{"content":"","date":"5 June 2020","externalUrl":null,"permalink":"/tags/cloud/","section":"Tags","summary":"","title":"Cloud","type":"tags"},{"content":"There are many ways to secure our functions. This topic is not clear when you start using the Cloud Function and it is also constantly changing. I decided to implement my own method that uses the basic and simplest authentication, the Basic Auth. It certainly is not the safest method but it was enough for my purpose. The only flaw is that the function has to be added and implemented in every Cloud function that we make.This implementation then gives us the possibility to call our function from anywhere we want to by simply adding as a parameter of the request the user and the password encrypted in the Basic Auth.\nTo simplify the verification, I created a function that I place in each Cloud Function. This function does the parsing of the request data, verifies if there is a basic auth and, if present, it checks whether the user and password data match. Here is the code I used:\nvar compare = require(\u0026#39;tsscmp\u0026#39;) const checkAuth = async() =\u0026gt; { // parse login and password from headers const b64auth = (req.headers.authorization || \u0026#39;\u0026#39;).split(\u0026#39; \u0026#39;)[1] || \u0026#39;\u0026#39; const strauth = new Buffer(b64auth, \u0026#39;base64\u0026#39;).toString() const splitIndex = strauth.indexOf(\u0026#39;:\u0026#39;) const splitIndex = strauth.indexOf(\u0026#39;:\u0026#39;) const login = strauth.substring(0, splitIndex) const password = strauth.substring(splitIndex + 1) //function to validate credentials using https://www.npmjs.com/package/tsscmp //Prevents timing attacks using Brad Hill\u0026#39;s Double HMAC pattern to perform secure string comparison function check (name, pass) { var valid = true // Simple method to prevent short-circut and use timing-safe compare valid = compare(name, \u0026#39;user\u0026#39;) \u0026amp;\u0026amp; valid valid = compare(pass,\u0026#39;password\u0026#39;) \u0026amp;\u0026amp; valid return valid } if (!check(login, password)) { res.statusCode = 401 res.setHeader(\u0026#39;WWW-Authenticate\u0026#39;, \u0026#39;Basic realm=\u0026#34;example\u0026#34;\u0026#39;) res.end(\u0026#39;Access denied\u0026#39;) } } Then we can use the function within the method called by our Cloud Function in the following way:\nexports.helloWorld = async (req, res) =\u0026gt; { await checkAuth(); let message = req.query.message || req.body.message || \u0026#39;Hello World!\u0026#39;; res.status(200).send(message); }; And that\u0026rsquo;s it, our functions are now safe! Not much but it\u0026rsquo;s a starting point. So in the end if our system is breached,it is not a big problem, in this function we only return Hello World!\nHow do we instead call our function with Flutter? We simply have to create the Basic Auth with user and password and add it to the request as follows:\nvar basicAuth = \u0026#39;Basic \u0026#39;+base64Encode(utf8.encode(user:password\u0026#39;)); http.Response response = await http.get(apiUrl, headers: \u0026lt;String, String\u0026gt;{\u0026#39;authorization\u0026#39;: basicAuth}); print(response.statusCode); //200 print(response.body ); //Hello world! This method is not one of the best, however, it is very fast to implement and also gives us an advantage because it can be used in the same way from all Cloud providers. Finally, we can recall it from anywhere using any language, and it does not force us to use json keys that could be displayed.\nThe only problem I had was having the username and password inside the code that I didn\u0026rsquo;t really like. I solved it by putting these parameters within the firebase configurations. If you are interested in this, you can read this article Flutter 2 indispensable plugins with great potential.\n","date":"5 June 2020","externalUrl":null,"permalink":"/coding/fast_way_to_secure_your_function_with_basic_auth/","section":"Coding","summary":"Secure your Cloud Functions quickly with Basic Auth. Step-by-step JavaScript implementation and Flutter integration for cross-provider compatibility.","title":"Fast way to secure your Function with Basic Auth","type":"Coding"},{"content":"","date":"5 June 2020","externalUrl":null,"permalink":"/tags/secure/","section":"Tags","summary":"","title":"Secure","type":"tags"},{"content":"","date":"1 June 2020","externalUrl":null,"permalink":"/tags/firebase/","section":"Tags","summary":"","title":"Firebase","type":"tags"},{"content":"In the article shared preferences in depth, I explained how to use shared preferences in Flutter. In this article I want to show you a class that I designed to simplify its use. I created this class out of the need to store user data. For example, I used it in Send to Kindle to store a mail list. I also used it to store the user\u0026rsquo;s token list and to purchase data.\nOverall, this structure can be used where there is the need of working with a list of strings. In my previous article, I have already shown how to store a list of strings in local cache. This class, however, makes it even easier to use and adds methods that allow us to work faster.\nFirst, I created the method to save a local cache list as follows:\nclass CashedUserData { static Future\u0026lt;void\u0026gt; _writes = Future.value(); //add list by key reference in local cache static Future\u0026lt;void\u0026gt; addlist(String kPrefKey, List\u0026lt;String\u0026gt; stringList) async{ static Future\u0026lt;void\u0026gt; addlist(String kPrefKey, List\u0026lt;String\u0026gt; stringList) async{ _writes = _writes.then((void _) =\u0026gt; _doAddList(kPrefKey,stringList)); return _writes; } } static Future\u0026lt;void\u0026gt; _doAddList(String kPrefKey, List\u0026lt;String\u0026gt; list) async { List\u0026lt;String\u0026gt; cached = await load(kPrefKey); cached.addAll(list); await (await SharedPreferences.getInstance()).setStringList(kPrefKey, cached); } Then I created another method to retrieve the list, I have also put the appropriate checks here, if empty or null:\nstatic Future\u0026lt;List\u0026lt;String\u0026gt;\u0026gt; load(String kPrefKey) async { return (await SharedPreferences.getInstance()).getStringList(kPrefKey) ?? []; } As I used it, I needed to add more methods. Methods to:\nClear the list.\nEnter one string at a time\nOverride the list\nCheck if an element exists\nTake the first item on the list.\nSave an item at the top of the list.\nIn this way the class eventually became like this:\nclass CashedUserData { static Future\u0026lt;void\u0026gt; _writes = Future.value(); static Future\u0026lt;void\u0026gt; overrideListData(String kPrefKey, List\u0026lt;String\u0026gt; stringList) async{ _writes = _writes.then((void _) =\u0026gt; _doOverrideListData(kPrefKey,stringList)); return _writes; } static Future\u0026lt;void\u0026gt; addlist(String kPrefKey, List\u0026lt;String\u0026gt; stringList) async{ _writes = _writes.then((void _) =\u0026gt; _doAddList(kPrefKey,stringList)); return _writes; } static Future\u0026lt;void\u0026gt; save(String kPrefKey, String id) async{ if(await CashedUserData.exist(kPrefKey, id)) return; _writes = _writes.then((void _) =\u0026gt; _doSave(kPrefKey,id)); return _writes; } static Future\u0026lt;void\u0026gt; saveAsFirst(String kPrefKey, String id) async{ List\u0026lt;String\u0026gt; actuaList = await load(kPrefKey); if(actuaList!=null \u0026amp;\u0026amp; actuaList.length == 0 ) return save(kPrefKey,id); if(actuaList.contains(id)) actuaList.remove(id); if(actuaList.length\u0026gt;1) actuaList.removeAt(0); List\u0026lt;String\u0026gt; newlist = new List(); newlist.add(id); newlist.addAll(actuaList); _writes = _writes.then((void _) =\u0026gt; _doOverrideListData(kPrefKey,newlist)); return _writes; } static Future\u0026lt;void\u0026gt; delete(String kPrefKey, String id) { _writes = _writes.then((void _) =\u0026gt; _doDelete(kPrefKey,id)); return _writes; } static Future\u0026lt;String\u0026gt; getFirst(String kPrefKey) async { List\u0026lt;String\u0026gt; dataList = (await SharedPreferences.getInstance()).getStringList(kPrefKey); return (dataList!=null \u0026amp;\u0026amp; dataList.length\u0026gt;0) ? dataList[0] : \u0026#34;\u0026#34;; } static Future\u0026lt;List\u0026lt;String\u0026gt;\u0026gt; load(String kPrefKey) async { return (await SharedPreferences.getInstance()).getStringList(kPrefKey) ?? []; } static Future\u0026lt;bool\u0026gt; exist(String kPrefKey, String id) async { List\u0026lt;String\u0026gt; userDataList = (await SharedPreferences.getInstance()).getStringList(kPrefKey) ?? []; return (userDataList!=null \u0026amp;\u0026amp; userDataList.length \u0026gt; 0) ? userDataList.contains(id) : false; } static Future\u0026lt;void\u0026gt; _doSave(String kPrefKey, String id) async { List\u0026lt;String\u0026gt; cached = await load(kPrefKey); cached.add(id); await (await SharedPreferences.getInstance()).setStringList(kPrefKey, cached); } static Future\u0026lt;void\u0026gt; _doDelete(String kPrefKey, String id) async { List\u0026lt;String\u0026gt; cached = await load(kPrefKey); cached.remove(id); await (await SharedPreferences.getInstance()).setStringList(kPrefKey, cached); } static Future\u0026lt;void\u0026gt; _doAddList(String kPrefKey, List\u0026lt;String\u0026gt; list) async { List\u0026lt;String\u0026gt; cached = await load(kPrefKey); cached.addAll(list); await (await SharedPreferences.getInstance()).setStringList(kPrefKey, cached); } static Future\u0026lt;void\u0026gt; _doOverrideListData(String kPrefKey, List\u0026lt;String\u0026gt; list) async { await (await SharedPreferences.getInstance()).setStringList(kPrefKey, list); } static update(String kPrefKey, String currentItem, String kindlemail) async{ List\u0026lt;String\u0026gt; actuaList = await load(kPrefKey); if(actuaList!=null \u0026amp;\u0026amp; actuaList.length \u0026gt; 0 ) { try{actuaList[actuaList.indexOf(currentItem)] = kindlemail;} catch (e) {} } await overrideListData(kPrefKey, actuaList); } } By doing this I simplified the call points. Furthermore, if the plugin shared preference used changed, there would only be one place where to take action.\n","date":"1 June 2020","externalUrl":null,"permalink":"/coding/flutter_useful_class_for_shared_preferences/","section":"Coding","summary":"A reusable Flutter class to simplify Shared Preferences management with add, delete, update, and cache operations for string lists.","title":"Flutter useful class for shared preferences","type":"Coding"},{"content":"","date":"26 May 2020","externalUrl":null,"permalink":"/tags/ads/","section":"Tags","summary":"","title":"ads","type":"tags"},{"content":"","date":"26 May 2020","externalUrl":null,"permalink":"/tags/android-app/","section":"Tags","summary":"","title":"android app","type":"tags"},{"content":"","date":"26 May 2020","externalUrl":null,"permalink":"/tags/gain-money/","section":"Tags","summary":"","title":"gain money","type":"tags"},{"content":"When we have an idea for an App, there are many questions that come to our mind, the first ones are:\nIs this app already on the market?\nCan this idea work?\nHow much does it cost to develop it?\nHow much can we earn?\nHow to monetize this idea?\nHow to monetize this idea?\nIn this article I want to talk about how to monetize. There are many ways and many tools that allow us to monetize, I want to report here my experience, my mistakes and suggestions on how to use these tools at the best.\nWhen I started, I had no clear idea. My main goal was not to earn money but to set up a self-sustainable service, which had no costs or costs very close to zero, so that I could afford to sell the service at a low price.\nFirst step # The first thing to do is to identify our potential audience, to do this I recommend using Google adWords or Facebook Ads. These tools are great to understand what our potential audience might be. To do this we must enter the keywords of our App services, select the age range and the countries involved. The result we get from this analysis is the total number of potential users and the country with the highest percentage of use. It could help us identify our competitors and understand what is their audience like and what sets us apart.\nEarning tools # It is time to establish our monetization method; there are really many different ways and choosing one of them depends on our type of business. However, the most used ones and the most adaptable in the world of Mobile Apps are the following:\nAdvertising\nProducts and Subscriptions in the app\nSales and data analysis\nAdvertising: # Although one of the largest web giants in the world Google earns only or almost with advertising, the latter is not, in my opinion, a good tool to be used in all contexts, I believe it has the following problems:\nIt is not appropriate at the beginning\nThe profit is very low unless you have many users\nThe product must attract and involve the user for some time.\nThere is the risk of being too annoying and could ruin the user experience.\nThe simplest advertising to implement with Flutter is the same used in google, therefore Google AdMob.\nSale of products: # if you decide to put your App on sale, you have various sales options available through the Google play console, including:\n**The price related to the App download **\nThis allows us to set a price for the App download. This is the simplest thing to implement, as we only have to just set the price of the app inside the console. Once done, we can be over with it unless we want to put a further check inside the app to prevent people from creating pirated copies of our app and from buying it. In my opinion setting a price from the beginning is now outdated, people do not trust buying in the dark. Although they can always ask for a refund, I think it is still an obstacle to impose a price from the beginning. It certainly makes sense for some apps, it is often used for the pro version of the app.\nProducts in the App\nThis type of product gives access to a free version of the application and makes the products available within the app itself. In this case, however, in addition to defining the various products, choosing and setting the various prices, we must also develop a piece in our app to retrieve the products from the Google Play Store in order to be able to show the products. Although libraries and plugins are available, we still have to develop it in order to use it.\nSubscriptions in the App\nSubscriptions are very similar to products with the difference that they have an expiring date and therefore have a temporal validity.\nDifferences between Products and Subscriptions # The product in the App can be used only once, expended immediately, or it could be used forever: it actually depends on the value that we decide to assign in our app. Once bought, it unlocks something. The subscription instead has a specific deadline, therefore it includes the same behavior as the base product but has a duration that can be weekly, monthly, three-monthly and annual.\nHow much do you really earn from selling on google play store? # This is something that is not known at first. As in normal life, when money is involved, everyone has to earn it. By \u0026ldquo;everyone\u0026quot;in this case I mean Google and the state. Google offers:\na showcase\na store\nrefund management\nprice management\ncurrency normalization\ntaxes in all countries of the world.\nAnd lot of other stuff\nAlthough the 95% of this service is completely automatic, it has to be paid. But the interesting thing is that the percentage that Google takes is about 30% of the price of our app. the percentage due to the State instead depends on the country of reference of the purchase. Example: if we sell an app with a cost of 2 euros, our actual net profit will be around 1 Euro. Instead if we subscribe the percentage due to Google changes and drops to 15%. But why does Google encourages us to sell subscriptions? It does not take long to get there, once we have sold the product, we won’t have any further earnings. The subscription instead is forever.\nWe establish the price # It is not easy to establish the right price but it is very important to choose it properly. The main mistake I made, and I believe many people commit, is the fact that we underestimate the product we have developed. Since we have been working on it for a long time and know it well, we tend to underestimate it. From my experience, I understood that the right way to define it is to multiply by 3 or 4 the price that I would be willing to pay. Google play console allows you to enter different prices for each country, although some countries are richer and more willing to pay for an App, I decided to put the same price for everyone, in my case I think it\u0026rsquo;s right. Also because it is a very low price. In addition, the App send to kindle is intended for the owners of a kindle who therefore can be willing to pay a few euros for a convenient feature.\nWe define the strategy # This I think is the most complicated part and depends a lot on the type of app or service that we have implemented. Consider send to kindle I can ask myself this question: Can I earn only with advertising? Although my audience is growing and can become very large for now, the answer is no and I believe it will be no also in the future. Why? I decided to make the app bloody fast and therefore the user interaction is too short. The user enters, sends the content to the kindle and he is done. He has nothing else to do in my app.\nSo the choices I could follow were the following:\nSuggest something else related to the context\nUse a different tool rather than advertising.\nIn the end I decided not to use advertising as the main income. So why did I use it anyway? I used advertising as an element of annoyance and boredom. Yes you got it right! boredom, I created a system in a way that every three submissions, you are forced to watch an advert video, in order to continue. People can continue watching videos, but sooner or later they will get so bored with watching advertising videos that they will decide to consider removing the advertisements.\nIn addition to converting articles, send to kindle also converts pdfs and various ebook formats. I recently decided to introduce a subscription for this. It allows you to perform an infinite number of conversions for a year. I decided to put a subscription because the conversion uses a container in the cloud and I have costs for the cloud service to be paid every month. In this way, if my users had to subscribe, I would receive something every year which, I hope, will be useful in order to pay for the cloud service and also earn something. As long as you\u0026rsquo;ll find it in the app store means it\u0026rsquo;s working;)\nConsiderations # In these days almost everyone is trying to offer a service using a subscription. This is because in the long run it is the most profitable. In my opinion, every app and every system need the right considerations and choices. I think a lot of people today can understand and are more likely to buy a product on time rather than signing up for a subscription. People don’t like the subscription, moreover it must be well motivated and you have to think about how to sell it and make everyone understand the advantages that they get. However, do not bandage your head too much, the price is not forever. Google play console, allows you to change the price at any time. If the person works well and the app grows, the value of the latter grows so it is correct to increase the price and add new features that open new doors to new earnings.\n","date":"26 May 2020","externalUrl":null,"permalink":"/strategie/how_to_earn_money_with_your_app/","section":"Strategies","summary":"Explore app monetization strategies: ads, in-app purchases, and subscriptions. Real-world pricing tips and lessons from Google Play Store.","title":"How to earn money with your app","type":"strategie"},{"content":"","date":"26 May 2020","externalUrl":null,"permalink":"/tags/in-app-purchase/","section":"Tags","summary":"","title":"In App Purchase","type":"tags"},{"content":"","date":"26 May 2020","externalUrl":null,"permalink":"/strategie/","section":"Strategies","summary":"","title":"Strategies","type":"strategie"},{"content":"","date":"22 May 2020","externalUrl":null,"permalink":"/tags/kindle/","section":"Tags","summary":"","title":"kindle","type":"tags"},{"content":"","date":"22 May 2020","externalUrl":null,"permalink":"/kindle/","section":"Kindle","summary":"","title":"Kindle","type":"Kindle"},{"content":"Today I want to tell you a story, the story of my creation and the project that has brought me more success and satisfaction to date.\nLet\u0026rsquo;s start from the dawn # I was born and especially raised in the digital age and I have always been in contact with technology. Unfortunately I have never had an excellent relationship with books, I believe and I hope to be able to catch up in the future. This bad relationship with books, however, has led me to the success I\u0026rsquo;m about to tell you. A long time ago, being frustrated by the fact that I wasn\u0026rsquo;t reading enough, I decided to buy a Kindle thinking that would give me new reading opportunities.\nThe Kindle indeed gave me different satisfactions, I have read several books but my main use has always been to read online articles retrieved from the web. I used to read programming, technology, science and math articles. Yes, as you have already understood, I am not a writer and least of all a philosopher, I write because I like it but I don\u0026rsquo;t think I can do it well as I haven’t studied subjects related to writing.\nOk, I\u0026rsquo;m too long-winded now! But why did I tell you this story? Why was the Kindle the cornerstone of my success? Since I appreciated its skills so much, I decided to recommend it to many of my friends and relatives. I also recommended it to a close colleague of mine, with whom we often given each other suggestions on how to get the most out of the kindle. The app that we used most was a smartphone app that allowed us to send items to the kindle. One day this app stopped working and disappeared from the store in a mysterious and unknown way. There were other apps in the store that did this, but they didn\u0026rsquo;t work very well and some of them weren’t free. My colleague and I were somewhat frustrated by this.\nMy colleague # My colleague # One day my colleague tells me: why don\u0026rsquo;t you make the app to send content to the kindle? I thought about it for a moment, I wasn\u0026rsquo;t sure from where to start, but then I said to myself: I\u0026rsquo;m a programmer and I have the basics … I can do it! This is how Send To Kindle was born. Today I owe a lot to my dear colleague and to his question.\nWhen I released the first version of the app, it was very spartan, I implemented it for myself, my friends/relatives and especially for my colleague. I did not believe and I could never imagine that today, one year after its creation, I would have reached more than 70,000 installations worldwide and this number grows daily.\nWhat have we learned? # This app made me grow in a short time and made me understand many things that I want to summarize and share with you:\nIf don\u0026rsquo;t try, you don\u0026rsquo;t succeed Sometimes we think about it too much or we wait for perfection before releasing something. Instead, in many cases, it is better to throw it there and then if it works we are always in time to update it and add new features.\nThe more you do/work on it and the more chances you have to succeed\nIf you succeed you have to run like crazy\nIt is Impossible to satisfy everyone\nEven if you have thought and worked to the smallest details, once your app or your site begin to mesh and populates with users, your problems will begin and that\u0026rsquo;s where you have to do your best in order not to lose your users.\nIt is Impossible to satisfy everyone Every user has his own needs and it is not possible to make a generic product that will satisfy everyone.\nDon\u0026rsquo;t follow too much and evaluate user requests well I tried it on my skin, users may never be satisfied! An example, Send To Kindle in the first period only used to send articles. All the negative reviews said: the app doesn’t send documents/files. So I implemented the sending of documents which cost me time and money. Now, what do you think users say? Some are satisfied but many others always put a star and say: it doesn’t send files larger than 25 mb. In your opinion, if I ever increase this limit what will they say?\nDo many frequent releases\nEven if one day everything goes well, always think that the next day everything will be st**\nPay attention to the answers given to customers\nAlways be updated with the moves of your competitors\nContinue to update and innovate\nFinal considerations # I am aware of the fact that Send To Kindle is not an unusual invention or an innovation. In fact, I did not invent something completely new, I improved something that was already there with new technologies and I made it more efficient. I think my strong point is that I made the mobile service accessible. Sometimes it takes little to be successful, you just need to be better than your competitors. Certainly, a lot of effort and a lot of work are needed to do it. Congratulations if you\u0026rsquo;ve read this far!!! if you haven’t done it yet, download Send To Kindle, and send this article or other articles to you kindle! Have a better reading and relaxing experience!\n","date":"22 May 2020","externalUrl":null,"permalink":"/kindle/send_to_kindle_mobile_the_story/","section":"Kindle","summary":"The origin story of Send To Kindle app — from a colleague\u0026rsquo;s idea to 70,000+ installs. Key lessons learned about app development and user feedback.","title":"Send To Kindle Mobile the story","type":"Kindle"},{"content":"","date":"19 May 2020","externalUrl":null,"permalink":"/tags/chatbot/","section":"Tags","summary":"","title":"ChatBot","type":"tags"},{"content":"","date":"19 May 2020","externalUrl":null,"permalink":"/tags/dialogflow/","section":"Tags","summary":"","title":"DialogFlow","type":"tags"},{"content":"In these days, I wanted to experiment and deepen my knowledge in the field of chatbot, I made this choice because at this moment, this technology is widely used and really growing.\nA little theory # Chatbots have been around for a long time, really for a long time, they date back to the early 60s70s with ELIZA and PARRY. These two projects were born for the purpose of creating a simulated conversation with a machine. In many cases, these two chatbots have managed to deceive the people involved, but using very vague but intelligent answers.\nThese two projects, however, despite being classified as chatbots, were very stupid, they do not have the same conception of today\u0026rsquo;s chatbot. The software behind the old chatbots was very simple, we can see it as a one-to-one mapping (question -\u0026gt; answer). There was no interpretation of the question. Most modern Chatbots, on the other hand, use natural language that we can imagine with the composition of three main elements:\nlexical analysis (decomposition of sentence into token)\ngrammatical analysis (association of parts of speech)\ngrammatical analysis (association of parts of speech)\nsyntactic analysis (token arrangement in a tree structure)\nanalysis semantics (assigning a meaning)\nThus described it seems simple and we as humans are able to do it without knowing the existence of all these steps. Teaching a machine how to process the steps listed above is really difficult. Especially the last point of the semantic analysis.\nNowadays the most common Chatbots that we use without realizing it are Ok Google, Alexa, Siri, Cortona and every day there are more and more new ones. The growing areas where they are most used are banks, customer service and e-commerce.\nBut why are chatbots called by personal names? # I have not found this answer online but I believe the answer is simple. As we have to interact with something with human features, what could be the best way to do it, if not to give a name with which we can call it? Almost all interactions with other people begin with the person\u0026rsquo;s first name, it is needed to request his/her attention.\nWhat\u0026rsquo;s behind the hood? # But what\u0026rsquo;s behind these Chatbots? In the case of Ok Google, the service in the background is just DialogFlow, This service made available to everyone, allows everyone in an agile way to create a real chatbot in a few steps and without any programming knowledge, the concept is very easy, it is basically based on the creation of intents and answers.\nI will explain in this article how to use DialogFlow and how to implement it using Flutter. Why Flutter? Because I think it is really growing at the moment. The project is growing so much that it is compatible with many platforms. In particular, it works natively on Android and IOS and works really well, according to the tests made, it has performances almost equal to the native languages ​​(Java / Swift / c ++). Although still in Beta, the Web function is going great, and it also works for desktop environments (linux and Windows). What is missing? Just TV and Smartwatch, I believe that the support will arrive shortly!\nCan you show me the code? # I don\u0026rsquo;t want to go in detail in DialogFlow configuration, there are really many good tutorials that explain the setup and how to use it. I assume that you have Flutter installed. If you haven’t, you can start from this guide. After installing Flutter, since its conception is Mobile, if you want to compile also for web you must execute the following commands:\n//enable web flutter versione flutter channel master flutter upgrade flutter config --enable-web //new web project and run in chrome cd into project directory flutter create . flutter run -d chrome Once the web version of flutter has been enabled and the project has been created, we can proceed by update the pubspec.yaml file. This file contains the configurations and dependencies to the plugins that we use in our project. We must therefore add the dependencies to DialogFlow, the compatible version for both web and mobile is as follows:\nflutter_dialogflow: ^0.1.3 assets: - assets/yourapifile.json We must also add in the assets the json file downloaded from google cloud relating to the service account that has access to the DialogFlow project. The implementation of dialog Flow requires very little, just a few lines of initialization code:\ndialogFlow.AuthGoogle authGoogle = await dialogFlow.AuthGoogle(fileJson:\u0026#34;assets/yourapifile.json\u0026#34;).build(); dialogflow = dialogFlow.Dialogflow(authGoogle: authGoogle); Finally we have to ask DialogFlow to process the intent in order to receive a response, do this with the following line of code:\ndialogFlow.AIResponse response = await dialogflow.detectIntent(query); print(response.getMessage()); The whole working implementation can be found at the following link Github. In order to use it, you only need to add your service account Json key, which you will have to create on Google Cloud and associate it with DialogFlow.\nfinal result screen:\n","date":"19 May 2020","externalUrl":null,"permalink":"/coding/when_flutter_meat_dialogflow_born_a_multi_platform_chatbot/","section":"Coding","summary":"Build a multi-platform chatbot using Flutter and DialogFlow. From chatbot history to a working implementation for Android, iOS, and web.","title":"When Flutter meat DialogFlow born a multi platform ChatBot","type":"Coding"},{"content":" Prerequisites # This article requires a good knowledge of the following topics that you can study at the following links:\nFirebase Remote Config\nFlutter Shared Preferences\nWhy are we talking about these two plugins that would see having nothing in common? i With this guide I will show you how to benefit from this two plugins and how to save money using the free services offered by Firebase! :)\nIn the talian with Eli app, created for the youtube channel Italian with Eli, I created a project on Firebase, so you can use the remote config and other potential that Firebase makes available for you. The app takes care of showing a video list from the youtube channel, if interested you can download the source code on github, you can use it with any youtube channel.\nTo make the Italian with Eli app more original I thought of adding questions to the videos on the topics covered in the videos. So I needed a place to save the question data. With Firebase, the most logical and also most direct thing would be to use Realtime Database or Firestore. I thought of using remote config! Yes you got it right remote config! You will be thinking \u0026ldquo;this guy is crazy\u0026rdquo; and “why is he doing that?” I fully share with you this thought… there is a bit of madness in the choice made. The reason why I thought of using remote config is the following:\nI didn\u0026rsquo;t have much time available\nremote config is free and has no limitation of use\nyou can give access to the service to an external person\nthe other choices would have led me to have to also build a back end interface to allow the census of the questions\nI had already used remote config and I would have been faster in the implementation.\nBut how does a service not born with this scope work? It works very well indeed, I must say that I was surprised by the responsiveness that shows the app and the system that I put up. To make it work so well, however, I had to put the two plugins together in the way that I explain below. Inside the remote config console I\u0026rsquo;m going to insert a new parameter for each video.\nIn the name field I insert the id of the youtube video and inside the parameter a json containing the questions and answers structured as follows:\n{ \u0026#34;Playlist\u0026#34;: \u0026#34;PLsrqydfBIVzy9IMGwSQieTVeSWC7cRCnN\u0026#34;, \u0026#34; Questions \u0026#34;: [ { \u0026#34; question \u0026#34;:\u0026#34; How do you say how much is it ??: \u0026#34;, \u0026#34; answare \u0026#34;: [ \u0026#34; How much does it cost? \u0026#34;, \u0026#34; How much does it cost? \u0026#34;, \u0026#34; How much does it cost? \u0026#34; ] }, { \u0026#34;question\u0026#34;: \u0026#34;How do you say how much are they ?:\u0026#34;, \u0026#34;answare\u0026#34;: [ \u0026#34;How much do they cost?\u0026#34;, \u0026#34;How much do you cost?\u0026#34;, \u0026#34;both / both\u0026#34; ] }, { \u0026#34;question\u0026#34; : \u0026#34;Choose the correct option\u0026#34;, \u0026#34;answare\u0026#34;: [ \u0026#34;How much does this computer cost? 300 Euros\u0026#34;, \u0026#34;How much computer does it cost? 300 Euros\u0026#34;, \u0026#34;How much does this computer cost?\u0026#34; ] }, { \u0026#34;question\u0026#34;: \u0026#34;How much does it cost? is\u0026#34;, \u0026#34;answare\u0026#34;: [ \u0026#34;singular\u0026#34;, \u0026#34;plural\u0026#34; ] } ] } In addition, firebase provides an easy insertion that also performs json validation, this allows us to edit more easily and not to make mistakes.\nIn the Flutter app I then built the Quiz object which contains the youtube id, a list of Questions and the Question will contain a list of Answers. With various useful management and constructor methods for deserializing Json data as follows:\nclass Answer { final String answerText; final bool isCorrect; Answer (this.answerText, this.isCorrect); } class Question { final String question; final List \u0026lt;Answer\u0026gt; answers; Question (this.question, this.answers); } class Quiz { List \u0026lt;Question\u0026gt; _questions; int _currentIndex = -1; int _score = 0; String _videoId; Quiz.fromJson (String videoId, String jsonInput) { _videoId = videoId; _questions = new List \u0026lt;Question\u0026gt; (); var jsonQuestions = json.decode (jsonInput); jsonQuestions [\u0026#39;Questions\u0026#39;]. forEach ((quest) { List \u0026lt;Answer\u0026gt; answers = new List \u0026lt;Answer\u0026gt; (); bool iscorrect = true; quest [\u0026#39;answare\u0026#39;]. forEach ((ans) { // put the first to true answers.add (new Answer (ans, iscorrect)); iscorrect = false; }); answers.shuffle (); _questions.add (new Question (quest [\u0026#39;question\u0026#39;], answers)); }); } Quiz (this._questions) { _questions.shuffle (); } List \u0026lt;Question\u0026gt; get questions =\u0026gt; _questions; int get length =\u0026gt; _questions.length; int get questionNumber =\u0026gt; _currentIndex + 1; int get score =\u0026gt; _score; Question get nextQuestion { _currentIndex ++; if (_currentIndex\u0026gt; = length) return null; return _questions [_currentIndex]; } Question get prevQuestion { _currentIndex--; if (_currentIndex \u0026lt;0) return null; return _questions [_currentIndex]; } String get correctAnsware { return _questions [_currentIndex] .answers.where ((x) =\u0026gt; x.isCorrect == true) .first.answerText; } void answer (bool isCorrect) { if (isCorrect) _score ++; } saveScore () async { SharedPreferences preferences = await SharedPreferences.getInstance (); preferences.setInt (\u0026#34;OK\u0026#34; + _ videoId, this.score); preferences.setInt (\u0026#34;KO\u0026#34; + _ videoId, this.length - this.score); //preferences.setString(_videoId, \u0026#34;{\u0026#39;questions\u0026#39;: \u0026#39;\u0026#34; + this.length.toString () + \u0026#34;\u0026#39;, \u0026#39;score\u0026#39;: \u0026#39;\u0026#34; + this.score.toString () + \u0026#34;\u0026#39;}\u0026#34;); } } The app first retrieves the list of videos via the youtube API, then retrieves the relative json from remote config using the video id and passes it to the constructor of the object that deserialize and you\u0026rsquo;re done. Once the app was completed, however, I realized that youtube provides a limited number of daily API calls. Moreover I thought it was useless every time I opened the app that it had to call the Youtube API. The videos, moreover, do not change as much as the channel makes a new video a week.\nTo solve the problem of Youtube API calls and make everything more responsive, I decided to save everything in a list of cached json strings using the Shared Preferences. Finally I added a parameter in the remote config containing a date.\nIn this way I made a mechanism that allows me to update the contents on the devices only if the date is more recent than the one stored in the cache of the single device itself:\nclass YoutubeData { RemoteConfig remoteConfig; String apikey; List \u0026lt;YoutubeDto\u0026gt; allYoutubeVideoList = []; List \u0026lt;YoutubeDto\u0026gt; getHomeList () { return List \u0026lt;YoutubeDto\u0026gt; .from (allYoutubeVideoList.where ((item) =\u0026gt; item.kind == \u0026#34;video\u0026#34; \u0026amp;\u0026amp; item.id! = Item.channelId)); } List \u0026lt;YoutubeDto\u0026gt; allCategory () { return List \u0026lt;YoutubeDto\u0026gt; .from (allYoutubeVideoList.where ((item) =\u0026gt; item.kind == \u0026#34;playlist\u0026#34; \u0026amp;\u0026amp; item.id! = Item.channelId)); } List \u0026lt;YoutubeDto\u0026gt; getCategoryVideoList (String plylistID) { return List \u0026lt;YoutubeDto\u0026gt; .from (allYoutubeVideoList.where ((item) =\u0026gt; item.kind == \u0026#34;video\u0026#34; \u0026amp;\u0026amp; item.id! = Item.channelId \u0026amp;\u0026amp; item.playlist == plylistID)); } YoutubeData (this.apikey, this.remoteConfig); checkAndLoad () async { SharedPreferences preferences = await SharedPreferences.getInstance (); List \u0026lt;String\u0026gt; videoIDList = preferences.getStringList (\u0026#34;VideoIdList\u0026#34;); DateTime lastUpdateDate, updateDate; String date = remoteConfig.getString (\u0026#34;UpdateDatetime\u0026#34;); updateDate = DateTime.parse (date); if (preferences.getString (\u0026#34;LastUpdateDatetime\u0026#34;)! = null \u0026amp;\u0026amp; preferences.getString (\u0026#34;LastUpdateDatetime\u0026#34;). isNotEmpty) lastUpdateDate = DateTime.parse (preferences.getString (\u0026#34;LastUpdateDatetime\u0026#34;)); else lastUpdateDate = DateTime (2010); if ((videoIDList == null || videoIDList.length == 0) || updateDate.isAfter (lastUpdateDate)) { await loadYtDataAndStoreInSharedPref (); preferences.setString (\u0026#34;LastUpdateDatetime\u0026#34;, DateTime.now (). toString ()); } await loadLocalDataAndAddQuestion (); } loadYtDataAndStoreInSharedPref () async { YoutubeAPI ytApi = new YoutubeAPI (apikey, maxResults: 50); List \u0026lt;YT_API\u0026gt; ytResult = await ytApi.channel (remoteConfig.getString (\u0026#39;ChannelId\u0026#39;)); // save the video count in shared pref SharedPreferences preferences = await SharedPreferences.getInstance (); preferences.setInt (\u0026#34;TotVideo\u0026#34;, ytResult.length); // save json youtube video in shared pref andvideo list YoutubeDtoyoutubedto = new YoutubeDto (); List \u0026lt;String\u0026gt; videoIdList = new List \u0026lt;String\u0026gt; (); for (var result in ytResult) { videoIdList.add (result.id); String json = jsonEncode (youtubedto.yApitoJson (result)); preferences.setString (result.id, json); } preferences.setStringList (\u0026#34;VideoIdList\u0026#34;, videoIdList); } // add the questions to the previously saved youtube objects loadLocalDataAndAddQuestion () async { SharedPreferences preferences = await SharedPreferences.getInstance (); List \u0026lt;String\u0026gt; videoIDList = preferences.getStringList (\u0026#34;VideoIdList\u0026#34;); allYoutubeVideoList = new List \u0026lt;YoutubeDto\u0026gt; (); int cntQuestion = 0; for (String videoID in videoIDList) { String jsonYoutube = preferences.getString (videoID); Map userMap = jsonDecode (jsonYoutube); YoutubeDto youtubeDao = new YoutubeDto.fromJson (userMap); youtubeDao.questionJson = remoteConfig.getString (\u0026#34;_\u0026#34; + videoID.replaceAll (\u0026#34;-\u0026#34;, \u0026#34;_trattino_\u0026#34;)); if (youtubeDao.questionJson! = null \u0026amp;\u0026amp; youtubeDao.questionJson.isNotEmpty) { cntQuestion = cntQuestion + \u0026#39;question\u0026#39;.allMatches (youtubeDao.questionJson) .length; youtubeDao.playlist = json.decode (youtubeDao.questionJson) [\u0026#39;Playlist\u0026#39;]; } allYoutubeVideoList.add (youtubeDao); } preferences.setInt (\u0026#34;TotQuestion\u0026#34;, cntQuestion); } } Below you can see an example of how it works:\n","date":"16 May 2020","externalUrl":null,"permalink":"/coding/flutter_2_plugin_necessary_with_great_potentiality/","section":"Coding","summary":"Combine Firebase Remote Config and Shared Preferences in Flutter to build a free, responsive quiz system with smart caching for your app.","title":"Flutter 2 plugin necessary with great potentiality","type":"Coding"},{"content":" # What is shared_preferences where, when and how much to use it? # The shared_preference is a plugin that allows you to save data app dedicated memory, the folder that will contain this data is named in Android with the package name of your app, e.g. com.companyname.appname.\nThe data that we can store in this space with this plugin are data of these types:\nString\nInteger\nBool\nList\nIt should be noted that these parameters are not persistent, they remain in the area dedicated to the app therefore are eliminated when the app is uninstalled or if the app cache data is removed. So, in general it is right to store non-essential preference data so that it is not a tragedy if they have been lost. A classic example can be the app theme color light or dark or the order of menu title.\nHow to use? # Saving: # import \u0026#39;package:shared_preferences/shared_preferences.dart\u0026#39;; SharedPreferences _preferences = await SharedPreferences.getInstance(); _preferences.setString(\u0026#34;theme\u0026#34;, \u0026#34;dark\u0026#34;); _preferences.setInt(\u0026#34;countaccess\u0026#34;, 2); Recovery: # import \u0026#39;package:shared_preferences/shared_preferences.dart\u0026#39;; SharedPreferences _preferences = await SharedPreferences.getInstance(); _preferences.getString(\u0026#34;theme\u0026#34;); _preferences.getInt(\u0026#34;countaccess\u0026#34;); At first we might think that it is of little use since in a string we cannot store a lot of information. In fact, if we think about it in a string, we can also store a lot but really a lot by using a json, below an example:\nimport \u0026#39;package:shared_preferences/shared_preferences.dart\u0026#39;; SharedPreferences _preferences = await SharedPreferences.getInstance(); _preferences.setString(\u0026#34;{\u0026#34;name\u0026#34;:\u0026#34;Andrea\u0026#34;,\u0026#34;surname\u0026#34;:\u0026#34;Luciano\u0026#34;,\u0026#34;age\u0026#34;:31,\u0026#34;sex\u0026#34;:\u0026#34;M\u0026#34;,\u0026#34;SurnameCouldBeName\u0026#34;:true}\u0026#34;); In this example I put SurnameCouldBeName as a field because my last name is also a first name. All those who don\u0026rsquo;t know me always ask me \u0026ldquo;Luciano is your name or surname?\u0026rdquo;\nAnd every time I would like to do something like that:\nWe can therefore create a collection of people using a list of strings instead of the single string as follows:\nimport \u0026#39;package:shared_preferences/shared_preferences.dart\u0026#39;; SharedPreferences _preferences = await SharedPreferences.getInstance(); List\u0026lt;String\u0026gt; users = new List\u0026lt;String\u0026gt;(); users.add(\u0026#34;{\u0026#34;name\u0026#34;:\u0026#34;Andrea\u0026#34;,\u0026#34;surname\u0026#34;:\u0026#34;Luciano\u0026#34;,\u0026#34;age\u0026#34;:31,\u0026#34;sex\u0026#34;:\u0026#34;M\u0026#34;,\u0026#34;SurnameCouldBeName\u0026#34;:true}\u0026#34;); users.add(\u0026#34;{\u0026#34;name\u0026#34;:\u0026#34;elisa\u0026#34;,\u0026#34;surname\u0026#34;:\u0026#34;luciano\u0026#34;,\u0026#34;age\u0026#34;:32,\u0026#34;sex\u0026#34;:\u0026#34;F\u0026#34;,\u0026#34;SurnameCouldBeName\u0026#34;:false}\u0026#34;); _preferences.setStringList(\u0026#34;users\u0026#34;, users); This could finally be mapped into an object in order to access the data simply and finally show it to the interface:\nClass UserDto() { String name, surname, age, sex, SurnameCouldBeName; UserDto.fromJson(Map\u0026lt;String, dynamic\u0026gt; json) : name= json[name], surname= json[surname], age= json[age], sex= json[sex], SurnameCouldBeName = json[SurnameCouldBeName]; } SharedPreferences _preferences = await SharedPreferences.getInstance(); List\u0026lt;UserDto\u0026gt; UserObj = new List\u0026lt;UserDto\u0026gt;; List\u0026lt;String\u0026gt; users = _preferences.getStringList(\u0026#34;users\u0026#34;); for(String userjson in users) { Map userMap = jsonDecode(userjson); UserDto = new UserDto.fromJson(userMap); print(UserDto.name); UserObj.add(UserDto); } Think about the possible benefits and applications of this. It can be used to store data returned by an API. In this way, the application would be more efficient and also can work offline without therefore having to use network data for recovering data from the server.\n","date":"15 May 2020","externalUrl":null,"permalink":"/coding/flutter_shared_preferences_in_depth/","section":"Coding","summary":"Master Flutter Shared Preferences: save strings, integers, booleans and JSON data locally. Learn object mapping for offline-capable apps.","title":"Flutter Shared Preferences in depth","type":"Coding"},{"content":"The name chosen by Google this time is very comprehensive and exhaustive. Firebase remote config is a remotely saved configuration, in this case on Google Cloud. This configuration is accessible to insert and update in the Firebase console, under the menu item Firebase remote config which is located at the very bottom, in the last section, in my opinion a little hidden.\nPrerequisites:\ncreate an account on Firebase using our google account\ncreate an app, I used flutter\nconnect our app to the source code using json key file\nBy doing this we could use all the Firebase services, there are many online tutorials and Firebase itself provides wizards with steps to guide you to the correct implementation of Firebase with your app. We can use Firebase Remote Config to store everything our app needs as configuration parameters. First of all, We must identify and configure what we think will change over time. In this way we will have configurations in the app that can be modified in real time remotely so as not to have to carry out a new app deployment. An example may be the case in which we are using an API to recover data, the base url may change over time. By doing this we could use all the Firebase services, there are many online tutorials and Firebase itself provides wizards with steps to guide you to the correct implementation of Firebase with your app. We can use Firebase Remote Config to store everything our app needs as configuration parameters. First of all, We must identify and configure what we think will change over time. In this way we will have configurations in the app that can be modified in real time remotely so as not to have to carry out a new app deployment. An example may be the case in which we are using an API to recover data, the base url may change over time.\nAnother more down to earth-example that I use in the send to kindle app is a parameter that contains the number of actions before showing an advertisement. In this way, if users complain about too many advertisements, I can change it in real time with just changing a parameter into the web interface at no cost.\nThe Firebase system works really well, there is a push-lazy system behind it that uses internet data to retrieve the configurations only if we have really changed something on the server side and therefore we have published a change to one or more parameters. The updating of the parameters takes place in real time so it changes immediately the behavior, state or data in app as real time.\nParameters can also be associated with conditions. For example, a parameter can only be used for users of a certain age in a certain country or language at a specific time. Cool! isn\u0026rsquo;t it?\nAdvantages # Instant and simple remote control.\nReal-time app customization.\nIt decreases the need for a new deployment.\nParameters can be combined with conditions.\nHow do I use it in my apps? # Below I want to show you an example of implementation. In this way I centralized the initialisation and parameter creation part so that they are more accessible. I decided to use a singleton so that I can use it in all the views and all the classes I need it, implemented in the following way:\nimport \u0026#39;package:firebase_remote_config/firebase_remote_config.dart\u0026#39;; class Configuration { int _link_sent_before_ads; int _max_send_limit_size = 24000000; int get linkSentBeforeAds =\u0026gt; _link_sent_before_ads; int get maxSendLimitSize =\u0026gt; _max_send_limit_size; int get maxSendLimitSizeMb =\u0026gt; (_max_send_limit_size/1000000).round(); static Configuration get instance =\u0026gt; _instance; static final Configuration _instance = Configuration._privateConstructor(); Configuration._privateConstructor() { //initializeRemoteConfig(); } loadConfig(RemoteConfig _remoteConfig) async { _link_sent_before_ads = _remoteConfig.getString(\u0026#39;link_sent_before_ads\u0026#39;).isEmpty ? _link_sent_before_ads : int.tryParse(_remoteConfig.getString(\u0026#39;link_sent_before_ads\u0026#39;)); _max_send_limit_size = _remoteConfig.getString(\u0026#39;max_send_limit_size\u0026#39;).isEmpty ? _max_send_limit_size : int.tryParse(_remoteConfig.getString(\u0026#39;max_send_limit_size\u0026#39;)); } initializeRemoteConfig() async{ RemoteConfig remoteConfig = await RemoteConfig.instance; try { //set some default params in case of crash await remoteConfig.setConfigSettings(RemoteConfigSettings(debugMode: false)); await remoteConfig.setDefaults(\u0026lt;String, dynamic\u0026gt;{ \u0026#39;service_api_conversion_1\u0026#39;: \u0026#39;https://ebook-converter.app/calibre/ebook-convert\u0026#39;, }); // Using default duration to force fetching from remote server. await remoteConfig.fetch(expiration: const Duration(seconds: 0)); await remoteConfig.activateFetched(); } on FetchThrottledException catch (exception) { // Fetch throttled. print(exception); } catch (exception) { print(\u0026#39;Unable to fetch remote config. Cached or default values will be used\u0026#39;); } await this.loadConfig(remoteConfig); } } It can finally be used very simply in the following way:\n//call this just first time in app initialization await Configuration.instance.initializeRemoteConfig(); Print(Configuration.instance.maxSendLimitSize); ","date":"15 May 2020","externalUrl":null,"permalink":"/coding/what_is_firebase_remote_config/","section":"Coding","summary":"Learn what Firebase Remote Config is and how to implement it in Flutter using a singleton pattern. Update app behavior in real time remotely.","title":"What is Firebase Remote Config","type":"Coding"},{"content":" Theory # Flutter is a new language that has recently come out from the beta, implemented by Google on the basis of Dart language less known today than FLutter. It is a modern language but based on Dart, the syntax is very similar to any other modern object language. The main concept on which it is based is Everything is a widget. But what does it really mean? All we are dealing with when developing in Flutter is a widget. A widget may or may not have a status, which can determine its content or form. It could be seen as an object as you imagine it with the difference that it can have a state to update the view and it can contain contents and shapes.\nYes, you have understood shapes correctly, since a widget, besides defining properties and methods, can define shapes. Finally, a widget can include or extend another widget. So an app in flutter is the composition of the widgets together. An example could be a form containing n input text widgets etc. and a button also widget.\nThe main widget that we can make are of two types, at least for now before google upsets everything, and are as follows:\nWidgets stateless (statelesswidget) are immutable, like a static class. A button that never changes color can be defined as a static widget. It can also be used in case we need to show only non-interactive descriptions.\nStateful widgets (statefulwidget): one (or more) property related to them, changing, can change the behavior, appearance or functionality of the widget. An app screen that changes based on content in an http response is a widget with status (just because the screen content varies based on the http response). Example: in case we need to request data from users and then update the same widget to validate or show an ok data entered correctly. To update the widget you need to use the setstate with the property updated so that the change is extended.\nStateful widgets (statefulwidget): one (or more) property related to them, changing, can change the behavior, appearance or functionality of the widget. An app screen that changes based on content in an http response is a widget with status (just because the screen content varies based on the http response). Example: in case we need to request data from users and then update the same widget to validate or show an ok data entered correctly. To update the widget you need to use the setstate with the property updated so that the change is extended.\nConsideration # The thing I liked most about Flutter:\nthat we can develop everything through a single language.\nthe livereload works really well and allows us to write the code faster.\nwith single environment and same code we have a build for Android and IOS as Native\nRecently flutter can also be used in web and desktop (Linux \u0026amp; Windows) :)\nAt the beginning I was a little skeptical about using widgets and it was a little complicated and dispersed to understand the advantages. After using them I must say that they are simpler than they seem to be implemented and thanks to this approach it will be easier to reason according to the best practice \u0026ldquo;DRY\u0026rdquo; (Don\u0026rsquo;t Repeat Yourself). On the one hand it adds an incredible nesting during the construction phase of the interface by boxing one widget into another and so on; however it has a logic that is modular in nature and this is excellent for decoupling small widgets that will consist of their properties and their tasks. By decoupling, we can test them and use them with different widgets to make more complex widgets. In this way the code will be more maintainable and functional.\n","date":"14 May 2020","externalUrl":null,"permalink":"/coding/flutter_everithings_is_a_widget_why_but_really_/","section":"Coding","summary":"Understand why everything in Flutter is a widget. Learn the difference between StatelessWidget and StatefulWidget with practical examples.","title":"Flutter everithings is a widget! Why? But Really! ","type":"Coding"},{"content":"","date":"14 May 2020","externalUrl":null,"permalink":"/tags/widjet/","section":"Tags","summary":"","title":"widjet","type":"tags"},{"content":"","date":"11 May 2020","externalUrl":null,"permalink":"/tags/google-app-script/","section":"Tags","summary":"","title":"google app script","type":"tags"},{"content":"","date":"11 May 2020","externalUrl":null,"permalink":"/tags/google-docs/","section":"Tags","summary":"","title":"google docs","type":"tags"},{"content":" Research # In these days I have felt the need to create the blog you are reading. While surfing the web, I became aware of the static site generators, I have always known what they are and that they have always existed but I had never given them much attention. Though, while surfing deeper, I was attracted by Hugo, one of the many new engines to generate static websites.\nNo WordPress # I needed to have something static for I don\u0026rsquo;t have a server where I can install Wordpress or other CMS and, for a small personal blog, I don\u0026rsquo;t think it\u0026rsquo;s necessary and it is also too expensive. Finally I wanted the blog to be efficient and scalable and cross platform.\nDRY # The first thing I thought about as a programmer was: how many operations do I need to do to deploy without a CMS? how will I bring my new content online? I am also a Google Docs lover and I like writing and having everything in one place. So I asked to myself: how do I combine Hugo and Google Docs without having to turn a thousand cranks?\nI studied the structure of MarkDown content and I started looking for something to convert Google Docs to MarkDown. The only useful thing I found on the web was this Googlescript mangini/ gdocs2md: Convert to Google Drive Document to the Markdown format, suitable for publishing. to whom I offer my heartfelt thanks.\nAlthough this script is very effective, I needed something more than receiving the conversion of an article by email. To have something more automated, I modified the script a bit and created the link script as follows:\nLink to my github repos\nThe script converts all the documents listed in a Google sheet, organizes into folders by categories, extracts images from articles, adds the MarkDown header, tags and finally creates a zip file containing all the contents. I decided to make the zip public and therefore downloadable, ready for deployment.\nI then created a sort of database using a Google sheet as a table with this struct:\nToDeploy Title Summary SummaryImage Category Date tag1 tag2 tag3 Tag4 Tag5 Language 1 Send As PDF files and web articles to the Kindle from Android 0 Kindle 09/05/2020 kindle pdf web article send to kindle android it In this way I have the possibility to deploy everything or to update only what I modified using the first field ToDeploy field.\nSubsequently, I created another google script that receives the id of the folder where there is the previously created zip. The script finally returns the public url from which it is possible to download the zip with the contents.\nfunction doGet (e) { params = JSON.parse (JSON.stringify (e)); var docid = params.parameters.docid; if (docid == null || docid == \u0026#34;\u0026#34;) return; var parentFolder = DriveApp.getFolderById (docid); if (parentFolder == null) return; var url = parentFolder.getFilesByName (\u0026#34;BlogProd.zip\u0026#34;). next (). getDownloadUrl (); return ContentService.createTextOutput (url); } Finally I put them all together in the following script linux sh.\nSo I can automate building and deployment:\n#!/bin/bash #ln -s /home/yourname/works/luciosoftsite/blog/ ~/luciosoftsite #ln -s /home/yourname/works/luciosoftsite/blog/content/ ~/luciosoftblogcontent #requirements wget|unzip|hugo folderid=”your google doc folder id” yourscriptid=”your google script id” cd ~/luciosoftblogcontent; retriveurl=\u0026#34;https://script.google.com/macros/s/$scriptid/exec?folderid=$folderid”; downlodUrl=$(wget $retriveurl -q -O -); fileName=\u0026#34;download.zip\u0026#34;; wget -c $downlodUrl -O $fileName; unzip -o $fileName; rm -f $fileName; cd ~/luciosoftblog; #hugo serve -D HUGO_ENV=\u0026#34;production\u0026#34; hugo --config config.yaml firebase deploy The script is very simple, it calls the google script to retrieve the download url.\nOnce the url is recovered, the script does the download of the zip, extracts the contents into the Hugo contents folder, executes the command to create Build, and finally calls firebase for deploy.\nAnd even today the magic has happened.\nYes, I could have followed a thousand other ways, even safer and more efficient. But this is a starting point, my goal is bigger. I would like to turn the linux script into a docker container and the google script into a dynamic application with google login. But this is another story that, maybe, you will be able to see in another link at my blog :)\nLink al progetto ghithub\n","date":"11 May 2020","externalUrl":null,"permalink":"/coding/how_to_create_a_blog_with_hugo_e_google_docs_as_backend/","section":"Coding","summary":"Build a static blog with Hugo using Google Docs as a backend CMS. Automate content conversion, deployment to Firebase with Google Apps Script.","title":"How to create a Blog with Hugo e Google Docs as BackEnd","type":"Coding"},{"content":"","date":"11 May 2020","externalUrl":null,"permalink":"/tags/hugo/","section":"Tags","summary":"","title":"Hugo","type":"tags"},{"content":"","date":"11 May 2020","externalUrl":null,"permalink":"/tags/static-blog/","section":"Tags","summary":"","title":"static blog","type":"tags"},{"content":"Are you ready to start a new better reading experience? You can finally say goodbye to the uncomfortable night readings from your smartphone.\nReading long articles on a mobile screen can be difficult, especially if the site has lots ads. Reading on a Kindle is much easier on the eyes, and you have more control over the size and the font you use.\nFind Your Kindle Address with 3 step configuration # 1. Recover the email of your kindle, you can find it by accessing to the following link:\nhttps://www.amazon.com/hz/mycd/myx#/home/settings/ (make sure that the .com is the Amazon used in your country, the one where you have associated your kindle)\n2. Scroll down to personal document settings and click on it. Edit the kindle address that you need in order to enter the Send to Kindle app.\n3. Scroll down, in the section approved mails, add the e-mail address you use every day or the one you want to send the documents from, please verify that archiving is enabled.\nNow, relax and enjoy sending documents from Send to Kindle.\nSend to Kindle # The best app for doing so is Send to Kindle app. This app is not the same as the Send to Kindle provided by Amazon.\n2026 Update — From Send to Kindle to Send to Reader: When I wrote this post back in 2020, Send to Kindle was just starting out. Over the years, many of you asked me for a way to send web articles, PDFs, and even 200 MB Manga without fighting Amazon\u0026rsquo;s approved email settings—and with support for Kobo, Onyx Boox, PocketBook, and iOS. That\u0026rsquo;s why I built Send to Reader! Check out my new articles \u0026amp; mini-guides on sharing clean web articles from Safari \u0026amp; Chrome, fixing unreadable PDFs \u0026amp; custom covers, and Kindle vs Kobo vs Boox in 2026.\nSend to Kindle allows you:\nsend web articles to your Kindle by Share feature on your mobile web browser.\nSend pdf/epub/azw document by converting it to mobi.\nSend to Kindle Web Article # Download Send to Kindle app from the Play Store Send to Kindle. Locate the article you want to send to your Kindle on any browser or news app.\nOpen the settings for your browser and look for three dots in the top-right corner.\nClick Share.\nChoose Send to Kindle as your sharing app.\nWait for the app to convert your article to the correct format.\nClick the yellow-arrow Send button.\nIf this is the first time you have used the app, you will need to set up your Kindle email address. Tap the message to do so.\nType in your Kindle email and press Save.\nChoose your email client.\nSend the email.\nCheck your Kindle for the article.\nSend to Kindle per PDF, EPUB o AZW # Click on plus icon in search bar Select your pdf file\nClick convert\nSend the mail\n","date":"9 May 2020","externalUrl":null,"permalink":"/kindle/how_to_send_pdf_file_and_article_to_kindle_from_android/","section":"Kindle","summary":"Send PDF files and web articles to your Kindle from Android. Step-by-step setup guide for Kindle email and the Send to Kindle app.","title":"How to send pdf file and article to kindle from Android","type":"Kindle"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"}]