de Garrett Vargas

Cum să utilizați limba de prezentare Alexa în abilitățile dvs.

Amazon a lansat recent Alexa Presentation Language (APL). APL oferă un afișaj mai bogat pentru abilități multimodale. Se bazează pe cadre moderne care separă elementele de afișare de sursele de date. Vă oferă flexibilitatea de a include multe elemente vizuale, cum ar fi grafica, imagini și prezentări de diapozitive și vă permite să adaptați afișajul pentru diferite dispozitive.

În acest articol, voi parcurge modul în care mi-am actualizat una dintre abilitățile de a folosi APL. Puteți utiliza și aceste sfaturi și tehnici dacă creați o nouă abilitate.

Majoritatea abilităților mele oferă suport multimodal folosind Interfață de afișare. Am decis să învăț APL prin actualizarea uneia dintre abilitățile mele existente. M-am concentrat asupra mea Video Poker abilitate pentru că nu am fost mulțumit de experiența existentă a clienților.

Video Poker oferă utilizatorilor o mână de poker cu 5 cărți, cu posibilitatea de a ține și arunca cărți înainte de a extrage pentru a finaliza o mână. Utilizatorii pot face acest lucru prin comanda vocală („păstrați prima carte” sau „păstrați perechea de mufe”) sau atingând cărțile pe un afișaj vizual. ListTemplate2 a fost cel mai bun mod de a face acest lucru cu interfața de afișare. Cu toate acestea, acest lucru a venit cu limitarea de a permite doar trei cărți pe ecran la un moment dat și de a pune numere sub fiecare carte în listă.

Cum sa utilizati limba de prezentare Alexa in abilitatile dvs
Video Poker folosind Directiva Display Display ListTemplate2

Folosind APL, am modificat un aspect ListTemplate2 pentru a micșora dimensiunea articolelor din listă, pentru a reduce spațiul dintre ele și pentru a potrivi o mână completă de cinci cărți pe ecran. Am reușit să scot numerele din articolele din listă și să pun textul care indică cărțile deținute într-un font roșu și aldin. Am reușit să optimizez aspectul pentru diferite dimensiuni ale ecranului, cum ar fi afișaje mai mici, cum ar fi Echo Spot.

1611493570 781 Cum sa utilizati limba de prezentare Alexa in abilitatile dvs
Video Poker folosind șablonul APL modificat din ListTemplate2

Instrumentul de creație APL

Modul în care am făcut acest lucru a fost prin Instrumentul de creație APL. Acest instrument la îndemână oferă o listă cu diferite modele vizuale pe care le puteți utiliza ca bază pentru a crea imagini convingătoare pentru abilitățile dvs. De asemenea, vă permite să salvați și să încărcați machete, astfel încât să le puteți extrage în codul dvs. de calificare sau să le încărcați dacă faceți actualizări offline. Pentru acest caz de utilizare, am început cu Exemplu de listă de transmitere a imaginii, care se bazează pe ListTemplate2.

1611493570 641 Cum sa utilizati limba de prezentare Alexa in abilitatile dvs
Selectarea unui design vizual din Instrumentul de creație APL

După ce selectați acest design vizual în instrument, veți vedea un exemplu generic de listă cu probe de brânză. Veți vedea documentul APL în partea de jos a ecranului separat în două file:

  • „Exemplu de listă de transmitere a imaginii” care oferă aspectul
  • Fila „Date JSON” care oferă o vizualizare a datelor documentului.
1611493571 752 Cum sa utilizati limba de prezentare Alexa in abilitatile dvs
Editarea documentului dvs. APL în Instrumentul de creație

Faceți un moment pentru a privi JSON atât în ​​fila Image Forward List Sample (codul de aspect), cât și în fila JSON Data (codul de conținut). Veți observa în aspect că există mai multe referințe la valori cuprinse în ${} precum ${payload.listTemplate2ListData.listPage.listItems.length}. Dacă vă uitați în fișierul de conținut, veți vedea că aceasta este o cale către o valoare din conținut. Acesta este modul în care APL leagă datele de stratul de prezentare și vă permite să faceți modificări.

Actualizarea surselor de date

Ca prim pas, am vrut să actualizez datele, astfel încât să arate imagini de pe card și text relevante pentru abilitățile mele. În acest fel, pe măsură ce am început să actualizez aspectul în sine, aș putea vedea cum va arăta cu imaginile mele reale. Instrumentul de creare vă arată imaginile de pe ecran redate în timp real, făcându-l convenabil de utilizat în timp ce încercați să vă perfecționați aspectul. Pentru a actualiza datele, am făcut următorii pași:

  • Faceți clic pe fila Data JSON
  • În listTemplate2Metadata, schimba title și logo elemente pentru ceva relevant pentru Video Poker
  • În același element, schimbați fișierul url în backgroundImages.sources câmpuri pentru a indica imaginea de fundal pe care am vrut să o folosesc
  • În listTemplate2ListData.listPage, Am actualizat fiecare dintre articolele din listItems matrice. Mai exact, am actualizat această matrice pentru a avea 5 articole (cărțile mele), cu listItemIdentifier și token setat la „card.x” (unde x a variat de la 0 la 4). Am eliminat secondaryText întrucât am vrut doar un rând de text (care fie ar fi gol, fie ar spune „HOLD”). Am actualizat image.sources pentru a indica adresele URL care conțin imaginile cardului meu. Deocamdată, tocmai am selectat câteva imagini de cărți la întâmplare – codul abilității mele va actualiza datele în timpul jocului cu mâna utilizatorului real.
  • Actualizați textul indiciu pentru a utiliza o transformare. Mai degrabă decât codarea dură a șirului de sugestii cu cuvântul cheie Alexa, puteți utiliza o transformare pentru a schimba un indiciu într-unul care utilizează cuvântul de veghe asociat dispozitivului, în cazul în care utilizatorul l-a schimbat. Faceți acest lucru eliminând fișierul hintText din listTemplate2ListData și adăugând următoarele în ultimul tău Model2Metadata:
