{"id":448,"date":"2019-05-31T14:38:22","date_gmt":"2019-05-31T12:38:22","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=448"},"modified":"2021-03-17T12:38:11","modified_gmt":"2021-03-17T11:38:11","slug":"amazon-alexa-anatomia-di-una-skill","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/","title":{"rendered":"Amazon Alexa: anatomia di una skill"},"content":{"rendered":"

Quanti di voi possiedono un dispositivo Alexa enabled<\/strong> o comunque un assistente vocale?<\/span><\/p>\n

Questi dispositivi stanno creando un modo di interagire con servizi ed applicazioni del tutto diverso da quanto siamo abituati a conoscere.<\/span><\/p>\n

Amazon, con Alexa<\/strong>, \u00e8 uno dei principali attori di quella che sta diventando una rivoluzione dell\u2019esperienza utente.<\/span><\/p>\n

In questo articolo spiegheremo ad alto livello il funzionamento di una Alexa Skill<\/strong> e vi forniremo un modello di interazione<\/strong>, oltre allo snippet di codice<\/strong> necessario per creare un back-end minimale.<\/span><\/p>\n

Prima di entrare nei dettagli \u00e8 importante definire un vocabolario; nei paragrafi seguenti andremo ad introdurre i termini e i concetti che utilizzeremo in tutto il resto \u00a0dell\u2019articolo.<\/span><\/p>\n

Cos\u2019\u00e8 Alexa?<\/span><\/h2>\n

Alexa \u00e8 l\u2019assistente vocale di Amazon<\/strong> basato su cloud e che consente \u00a0il funzionamento di Amazon Echo.<\/strong> Oltre ad Amazon Echo \u00e8 possibile trovare una vasta gamma di dispositivi che supportano Alexa. Inoltre \u00e8 anche possibile costruirne di nuovi utilizzando <\/span>AVS<\/span><\/a> (Alexa voice service: il kit e le API messe a disposizione da Amazon).<\/span><\/p>\n

Alexa Skill<\/span><\/h2>\n

Le skill sono le \u201cabilit\u00e0\u201d, ovvero le applicazioni che aggiungono capacit\u00e0 ad Alexa.<\/strong><\/span>Ogni cosa che Alexa pu\u00f2 fare viene implementata in una Skill.<\/span>Alexa dispone di alcune skill predefinite e disponibili in tutte le lingue supportate, come ad esempio l\u2019orologio, le liste, i timer e i promemoria. Tutte le altre, invece, sono sviluppate da terze parti e raccolte in un catalogo del tutto simile ad un application store. Per attivare una skill di terze parti occorre cercarla sul catalogo dall\u2019app Alexa ed abilitarla per i propri dispositivi, in alternativa \u00e8 possibile attivare una skill usando solo la voce, ad esempio chiedendo esplicitamente ad un Amazon Echo di avviarla.<\/span><\/p>\n

L\u2019anatomia di una skill<\/span><\/h2>\n

Entrando nello specifico, una skill si compone essenzialmente di due parti:<\/span><\/p>\n

    \n
  1. Un modello di interazione<\/strong><\/li>\n
  2. Una API di back-end<\/strong><\/li>\n<\/ol>\n

    Il modello di interazione consiste in un file json che modellizza tutti gli intenti,<\/strong> cio\u00e8 il tipo di azioni rese possibili agli utenti e che la skill pu\u00f2 gestire. Per ogni intento \u00e8 necessario definire anche quali siano i parametri necessari, il loro tipo e le frasi che Alexa dovr\u00e0 utilizzare per richiederli. Il modello contiene anche molte frasi di esempio per ogni intento (utterances),<\/strong> frasi che verranno utilizzate dalla IA per riconoscere le richieste degli utenti verso la propria skill.<\/span><\/p>\n

    Il back-end della skill \u00e8 un servizio web. <\/strong><\/p>\n

    Pu\u00f2 essere ospitato su AWS Lambda<\/strong>\u00a0che permette una facile autenticazione di Alexa e ha un modello di pricing piuttosto allettante. <\/span><\/p>\n

    In alternativa pu\u00f2 essere ospitato su qualsiasi servizio permetta di esporre un endpoint pubblico accessibile attraverso https.<\/span><\/p>\n

    Indipendentemente dalla scelta dell\u2019hosting, il back-end dovr\u00e0 essere raggiungibile dalle chiamate di Alexa. Entro pochi secondi dovr\u00e0 rispondere con un messaggio contenente istruzioni per Alexa, ad esempio il testo che dovr\u00e0 essere sintetizzato all\u2019utente e\/o un altro tipo di istruzione (ad esempio comandi IoT, dati da mostrare su eventuali display, …).<\/span><\/p>\n

    Approfondiremo meglio il funzionamento del back-end tra qualche paragrafo.<\/span><\/p>\n

     <\/p>\n

    \"alexa_schema\"<\/p>\n

     <\/p>\n

    Ecco come funziona l\u2019interazione con una skill ad alto livello:<\/span><\/p>\n

    Quando l\u2019utente parla ad un dispositivo Echo, questo registra l\u2019audio e lo invia ad Alexa usando AVS.<\/strong> A questo punto Alexa sar\u00e0 in grado di individuare la skill da interpellare in uno dei seguenti modi:<\/span><\/p>\n

      \n
    1. La richiesta contiene esplicitamente il nome della skill desiderata, ad esempio \u201cAlexa chiedi a [nome skill] di \u2026 \u201c o forme simili.<\/span><\/li>\n
    2. L\u2019utente ha gi\u00e0 abilitato una skill in grado di soddisfare l\u2019intento espresso; in questo caso Alexa selezioner\u00e0 tale skill.<\/span><\/li>\n
    3. Se l\u2019utente non ha abilitato nessuna skill in grado di soddisfare la richiesta, verr\u00e0 scelta la skill di default per l\u2019intento (selezionata da Amazon).<\/span><\/li>\n<\/ol>\n

      Una volta identificata la skill che l\u2019utente intende utilizzare, entra in gioco il modello di interazione sviluppato dal programmatore.<\/span><\/p>\n

      Alexa utilizza le frasi di esempio e la definizione degli intenti e dei parametri per capire cosa l\u2019utente desidera. In caso la richiesta non contenga tutti i parametri necessari, l\u2019utente sar\u00e0 interrogato fino a quando non avr\u00e0 fornito tutte le informazioni.<\/span><\/p>\n

      Una volta completata la prima fase dell\u2019interazione, Alexa contatta il back-end dell\u2019applicazione tramite una chiamata POST, fornendogli tutti i dettagli ed attendendo l\u2019output da comunicare all\u2019utente.<\/span><\/p>\n

      Per skill complicate, \u00e8 possibile conservare nel back-end le regole e la logica di reperimento dei parametri, permettendo di modificarli in funzione di quanto acquisito fino a quel momento.<\/span><\/p>\n

      Tra le funzioni di Alexa vi \u00e8 anche quella di mantenere i dati di sessione:<\/strong> sar\u00e0 quindi possibile mantenere lo stato di una conversazione inserendo e modificando variabili in un\u2019apposita sezione del messaggio restituito dal back-end. Queste informazioni saranno inviate da Alexa alle successive chiamate al back-end fino a quando l\u2019utente non concluder\u00e0 l\u2019interazione con la skill.<\/span><\/p>\n

      Sfruttando la sessione \u00e8 pertanto possibile realizzare skill complesse che \u201cricordano\u201d le risposte o le richieste precedenti dell\u2019utente, realizzando di fatto una conversazione \u00a0realistica.<\/strong><\/span><\/p>\n

      Una skill triviale<\/span><\/h2>\n

      Finora abbiamo parlato del modello di interazione e del back-end senza entrare troppo nel dettaglio.<\/span><\/p>\n

      Ecco pertanto un modello di esempio<\/span><\/p>\n

      {\r\n    \"interactionModel\": {\r\n        \"languageModel\": {\r\n            \"invocationName\": \"saluti\",\r\n            \"intents\": [\r\n                {\r\n                    \"name\": \"AMAZON.CancelIntent\",\r\n                    \"samples\": [\r\n                        \"no\",\r\n                        \"niente\",\r\n                        \"non fa niente\",\r\n                        \"lascia perdere\",\r\n                        \"annulla\"\r\n                    ]\r\n                },\r\n                {\r\n                    \"name\": \"AMAZON.HelpIntent\",\r\n                    \"samples\": []\r\n                },\r\n                {\r\n                    \"name\": \"AMAZON.StopIntent\",\r\n                    \"samples\": [\r\n                        \"abbandona\",\r\n                        \"esci\",\r\n                        \"fine\",\r\n                        \"stop\"\r\n                    ]\r\n                },\r\n                {\r\n                    \"name\": \"Salutare\",\r\n                    \"slots\": [],\r\n                    \"samples\": [\r\n                        \"salutarmi\",\r\n                        \"salutami\",\r\n                        \"saluti\",\r\n                        \"ciao\"\r\n                    ]\r\n                }\r\n            ],\r\n            \"types\": []\r\n        }\r\n    }\r\n}\r\n\r\n<\/pre>\n

      Questo modello definisce un solo intento con identificativo \u201cSalutare\u201d, oltre agli intenti standard di Amazon \u201ccancel\u201d, \u201cstop\u201d ed \u201chelp\u201d. Non sono necessari parametri, e sono fornite poche frasi di esempio.<\/span><\/p>\n

      Nella sua semplicit\u00e0, si tratta di un modello funzionante<\/strong> ed in grado di assolvere allo scopo di farsi salutare da Alexa.<\/span><\/p>\n

      Manca tuttavia il back-end, ovvero il servizio che \u00e8 in grado di rispondere alle richieste che Alexa esegue una volta individuato l\u2019intento.<\/span><\/p>\n

      Supponendo di utilizzare AWS Lambda, ecco uno snippet per rispondere correttamente alle chiamate relative all\u2019intento definito sopra. <\/span><\/p>\n

      Si tratta di una funzione Nodejs,<\/strong> il cui codice utilizza l\u2019sdk di Alexa per node. Abbiamo evidenziato la funzione che viene invocata per l\u2019intento \u201cSalutare\u201d in rosso.<\/span><\/p>\n

      Il resto del codice \u00e8 sostanzialmente solo boilerplate e rimane quasi completamente invariato anche in caso di skill pi\u00f9 complesse.<\/span><\/p>\n

      let speechOutput;\r\nlet reprompt;\r\nlet welcomeOutput = \"Benvenuto in 'Ciao' in italiano. Puoi salutarmi per essere salutato a tua volta\";\r\nlet welcomeReprompt = \"puoi solo dire 'ciao' per essere salutato\";\r\n\r\n\"use strict\";\r\nconst Alexa = require('alexa-sdk');\r\nconst APP_ID = undefined;\r\nspeechOutput = '';\r\nconst handlers = {\r\n'LaunchRequest': function() {\r\nthis.emit(':ask', welcomeOutput, welcomeReprompt);\r\n},\r\n'AMAZON.HelpIntent': function() {\r\nspeechOutput = 'Placeholder response for AMAZON.HelpIntent.';\r\nreprompt = '';\r\nthis.emit(':ask', speechOutput, reprompt);\r\n},\r\n'AMAZON.CancelIntent': function() {\r\nspeechOutput = 'Ok, annullato\u2019;\r\nthis.emit(':tell', speechOutput);\r\n},\r\n'AMAZON.StopIntent': function() {\r\nspeechOutput = 'Arrivederci';\r\nthis.emit(':tell', speechOutput);\r\n},\r\n'SessionEndedRequest': function() {\r\nspeechOutput = '';\r\nthis.emit(':tell', speechOutput);\r\n},\r\n'Salutare': function() {<\/span>\r\nspeechOutput = '';<\/span>\r\nspeechOutput = \"Ciao! Questo \u00e8 tutto quello che puoi fare per ora\u201d;<\/span>\r\nthis.emit(\":tell\", speechOutput, speechOutput);<\/span>\r\n},<\/span>\r\n'Unhandled': function() {\r\nspeechOutput = \"Non ho capito. Riprova\";\r\nthis.emit(':ask', speechOutput, speechOutput);\r\n}\r\n};\r\n\r\nexports.handler = (event, context) => {\r\nconst alexa = Alexa.handler(event, context);\r\nalexa.appId = APP_ID;\r\n\/\/ To enable string internationalization (i18n) features, set a resources object.\r\n\/\/alexa.resources = languageStrings;\r\nalexa.registerHandlers(handlers);\r\n\/\/alexa.dynamoDBTableName = 'DYNAMODB_TABLE_NAME'; \/\/uncomment this line to save attributes to DB\r\nalexa.execute();\r\n};\r\n\r\n\/\/ END of Intent Handlers {} ========================================================================================\r\n\/\/ 3. Helper Function =================================================================================================\r\n\r\nfunction resolveCanonical(slot) {\r\n\/\/this function looks at the entity resolution part of request and returns the slot value if a synonyms is provided\r\nlet canonical;\r\ntry {\r\ncanonical = slot.resolutions.resolutionsPerAuthority[0].values[0].value.name;\r\n}\r\ncatch (err) {\r\nconsole.log(err.message);\r\ncanonical = slot.value;\r\n};\r\nreturn canonical;\r\n};\r\n\r\nfunction delegateSlotCollection() {\r\nconsole.log(\"in delegateSlotCollection\");\r\nconsole.log(\"current dialogState: \" + this.event.request.dialogState);\r\nif (this.event.request.dialogState === \"STARTED\") {\r\nconsole.log(\"in Beginning\");\r\nlet updatedIntent = null;\r\n\/\/ updatedIntent=this.event.request.intent;\r\n\/\/optionally pre-fill slots: update the intent object with slot values for which\r\n\/\/you have defaults, then return Dialog.Delegate with this updated intent\r\n\/\/ in the updatedIntent property\r\n\/\/this.emit(\":delegate\", updatedIntent); \/\/uncomment this is using ASK SDK 1.0.9 or newer\r\n\r\n\/\/this code is necessary if using ASK SDK versions prior to 1.0.9 \r\nif (this.isOverridden()) {\r\nreturn;\r\n}\r\nthis.handler.response = buildSpeechletResponse({\r\nsessionAttributes: this.attributes,\r\ndirectives: getDialogDirectives('Dialog.Delegate', updatedIntent, null),\r\nshouldEndSession: false\r\n});\r\nthis.emit(':responseReady', updatedIntent);\r\n\r\n}\r\nelse if (this.event.request.dialogState !== \"COMPLETED\") {\r\nconsole.log(\"in not completed\");\r\n\/\/ return a Dialog.Delegate directive with no updatedIntent property.\r\n\/\/this.emit(\":delegate\"); \/\/uncomment this is using ASK SDK 1.0.9 or newer\r\n\r\n\/\/this code necessary is using ASK SDK versions prior to 1.0.9\r\nif (this.isOverridden()) {\r\nreturn;\r\n}\r\nthis.handler.response = buildSpeechletResponse({\r\nsessionAttributes: this.attributes,\r\ndirectives: getDialogDirectives('Dialog.Delegate', null, null),\r\nshouldEndSession: false\r\n});\r\nthis.emit(':responseReady');\r\n\r\n}\r\nelse {\r\nconsole.log(\"in completed\");\r\nconsole.log(\"returning: \" + JSON.stringify(this.event.request.intent));\r\n\/\/ Dialog is now complete and all required slots should be filled,\r\n\/\/ so call your normal intent handler.\r\nreturn this.event.request.intent;\r\n}\r\n}\r\n\r\n\r\nfunction randomPhrase(array) {\r\n\/\/ the argument is an array [] of words or phrases\r\nlet i = 0;\r\ni = Math.floor(Math.random() * array.length);\r\nreturn (array[i]);\r\n}\r\n\r\nfunction isSlotValid(request, slotName) {\r\nlet slot = request.intent.slots[slotName];\r\n\/\/console.log(\"request = \"+JSON.stringify(request)); \/\/uncomment if you want to see the request\r\nlet slotValue;\r\n\r\n\/\/if we have a slot, get the text and store it into speechOutput\r\nif (slot && slot.value) {\r\n\/\/we have a value in the slot\r\nslotValue = slot.value.toLowerCase();\r\nreturn slotValue;\r\n}\r\nelse {\r\n\/\/we didn't get a value in the slot.\r\nreturn false;\r\n}\r\n}\r\n\r\n\/\/These functions are here to allow dialog directives to work with SDK versions prior to 1.0.9\r\n\/\/will be removed once Lambda templates are updated with the latest SDK\r\n\r\nfunction createSpeechObject(optionsParam) {\r\nif (optionsParam && optionsParam.type === 'SSML') {\r\nreturn {\r\ntype: optionsParam.type,\r\nssml: optionsParam['speech']\r\n};\r\n}\r\nelse {\r\nreturn {\r\ntype: optionsParam.type || 'PlainText',\r\ntext: optionsParam['speech'] || optionsParam\r\n};\r\n}\r\n}\r\n\r\nfunction buildSpeechletResponse(options) {\r\nlet alexaResponse = {\r\nshouldEndSession: options.shouldEndSession\r\n};\r\n\r\nif (options.output) {\r\nalexaResponse.outputSpeech = createSpeechObject(options.output);\r\n}\r\n\r\nif (options.reprompt) {\r\nalexaResponse.reprompt = {\r\noutputSpeech: createSpeechObject(options.reprompt)\r\n};\r\n}\r\n\r\nif (options.directives) {\r\nalexaResponse.directives = options.directives;\r\n}\r\n\r\nif (options.cardTitle && options.cardContent) {\r\nalexaResponse.card = {\r\ntype: 'Simple',\r\ntitle: options.cardTitle,\r\ncontent: options.cardContent\r\n};\r\n\r\nif (options.cardImage && (options.cardImage.smallImageUrl || options.cardImage.largeImageUrl)) {\r\nalexaResponse.card.type = 'Standard';\r\nalexaResponse.card['image'] = {};\r\n\r\ndelete alexaResponse.card.content;\r\nalexaResponse.card.text = options.cardContent;\r\n\r\nif (options.cardImage.smallImageUrl) {\r\nalexaResponse.card.image['smallImageUrl'] = options.cardImage.smallImageUrl;\r\n}\r\n\r\nif (options.cardImage.largeImageUrl) {\r\nalexaResponse.card.image['largeImageUrl'] = options.cardImage.largeImageUrl;\r\n}\r\n}\r\n}\r\nelse if (options.cardType === 'LinkAccount') {\r\nalexaResponse.card = {\r\ntype: 'LinkAccount'\r\n};\r\n}\r\nelse if (options.cardType === 'AskForPermissionsConsent') {\r\nalexaResponse.card = {\r\ntype: 'AskForPermissionsConsent',\r\npermissions: options.permissions\r\n};\r\n}\r\n\r\nlet returnResult = {\r\nversion: '1.0',\r\nresponse: alexaResponse\r\n};\r\n\r\nif (options.sessionAttributes) {\r\nreturnResult.sessionAttributes = options.sessionAttributes;\r\n}\r\nreturn returnResult;\r\n}\r\n\r\nfunction getDialogDirectives(dialogType, updatedIntent, slotName) {\r\nlet directive = {\r\ntype: dialogType\r\n};\r\n\r\nif (dialogType === 'Dialog.ElicitSlot') {\r\ndirective.slotToElicit = slotName;\r\n}\r\nelse if (dialogType === 'Dialog.ConfirmSlot') {\r\ndirective.slotToConfirm = slotName;\r\n}\r\n\r\nif (updatedIntent) {\r\ndirective.updatedIntent = updatedIntent;\r\n}\r\nreturn [directive];\r\n}<\/pre>\n

      In questo articolo abbiamo trattato i concetti fondamentali che stanno alla base del funzionamento di Alexa. Abbiamo poi analizzato l\u2019anatomia di una skill semplice e funzionante,<\/strong> il primo passo per la realizzazione di skill pi\u00f9 complesse e potenzialmente pubblicabili. <\/span><\/p>\n

      Per la pubblicazione vi sono per\u00f2 vincoli di compliance e regole di cui tenere conto durante la progettazione di un\u2019interfaccia vocale.<\/span><\/p>\n

      Di questo e di molti altri aspetti importanti sulla fase di pubblicazione e realizzazione ci occuperemo nei prossimi articoli. Ma prima pubblicheremo un tutorial dettagliato per la realizzazione di una skill… non \u201cbanale\u201d. <\/span><\/p>\n

      Non vi anticipiamo nulla \ud83d\ude42 <\/span><\/p>\n

      Stay tuned!<\/span><\/p>\n

      Vuoi approfondire l\u2019uso di AWS Lambda o saperne di pi\u00f9 sullo sviluppo Serverless? Leggi la nostra serie di articoli dedicati!<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"

      Quanti di voi possiedono un dispositivo Alexa enabled o comunque un assistente vocale? Questi dispositivi stanno creando un modo di […]<\/p>\n","protected":false},"author":8,"featured_media":468,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[247],"tags":[339,341,263],"yoast_head":"\nAmazon Alexa: creiamo una skill - Proud2beCloud Blog<\/title>\n<meta name=\"description\" content=\"In questo articolo spiegheremo il funzionamento di una Alexa Skill e vi forniremo tutto il necessario per costruirne una in pochi minuti.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Amazon Alexa: creiamo una skill\" \/>\n<meta property=\"og:description\" content=\"In questo articolo spiegheremo il funzionamento di una Alexa Skill e vi forniremo tutto il necessario per costruirne una in pochi minuti.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/\" \/>\n<meta property=\"og:site_name\" content=\"Proud2beCloud Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-05-31T12:38:22+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-03-17T11:38:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.besharp.it\/wp-content\/uploads\/2019\/05\/copertine-blog_Tavola-disegno-1-copia-2.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1668\" \/>\n\t<meta property=\"og:image:height\" content=\"1250\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Alessio Gandini\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Amazon Alexa: creiamo una skill\" \/>\n<meta name=\"twitter:description\" content=\"In questo articolo spiegheremo il funzionamento di una Alexa Skill e vi forniremo tutto il necessario per costruirne una in pochi minuti.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/blog.besharp.it\/wp-content\/uploads\/2019\/05\/copertine-blog_Tavola-disegno-1-copia-2.png\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alessio Gandini\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/\",\"url\":\"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/\",\"name\":\"Amazon Alexa: creiamo una skill - Proud2beCloud Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/#website\"},\"datePublished\":\"2019-05-31T12:38:22+00:00\",\"dateModified\":\"2021-03-17T11:38:11+00:00\",\"author\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/e7262d28e51528c2e420327f9b18cd43\"},\"description\":\"In questo articolo spiegheremo il funzionamento di una Alexa Skill e vi forniremo tutto il necessario per costruirne una in pochi minuti.\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.besharp.it\/it\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Amazon Alexa: anatomia di una skill\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.besharp.it\/it\/#website\",\"url\":\"https:\/\/blog.besharp.it\/it\/\",\"name\":\"Proud2beCloud Blog\",\"description\":\"il blog di beSharp\",\"alternateName\":\"Proud2beCloud Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.besharp.it\/it\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/e7262d28e51528c2e420327f9b18cd43\",\"name\":\"Alessio Gandini\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/eeb98518768d999bff24f8358b464fe2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/eeb98518768d999bff24f8358b464fe2?s=96&d=mm&r=g\",\"caption\":\"Alessio Gandini\"},\"description\":\"Cloud-native Development Line Manager @ beSharp, DevOps Engineer e AWS expert. Computer geek da quando avevo 6 anni, appassionato di informatica ed elettronica a tutto tondo. Ultimamente sto esplorando l'esperienza utente vocale e il mondo dell'IoT. Appassionato di cinema e grande consumatore di serie TV, videogiocatore della domenica.\",\"url\":\"https:\/\/blog.besharp.it\/it\/author\/alessio-gandini\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Amazon Alexa: creiamo una skill - Proud2beCloud Blog","description":"In questo articolo spiegheremo il funzionamento di una Alexa Skill e vi forniremo tutto il necessario per costruirne una in pochi minuti.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/","og_locale":"it_IT","og_type":"article","og_title":"Amazon Alexa: creiamo una skill","og_description":"In questo articolo spiegheremo il funzionamento di una Alexa Skill e vi forniremo tutto il necessario per costruirne una in pochi minuti.","og_url":"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/","og_site_name":"Proud2beCloud Blog","article_published_time":"2019-05-31T12:38:22+00:00","article_modified_time":"2021-03-17T11:38:11+00:00","og_image":[{"width":1668,"height":1250,"url":"https:\/\/blog.besharp.it\/wp-content\/uploads\/2019\/05\/copertine-blog_Tavola-disegno-1-copia-2.png","type":"image\/png"}],"author":"Alessio Gandini","twitter_card":"summary_large_image","twitter_title":"Amazon Alexa: creiamo una skill","twitter_description":"In questo articolo spiegheremo il funzionamento di una Alexa Skill e vi forniremo tutto il necessario per costruirne una in pochi minuti.","twitter_image":"https:\/\/blog.besharp.it\/wp-content\/uploads\/2019\/05\/copertine-blog_Tavola-disegno-1-copia-2.png","twitter_misc":{"Scritto da":"Alessio Gandini","Tempo di lettura stimato":"9 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/","url":"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/","name":"Amazon Alexa: creiamo una skill - Proud2beCloud Blog","isPartOf":{"@id":"https:\/\/blog.besharp.it\/it\/#website"},"datePublished":"2019-05-31T12:38:22+00:00","dateModified":"2021-03-17T11:38:11+00:00","author":{"@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/e7262d28e51528c2e420327f9b18cd43"},"description":"In questo articolo spiegheremo il funzionamento di una Alexa Skill e vi forniremo tutto il necessario per costruirne una in pochi minuti.","breadcrumb":{"@id":"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.besharp.it\/it\/amazon-alexa-anatomia-di-una-skill\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.besharp.it\/it\/"},{"@type":"ListItem","position":2,"name":"Amazon Alexa: anatomia di una skill"}]},{"@type":"WebSite","@id":"https:\/\/blog.besharp.it\/it\/#website","url":"https:\/\/blog.besharp.it\/it\/","name":"Proud2beCloud Blog","description":"il blog di beSharp","alternateName":"Proud2beCloud Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.besharp.it\/it\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"it-IT"},{"@type":"Person","@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/e7262d28e51528c2e420327f9b18cd43","name":"Alessio Gandini","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/eeb98518768d999bff24f8358b464fe2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/eeb98518768d999bff24f8358b464fe2?s=96&d=mm&r=g","caption":"Alessio Gandini"},"description":"Cloud-native Development Line Manager @ beSharp, DevOps Engineer e AWS expert. Computer geek da quando avevo 6 anni, appassionato di informatica ed elettronica a tutto tondo. Ultimamente sto esplorando l'esperienza utente vocale e il mondo dell'IoT. Appassionato di cinema e grande consumatore di serie TV, videogiocatore della domenica.","url":"https:\/\/blog.besharp.it\/it\/author\/alessio-gandini\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts\/448"}],"collection":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/comments?post=448"}],"version-history":[{"count":0,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts\/448\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/media\/468"}],"wp:attachment":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/media?parent=448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/categories?post=448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/tags?post=448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}