QnABot now lets you use Handlebars templates in your answers, including the Markdown and SSML fields, so you can include variable substitution and conditional elements. Let's try a simple example to illustrate the concept:
- Log in to the Content Designer, and choose Add.
- Enter ID: Handlebars.001
- Enter question: What is my interaction count?
- Enter answer: So far, you have interacted with me {{UserInfo.InteractionCount}} times.
- Save the new item.
- Use the Web UI, or any Alexa device to say “What is my interaction count?” to your bot, and listen to it respond.
- Ask a few more questions, and then ask “What is my interaction count?” again. Notice that the value has increased.
- In Content designer, edit item Handlebars.001
- Modify answer to:
So far, you have interacted with me {{UserInfo.InteractionCount}} times.
{{#ifCond UserInfo.TimeSinceLastInteraction '>' 60}}
It's over a minute since I heard from you last.. I almost fell asleep!
{{else}}
Keep those questions coming fast.. It's been {{UserInfo.TimeSinceLastInteraction}} seconds since your last interaction.
{{/ifCond}} - Use the Web UI, or Alexa, to interact with the bot again. Wait over a minute between interactions and observe the conditional answer in action.
QnABot exposes the following content to the Handlebars context:
Context Variable | Notes |
---|---|
LexOrAlexa | Indicates if QnABot access method is LEX or ALEXA |
ClientType | Detected client type. May be ALEXA, LEX.Slack.Text, LEX.TwilioSMS.Text, LEX.AmazonConnect.Text|Voice, LEX.LexWebUI.Text|Voice, or LEX.Text|Voice |
UserInfo.UserId | Lex or Alexa user id set by client (For Twilio SMS, UserId is the user's phone number) |
UserInfo.InteractionCount | Accumulating interaction count for UserId (not including current interaction) |
UserInfo.FirstSeen | Date and time of user's first interaction with QnABot |
UserInfo.LastSeen | Date and time of user's most recent previous interaction with QnABot |
UserInfo.TimeSinceLastInteraction | Number of seconds between current and previous interaction (seconds since epoch for first interaction) |
UserInfo.UserName | UserName: Authenticated users only - from token in session attribute 'accesstokenjwt' |
UserInfo.GivenName | Given Name: Authenticated users only - from token in session attribute 'accesstokenjwt' |
UserInfo.FamilyName | Family Name: Authenticated users only - from token in session attribute 'accesstokenjwt' |
UserInfo.Email | Email address: Authenticated users only - from token in session attribute 'accesstokenjwt' |
UserInfo.isVerifiedIdentity | true or false: Authenticated users only - verifies if token is signed by key in jwks from trusted identity provider per QnABot setting IDENTITY_PROVIDER_JWKS_URLS |
SessionAttributes.name | all session attributes are available to the handlebars context |
Settings.name | all settings values are available to the handlebars context |
Question | the users utterance, or question - translated to English if ENABLE_MULTI_LANGUAGE_SUPPORT is true |
OrigQuestion | the users utterance, or question - before translation to English if ENABLE_MULTI_LANGUAGE_SUPPORT is true |
PreviousQuestion | the users previous utterance, or question |
Sentiment | the detected sentiment value of user's question/utterance (POSITIVE|NEGATIVE|NEUTRAL|MIXED) |
You can use any built-in handlerbars helpers.
QnABot also provides these additional helpers:
Helper | Descr | Example |
---|---|---|
ifCond | Block helper for conditional output. Supported comparison operators: '==', '===', '!=' ,'!==', '<', '<=', '>', '>=', '&&','||' |
{{#ifCond LexOrAlexa '==' 'LEX'}} output if true {{else}} output if false {{/ifCond}} |
getSessionAttr | Returns named session attribute value if it is defined, or default value. | {{getSessionAttr 'attrName' 'default'}} |
setSessionAttr | Sets a named session attribute to specified value. | {{setSessionAttr 'attrName' 'value'}} |
randomPick | Randomly return a string selected from a list. | {{randomPick "Greetings." "Hi there!" "Howdy" "Hello, how are you?" "Whassup dude!" }} |
signS3URL | Converts S3 URL to a signed URL with 300 sec expiration. S3 bucket name must start with QNA or qna, or policy granting bucket read access must be added to ESProxyLambdaRole. | {{signS3URL 'https://qnabot-images.s3.amazonaws.com/testimage.png'}} |
Use the handlebars comment syntax to make your handlebars easier to understand..
{{!-- comment --}}
{{!-- respond with users name if known --}}
{{#if UserInfo.GivenName}}
Greetings {{UserInfo.GivenName}}!
{{else}}
Greetings friendly human!
{{/if}}
{{!-- Conditional welcome back message --}}
{{#ifCond UserInfo.TimeSinceLastInteraction '>' 3600}}
You've been gone for a while. I missed you!
{{/ifCond}}
Ask me a question. Try to stump me.
{{!-- check and set session Attribute --}}
{{#if SessionAttributes.testAttr}}
Session Attribute "testAttr" is already set: {{SessionAttributes.testAttr}}
{{else}}
Setting Session Attribute "testAttr"
{{setSessionAttr 'testAttr' 'BobRocks'}}
Done
{{/if}}
{{!-- get nested Session Attribute, or default if attribute doesn't exist or is not defined --}}
Previous answer was qid: {{getSessionAttr 'qnabotcontext.previous.qid' 'No previous response'}}
{{!-- pick a random answer from list below --}}
{{randomPick
"Greetings."
"Hi there!"
"Howdy"
"Hello, how are you?"
"Whassup dude!"
}}
{{!-- Support different for Slack answer--}}
{{!-- NOTE: QnABot now automates conversion of standard markdown to Slack markdown syntax - always author in standard markdown --}}
{{#ifCond ClientType '==' 'LEX.Slack.Text'}}
Slack Message
{{else}}
Other client message
{{/ifCond}}
{{!-- Use S3 Signed URL as a hyperlink to document/image in S3 --}}
{{!-- S3 bucket name must start with QNA or qna, otherwise bucket access must be granted to ESProxyLambdaRole in IAM --}}
Here is a link to my S3 doc: [link]({{signS3URL 'https://qnabot-docs.s3.amazonaws.com/mydoc.pdf'}})
{{!-- You can also generate a S3 signed URL as an Image URL for a Response Card --}}
{{signS3URL 'https://qnabot-docs.s3.amazonaws.com/myimage.png'}}