"properties": {    "hintText": "select number 1"},"transformers": [    {        "inputPath": "hintText",        "transformer": "textToHint"    }],

Odată ce le-am făcut la sursele de date, imaginea mea arăta așa – destul de asemănătoare cu abilitatea, deoarece există cu afișajul ListTemplate2, ceea ce are sens, deoarece în acest moment încă folosesc aspectul bazat pe ListTemplate2 și am creat doar conținut schimbări.

1611493571 904 Cum sa utilizati limba de prezentare Alexa in abilitatile dvs
Vizualizare actualizată cu conținut relevant de Video Poker

Actualizarea aspectului

Acum, pentru partea distractivă – actualizarea aspectului pentru a obține cinci imagini pe ecran simultan. Pentru această parte, am făcut actualizări ale aspectului de pe fila „Exemplu de listă pentru imagini înainte”. Pentru a face aceste modificări, am făcut clic pe glisorul care vă permite să comutați între o vizualizare vizuală a componentelor APL imbricate la o vizualizare JSON brută. Mi se pare mai ușor de vizualizat documentul complet JSON decât de a face clic pe fiecare componentă și de a edita JSON în cadrul componentei. Dar poți să te joci cu el și să urmărești orice abordare ți se pare cea mai naturală.

Înainte de a vorbi despre modificările pe care le-am făcut, am vrut să subliniez câteva dintre elementele acestui șablon de aspect:

  • Este un ListTemplate2 nod în JSON care oferă două containere într-un items nod – unul care se aplică ecranelor circulare (cum ar fi Echo Spot) și celălalt pentru alte tipuri de ecran. În acest blog, mă voi concentra pe afișajele non-Spot, dar ar trebui să apreciați că puteți face modificări specifice diferitelor aspecte ale ecranului.
  • Privind la al doilea container pe care îl vom schimba, veți vedea un set de items inclusiv o imagine (imaginea de fundal), un AlexaHeader (titlul de pe ecran), a Secvenţă (care este lista de cărți) și un AlexaFooter (indiciu din partea de jos a ecranului)
  • Veți vedea că secvența indică HorizontalListItem, care este un alt container din acest document JSON. Conține elemente constând dintr-o imagine și două elemente de text (textul principal și textul secundar)

Având în vedere acest context, am făcut următoarele modificări la acest document:

  • În cadrul HorizontalListItem, Am schimbat dimensiunile articolului Imagine – în mod specific am setat height la 40vh și width la 17vw. Aceasta setează înălțimea fiecărui card la 40% din înălțimea ferestrei, iar lățimea la 17% din lățimea ferestrei.
  • Am actualizat apoi midWidth până la 100. Acest lucru face ca lățimea fiecărui element de listă să fie mai mică și permite ca cele cinci imagini ale cardului să apară pe ecran
  • eu am schimbat paddingLeft și paddingRight la 6 pentru a reduce spațiul dintre elemente
  • Am adăugat paddingTop și setați-l la 100 pentru a adăuga o anumită separare între antet și imaginile cardului
  • Am scăpat de elementul secundar Text, deoarece nu am două linii de text pe afișaj
  • Am schimbat elementul Text primar, astfel încât să nu deseneze ordinalul. Asa de text în acest element schimbat din <b>${ordinal}.</b>${data.textContent.priamryText.text} to <b>${data.textContent.primaryText.text} .
  • În cadrul aceluiași element, am vrut ca textul să fie roșu și centrat. Am realizat acest lucru adăugând un textAlign câmp cu valoarea „centru” și a color câmp cu valoarea „roșu”.
  • Pentru a obține textul de sugestie din locația corespunzătoare (acum o parte a metadatelor, mai degrabă decât datele din listă), a trebuit să actualizez elementul AlexaFooter pentru a obține sugestia de la ${payload.listTemplate2Metadata.properties.hintText}

În cele din urmă, trebuia să fac cărțile din lista mea selectabile, astfel încât să pot răspunde când utilizatorul atinge una dintre ele pe ecran. Pentru a face acest lucru, a trebuit să schimb elementele asociate cu Sequence element dintr-un FullHorizontalListItem la o TouchWrapper care la rândul său conținea o FullHorizontalListItem. În cod, asta înseamnă că am schimbat acest lucru:

