NOTE – this blog entry was written for the old version of the Alexa Skills Kit Developer Console – whilst the PHP server code still works some info and screen shots of the developer console are now obsolete!
In part one of the Alexa PHP Hello World example I created a very basic skill and a PHP app to show how to handle Amazon Alexa IntentRequest data and provide a response. In part two I will extend the code to allow us to create interactive prompt and responses.
If you are new to Alex skills and PHP read part one of this Hello World example first.
To demonstrate prompt and responses we will ask Alexa for a “clever quote”, Alexa will give us the quote and ask if we want another. If the user replies yes, Alexa reads another quote and prompts again until all the available quotes have been used.
Alexa Prompt and Response
To allow this prompt and response interaction we simply tell our skill to keep the session open when we require a response, and we store the data we need for the session in the session attributes array.
First let’s modify the Hello World skill interaction model :
{ "intents": [ { "slots": [ { "name": "command", "type": "COMMANDOBJECTS" }, { "name": "prompt", "type": "PROMPTOBJECTS" } ], "intent": "HelloWorld" }, { "intent": "HelpIntent" } ] }
Now we have command and prompt slots, with command objects and prompt objects to catch our prompt and response utterances. I have also added two new utterances
HelloWorld for {command}
HelloWorld {prompt}
“Clever” quotes
The clever quotes data is an array of sentences stored in Data::cleverQuotes(). We load the data, and then create a list of random numbers we will use as array keys to get random quotes from the array. The list of random array keys will be stored in the session data.
// clever quotes data // $_cleverQuotesData=Data::cleverQuotes(); $_cleverQuotesArrayKeys= range(0, (count($_cleverQuotesData)-1)); shuffle($_cleverQuotesArrayKeys);
- alexa ask hello world for clever quotes
In the HelloWorld php intent class I have added some new code to parse the user request for clever quotes. The response includes the first “clever quote” fetched from the array using the first of our random array key numbers and the prompt to the user – “would you like some more clever quotes“. We also set endsession to false to keep the session open and save the random key data and prompt count data we need for the next session.
// response // return array( 'intent' => array( 'response' => 'Ok, here comes your first clever quote : '. $_cleverQuotesData[$_cleverQuotesArrayKeys[0]]. ' Would you like some more clever quotes?', 'card' => array( 'title' => $_target, 'text' => $_now->format('H:i:s'). ' '. $_cleverQuotesData[$_cleverQuotesArrayKeys[0]], 'image' => false ), 'target' => $_target, 'status' => false, 'sessionattributes' => array('object' => 'clever quotes','target' => $_target,'prompt' => true, 'count' => 1,'data' => $_cleverQuotesArrayKeys), 'endsession' => false ) );
With the session still open the user has about 8 seconds to reply and we will see the response in the prompt slot. In the same way we parse the command slot data we parse the response slots for the yes or no response from the user.
If the user responded with yes, we extract the data we need from the session to provide the next “clever quote” and then provide the exact same response and session data including an incremented prompt count variable.
If there are no more quotes available we respond appropriately and end the session. Similarly if the user responds with no, we respond and end the session by setting endsession to true.
Alexa Session Data
If you check the logs generated by the php script you will see the session data:
[session] > Array ( [new] > [sessionId] > SessionId.1-2-3 [application] > Array ( [applicationId] > amzn1.ask.skill.1-2-3 ) [attributes] > Array ( [data] > Array ( [0] > 0 [1] > 1 [2] > 5 [3] > 3 [4] > 7 [5] > 4 [6] > 10 [7] > 6 [8] > 2 [9] > 8 [10] > 9 ) [count] > 1 [prompt] > 1 [object] > clever quotes [target] > clever quotes ) [user] > Array ( [userId] > amzn1.ask.account.123 )
Custom Help and Launch intent
Alexa has some default built in intents such as STOP, HELP and LAUNCH.
When you say “Alex open skillname” the LAUNCH intent is used. When you say HELP in a skill, the HELP intent is used. When you submit your skill Amazon will check these intents for functionality. To create your own custom LAUNCH and HELP intent responses you must create or edit the example file in AmazonDev/Alexa/Launch and AmazonDev/Alexa/Help.
The filenames should be as follows
launch123.php
help123.php
Where 123 is replaced with the last digits from your skill id, i.e. if your skill id is amzn1.ask.skill.111-222-333-444-555 then the launch and intent filenames should be
launch555.php
help555.php
You should also change the class name of the launch and help classes to the same as the filename (without .php). Now you can customise the launch and help intent for you skill by editing the responses in the help and launch methods.
public static function help($_alexaRequest=false) { $_response="Hello, I am happy to Help! To start this skill please say 'Alexa, open Hello World'"; $_card=false; $_endSession=false; $_sessionAttributes=false; $_outputSSML=false; return array( 'response' => $_response, 'card' => $_card, 'endsession' => $_endSession, 'sessionattributes' => $_sessionAttributes, 'outputssml' => $_outputSSML ); }
You can see here that it is relatively simple to include prompts and responses in your Alexa skill by controlling and storing data in the skill session.
The example “clever quotes” intent show here is published in the Alexa skill store as “Clever Stuff”.
The updated code for this Hello World and Clever Quotes example is available from github here.
Boris says:
Thank you for you great work so far. Are there any plans to support the new Dialog model from amazon in the near future?
https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/dialog-interface-reference
This could make the code part much leaner, when it comes to more complex implementations. I would highly appreciate to see this officially implemented in your library, so that I don’t have to start to “frickle around” with this 😉 Any feedback welcome.
Beside that: Cool stuff, thank you for publishing!
PAJ says:
The new skill builder tool looks good. The new dialog model is really just delegating some dialog tasks to the skill to ensure that all the required slots for the intent get filled before the intent request is sent. I will certainly start using the beta skill but I don’t think my server side code will change that much as we still need to parse the intent response and slot values to process the intent.
Johann says:
Great work PAJ! i’vegot build a nice SDK.
I agree completely with Boris.
Could you take a look at the multiturn dialog at alexa?
What are your next plans ?
Greetings
marcelo says:
HI how enable help content? I just see: “version”: “1.0”,
“response”: {
“outputSpeech”: {
“text”: “Sorry, there is no help configured for this skill. Next time”,
“type”: “PlainText”
},
PAJ says:
in AmazonDev\Alexa\Help copy example.php and rename it to helpxxx.php where xxx is the amazon id of your alexa application. Edit helpxxx.php and also change the class name to the be the same as the filename. This will then be the custom help action for your alexa app.
marcelo says:
done: file name helpamzn1.ask.skill.f1b1dfc1-09f0-4674-1111-XXXXXXXXX.php
inside helpamzn1.ask.skill.f1b1dfc1-09f0-4674-b07e-XXXXXXXXX:
/**
* ALEXA HELP CLASS
*
*/
class helpamzn1.ask.skill.f1b1dfc1-09f0-4674-b07e-XXXXXXXXX {
again dont work….. More things to do?
PAJ says:
My mistake it should just be the last part of the id – the part you have shown with X’s (with no minus ‘-‘ character just the alphanumerics). This should replace xxx in helpxxx.php. So if your id is alexa.blah.skill.000-111-222-333-444 then the help intent class would be help444
🙂
marcelo says:
Ok, done:
Stop and cancel working HELP not yet.
Two questions:
1) I need set anything in IntentFactory.php?
2) The name space is correct? namespace PAJ\Application\Amazon\Alexa\Help;
file name: helpxxxxxx.php
inside: class helpxxxxxx {
PAJ says:
You found another mistake – namespace for the help class should be
namespace PAJ\Application\AmazonDev\Alexa\Help;
marcelo says:
Ok fixit but dont work.
Another question: is missing log.php ?
marcelo says:
Fixed and add:
if (in_array(‘yes’, $_spokenWords) || in_array(‘ok’, $_spokenWords) || in_array(‘sure’, $_spokenWords))
but why Alexa dont undesrtand OK word ?
marcelo says:
and o.k. she dont understand again !!! Why?
PAJ says:
Maybe it should be ‘okay’ …
kcjames1138 says:
Marcelo, what did you do to fix custom help? It is not working for me. I modified the file name as PAJ indicated, the class name, and the name space.
PAJ says:
I have modified the launch and help filenames. If you are using the latest version from github the launch and help file and class names should be launch123 where 123 is the digits from the last section of your skill id.
kcjames1138 says:
I found the issue. It was in IntentFactory.php. Changed these lines:
if (isset($_applicationID[4])){$_alexaLaunchClass = __NAMESPACE__ . ‘\\Launch\\’.$_applicationID[4];}
if (isset($_applicationID[4])){$_alexaHelpClass = __NAMESPACE__ . ‘\\Help\\’.$_applicationID[4];}
To:
if (isset($_applicationID[4])){$_alexaLaunchClass = __NAMESPACE__ . ‘\\Launch\\’.’launch’.$_applicationID[4];}
if (isset($_applicationID[4])){$_alexaHelpClass = __NAMESPACE__ . ‘\\Help\\’.’help’.$_applicationID[4];}
Class names cant start with numbers and the keywords help and launch were left off the definition.
Regards,
PAJ says:
Yes I had changed that in my production code but had not pushed it to github until last week. Sorry about that…
Marcelo says:
99% ready, how Checking the Signature of the Request, using php not java?
SvenM. says:
Great and nice work!
Could you explain how we can use dialogs?
For example:
1. Dialog.Delegate: https://developer.amazon.com/de/docs/custom-skills/dialog-interface-reference.html#delegate
2. Dialog.ElictSlot: https://developer.amazon.com/de/docs/custom-skills/dialog-interface-reference.html#elicitslot
PAJ says:
sorry, I don’t have a version available for download.
kcjames1138 says:
Curious how to use link account with this library. Any tips?
PAJ says:
This is something I haven’t looked into yet but it is on my to do list!
kcjames1138 says:
Thanks. I added the new files, modified appropriately for the last section of my skill ID and am still getting the no help configured. Is there something else that changed outside of these files to make it work that I might need to include? I am using a version from a few weeks ago.
I also tried to certify and got a lot of errors on missing card images. They are set to false everywhere, so not sure what is going on there. Should I just set it to the card image if it doesn’t understand I dont want a card?
1. Images in home cards must display without error. We found home card(s) with images that were not displayed properly.
Please note that “No Image Found” is displayed in home card.
Please refer to test case 3.3 of the Submission Checklist for expected behavior.
Just as an FYI, I did update the card images you included to ones specific to my skill. They are PNGs same format and size as your samples.
PAJ says:
For the card image problem make sure you have set amazonCardImageFolder in config.php to the correct path to your images on your server.
kcjames1138 says:
The path configs were it. Can’t believe I missed those. Thanks.
marcelo says:
Hi,
How do ?
The skill end-point is not accepting valid signed requests. Please make sure that your signature URL validation is correct. Please refer to our documentation on how to build your Alexa Skill as a web service and validate requests and signatures.
PAJ says:
I take it your skill is failing Amazon certification. Have you checked the application logs for errors? I am resubmitting one of my skills with this version of the app to test it myself.
PAJ says:
My skill passed certification, so there must be some problem with your implementation.
marcelo says:
Ok, very very thanks, I will check again everything !!! About log, I dont find log.php.
marcelo says:
Hi again!
I see in cachealexarequest_2017-12-18.log:
Signature: xyz (hiden for public here)
Signaturecertchainurl: https://s3.amazonaws.com/echo.api/echo-api-cert-5.pem
and:
[userId] => amzn1.ask.account.xyz
[accessToken] =>
accessToken is empty, right this?
marcelo says:
My mistake!
const amazonCacheFolder=’/home/user/public_html/amazon/cache -> wrong
const amazonCacheFolder=’/home/user/public_html/amazon/cache/ -> OK !
marcelo says:
Well 99% done, just HELP is not working.
2. When users ask for “help” within the skill, it must return a prompt which instructs users how to navigate the skill’s core functionality. Additionally, the help prompt must end with a question for users and leave the session open to receive a response.
Marcelo says:
Hi!
The skill LIVE !!!! But, after receiving the email that was published, I started getting a 403 error when I used the skill in echo dot. When it is released, should we change anything? It was working perfectly in development mode.
PAJ says:
There is no difference to the app between dev and live.
Marcelo says:
Thank you, the error message in Alexa persiste will look at everything again !