# Handlebars ## Simple example QnABot now lets you use [Handlebars](https://handlebarsjs.com/) 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: 1. Log in to the Content Designer, and choose **Add**. 1. Enter ID: *Handlebars.001* 1. Enter question: *What is my interaction count?* 1. Enter answer: *So far, you have interacted with me {{UserInfo.InteractionCount}} times.* 1. Save the new item. 1. Use the Web UI, or any Alexa device to say “*What is my interaction count?*” to your bot, and listen to it respond.  1. Ask a few more questions, and then ask “*What is my interaction count?*” again. Notice that the value has increased. 1. In Content designer, edit item Handlebars.001 1. 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}}_ 1. 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. ## Available variables (handlebars context) 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 - see helpers 'setSessionAttr' and 'getSessionAttr' | |Slots._name_ | all slots filled by Lex are available to the handlebars context - see helper 'getSlot' | |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)| ## Helpers You can use any [built-in handlerbars helpers](https://handlebarsjs.com/guide/builtin-helpers.html). 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_'}} | |getSlot | Returns named slot value if it is defined, or default value. | {{getSlot '_slotName_' '_default_'}} | |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'}}| ## Comments Use the handlebars comment syntax to make your handlebars easier to understand.. {{!-- comment --}} ## Examples ``` {{!-- 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'}} {{!-- get Slot value, or default if slot doesn't exist or is not defined --}} Hi {{getSlot 'firstname' 'stranger'}}! {{!-- 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'}} ```