"item": [  {    "type": "FullHorizontalListItem",    "listLength": "${payload.listTemplate2ListData.listPage.listItems.length}"  }]

la acest:

"item": [  {    "type": "TouchWrapper",    "onPress": {      "type": "SendEvent",      "arguments": [        "${data.token}"      ]    },    "item": {      "type": "FullHorizontalListItem",      "listLength": "${payload.listTemplate2ListData.listPage.listItems.length}"    }  }]

Rețineți onPress element din acest articol. Mai exact, lista argumentelor. Puteți specifica o serie de argumente diferite pe care să le trimiteți abilităților dvs. atunci când este selectat un element. Deoarece codul meu existent prelucra simbolul cardului selectat, am decis să fac același lucru pentru a minimiza cantitatea de cod pe care trebuia să o schimb. Dar ai putea să treci și tu ${ordinal} care vă va indica indexul elementului selectat fără a fi nevoie să procesați jetonul.

Actualizări la Codul de competențe

După ce ați făcut modificări în Instrumentul de creație, puteți selecta butonul Exportă codul care vă va împacheta aspectul și fișierele de date într-un singur fișier JSON pentru dvs. Am ales să folosesc două fișiere JSON diferite în codul meu, unul numit main pe care l-am folosit pentru aspect și altul numit surse de date pe care le-am folosit pentru date. Îmi place să păstrez separarea aspectului și a conținutului în codul meu sursă ca o bună practică generală. A fost surprinzător faptul că Instrumentul de creație Amazon nu a încurajat și acest lucru.

Acum că am descărcat documentul și conținutul, trebuie să facem modificări de cod pentru a-l încorpora și a actualiza datele pe măsură ce utilizatorul se joacă cu abilitățile noastre. Putem face acest lucru manipulând elementele de date și apoi trecându-le înapoi la abilitate. Am folosit funcționalitatea interceptorului de răspuns Alexa (despre care vorbesc într-un postare de blog separată). Încărc sursa de date dintr-un fișier JSON, apoi actualizez cardurile și textul din structură înainte de ao trimite la Alexa. Fac asta cu următorul cod:

const main = require('./main.json');const datasource = require('./datasource.json');
function drawTable(handlerInput) {  const event = handlerInput.requestEnvelope;  const attributes = handlerInput.attributesManager.getSessionAttributes();  const game = attributes[attributes.currentGame];  let i;  let cardText;  let url;
  // Update the images  for (i = 0; i < game.cards.length; i++) {    const card = game.cards[i];    url = GetCardURL(card);    cardText = (card.hold) ? 'HELD' : '';    datasource.listTemplate2ListData.listPage.listItems[i]      .textContent.primaryText.text = cardText;    datasource.listTemplate2ListData.listPage.listItems[i]      .image.sources[0].url = url;    datasource.listTemplate2ListData.listPage.listItems[i]      .image.sources[1].url = url;  }  // Give an appropriate hint  if (game.state === 'FIRSTDEAL') {      if (game.cards[0].hold) {        datasource.listTemplate2ListData.hintText="discard the first card";      } else {        datasource.listTemplate2ListData.hintText="hold the first card";      }      datasource.listTemplate2Metadata.title="Select cards to hold or say Deal";    } else {      datasource.listTemplate2ListData.hintText="deal";      datasource.listTemplate2Metadata.title="Your last hand";    }  }  return handlerInput.responseBuilder    .addDirective({      type: 'Alexa.Presentation.APL.RenderDocument',      version: '1.0',      document: main,      datasources: datasource,    });}

Al doilea loc în care a trebuit să fac o modificare a codului a fost să mă ocup de utilizatorul care atinge unul dintre elementele din lista mea. În vechiul meu cod, analizam jetoane de articole de forma „card.x” unde x este poziția ordinală a cărții din listă. Cu o interfață de afișare, aceasta însemna căutarea unui ElementSelected cerere. În APL, codul dvs. va primi un APL.Presentation.APL.UserEvent, și puteți procesa solicitarea după cum urmează pentru a determina ce carte a fost selectată:

module.exports = {  canHandle(handlerInput) {    const request = handlerInput.requestEnvelope.request;       // Was this a touch item selected?    if (request.type === 'Alexa.Presentation.APL.UserEvent') {      return ((request.source.type === 'TouchWrapper')        && (request.source.handler === 'Press'));    }    return false;  },  handle(handlerInput) {    let index;    const event = handlerInput.requestEnvelope;    // Was this a touch item selected?    if (event.request.type === 'Alexa.Presentation.APL.UserEvent') {      const cards = event.request.arguments[0].split('.');      if (cards.length === 2) {        index = cards[1];      }            // Do something with the selected card...
    }  },};

Odată cu aceste schimbări, am avut o abilitate de Video Poker mult mai curată, care sigur îmi va încânta clienții mai mult decât formatul mai vechi pe care îl foloseam. Tocmai am început să zgâriem suprafața în ceea ce privește capacitățile APL. Dar pot să spun că va deschide o nouă lume de posibilități pentru abilitățile multimodale bazate pe voce! Spuneți-mi în comentariile despre propriile învățături cu acest nou cadru.