The text in the Suggestion helps to move the next intent that has the text of Suggestion.
In the example of below, if the user click that button, the intents would move to the other intents that have 'dirrecion' as training phrase.
agent.add(new Suggestion(`dirrecion`));
But I want to make this same thing with 'Card'.
So I made like below code seeing doucments of Dialogflow. But it doesn't work.
Could you give me the solution?
agent.add(new Card({
title: `temperature`,
imageUrl: wikipediaTemperatureImageUrl,
text: `how are you`,
//buttonText: 'Temperature Wikipedia Page',
buttons: [
{
postback: `move`,
text: `Card Link Title`
}]
})
);
Related
I am trying to create a messenger bot using Microsoft bot framework
I am using a waterfall dialog to create the flow of the structure.
In this, I have multiple steps were in a particular step I need to send a carousel of four hero cards with buttons for each.
I have used the answer by steven,
Handling HeroCards responses In Microsoft Bot Framework v4 for NodeJS
I work fine while testing in bot emulator and webchat
But produces an error while testing in messenger bot
can anyone help me to rectify this error, Thanks in advance
async locationStep(step) {
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is a Prompt Dialog.
// Running a prompt here means the next WaterfallStep will be run when the user's response is received.
await this.sendIntroCard(step)
await step.context.sendActivity("How often do you use surface on the move?")
let acard =CardFactory.heroCard(
" ",
[`https://scontent.fmaa1-4.fna.fbcdn.net/v/t1.0-9/89121134_2372258766207358_5255590702309441536_n.jpg?_nc_cat=109&_nc_sid=8024bb&_nc_ohc=1cHak5WO_yoAX-VdtfO&_nc_ht=scontent.fmaa1-4.fna&oh=fd002544bc74bf53ae0185f4c192efe6&oe=5E82E09B`],
[{ type: ActionTypes.PostBack,
title: 'Never',
value: 'Never'}]
);
let bcard =CardFactory.heroCard(
" ",
['https://i.imgur.com/m2DWB7m.jpg'],
[{ type: ActionTypes.PostBack,
title: 'Once in a while',
value: 'Once in a while'}]
);
let ccard =CardFactory.heroCard(
" ",
['https://i.imgur.com/Kwn0FBn.jpg'],
[{ type: ActionTypes.PostBack,
title: 'A few days a week',
value: 'A few days a week'}]
);
let dcard =CardFactory.heroCard(
" ",
['https://i.imgur.com/mAlW0Bv.jpg'],
[{ type: ActionTypes.PostBack,
title: 'Every day',
value: 'Every day'}]
);
await step.context.sendActivity( {attachments:[acard,bcard,ccard,dcard],attachmentLayout: AttachmentLayoutTypes.Carousel
});
return await { status: DialogTurnStatus.waiting };
}
Your issue is caused by the space you have included as the title of your hero cards: " ". Fixing your problem is simple. You can using an actually empty string without the space ("") or even omitting the title altogether.
EDIT: As you've seen, the Bot Framework will add "Options" as the card's title if you haven't provided one because it uses Facebook Messenger's generic template which requires a title. There is nothing the Bot Framework can do and there's nothing you can do to bypass Facebook's API restrictions. However, if you really want to send a card with an image and buttons then you can use a media template. This will be inconvenient because you'll need to upload the image attachment beforehand so you can get an attachment ID using this API: https://developers.facebook.com/docs/messenger-platform/reference/attachment-upload-api
Rather than having your bot upload the images every time it needs to use them, you should be able upload each image once on your own and then give the ID's to your bot. Once you've uploaded your attachments, you can send a media template directly using the Send API or using the Bot Framework activity's channel data according to these instructions: https://blog.botframework.com/2017/03/28/custom-channel-data/
await step.context.sendActivity( {
"channelData": {
"attachment": {
"type": "template",
"payload": {
"template_type": "media",
"elements": [
{
"media_type": "image",
"attachment_id": "<YOUR_ATTACHMENT_ID>",
"buttons": [
{
"type": "postback",
"payload": "Never",
"title": "Never"
}
]
},
// More media templates ...
]
}
}
}
} );
Since this may be more complicated than you'd like, you might consider an alternative design like Messenger's quick replies.
I have an List showing 3 items but when I select an item from the list(intent1) then it works and triggers the intent2 but after few intents if I again type the item name then the intent2 doesn't triggers and gives the response of fallback intent.
this is my code
const ItemList = {
title: "Select to update.",
items: {
"Games": {
title: "Games",
description: "Click here to update Games details.",
image: new Image({
url: 'https://img.icons8.com/plasticine/2x/name.png',
alt: 'p1',
}),
},
"Books": {
title: "Books",
description: "Click here to update Books details.",
image: new Image({
url: 'https://img.icons8.com/plasticine/2x/name.png',
alt: 'p2',
}),
},
"Language": {
title: "Language",
description: "Click here to update Language details.",
image: new Image({
url: 'https://img.icons8.com/plasticine/2x/name.png',
alt: 'p3',
}),
},
},
}
app.intent(SHOW_LIST_INTENT, (conv) => {
conv.ask("Here's the list.");
conv.ask(new List(ItemList));
});
app.intent(SELECTED_ITEM_INTENT, (conv, input, option) => {
conv.contexts.set(AppContexts.AWAITING_ITEM, 1, {item: option});
if (option === 'Games'){
conv.ask(`Which is your favorite Game?`);
} else if (option === 'Language'){
conv.ask(`Which ${option} do you know?`);
} else if (option === 'Books'){
conv.ask(`Your favorite ${option} name?`);
}
});
app.intent(HANDLER_INTENT, (conv, parameters) => {
const context = conv.contexts.get(AppContexts.AWAITING_ITEM);
const selectedItem = context.parameters.item;
if (selectedItem === 'Games'){
conv.ask(`${parameters} is updated as your favorite Game. ` + `Your next preference?`);
conv.ask(new Suggestions([`Add More Games`, `Show List`]));
} else if (selectedItem === 'Books'){
conv.ask(`${parameters} is updated as your favorite Book. ` + `Your next preference?`);
conv.ask(new Suggestions([`Add More Books`, `Show List`]));
} else if (selectedItem === 'Language'){
conv.ask(`${parameters} is updated as your Language. ` + `Your next preference?`);
conv.ask(new Suggestions([`Add More Language`, `Show List`]));
}
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
I want to trigger the SELECTED_ITEM_INTENT when user says Add More Games
how to get this, is there anything missing in the code.
I think the design of your conversation is a little confused, and this may be making it more difficult to do exactly what you want.
Your SELECTED_ITEM_INTENT is only triggered based on interaction with the list, and you are prompting them to say something. Since the list is no longer active, and you don't have any Intents set to handle any of the phrases, then nothing will match.
Rather than relying on a visual list (which will not work well for all Assistant platforms), you may want to approach it more as a voice conversation. Under this model, you can picture conversations that look something like this:
Agent: Would you like to update the Games, Books, or Language details?
User: Games
Agent: What is your favorite game?
User: Rock, paper, scissors
Agent: Rock, paper, scissors has been set as your favorite game. What would you like to update next?
User: Another game
...
Or the conversation could go something like this
Agent: Would you like to update the Games, Books, or Language details?
User: Game details
Agent: What is your favorite game?
User: Rock, paper, scissors
Agent: Rock, paper, scissors has been set as your favorite game. What would you like to update next?
User: Another game
...
But what if they said something like this instead?
Agent: Would you like to update the Games, Books, or Language details?
User: Books
Agent: What is your favorite book?
User: I meant game
Agent: What is your favorite game?
User: Rock, paper, scissors
Agent: Rock, paper, scissors has been set as your favorite game. What would you like to update next?
User: I don't know
...
From this, we might think that users would reply in one of three ways:
Indicating what category they want with phrases such as "Book", "Games", "Language details", "I mean games", "Add more languages", "Another book", etc.
This suggests that each category might be a good Entity for the phrases the user might say.
With the value of whatever they're updating
This is well handled by using a Context to know when we're asking for something specific. As you've done.
Asking for help with phrases such as "What can I do?" or "I don't understand."
Each of these would be done using an Intent with phrases and Input Contexts tuned for those phrases. In the output, we might use Suggestion Chips where appropriate to cue for the possible categories we expect for the first Intent.
But we haven't considered a few other things the user might have said. What, for example, if we had
Agent: Rock, paper, scissors has been set as your favorite game. What would you like to update next?
User: Add another one
The user knows that they just set a game, and they want to set another one. But they haven't used the term "game" specifically. We will need to keep track of what category they last updated in a Context and have another Intent that can handle phrases like "Add another one" or "The same thing".
But what if our users start doing this a lot and we have an interaction such as
Agent: Rock, paper, scissors has been set as your favorite game. What would you like to update next?
User: Add a book named Dungeon Masters Guide
Here, they've combined to things that we thought of as separate Intents. So we may need to add an Intent that handles phrases such as this, where they specify both the category and the information at the same time.
This is something that is confusing me. So, I have the following carousel with three items:
//This is my test Carousel
function googleAssistantOther1(agent){
let conv = agent.conv();
conv.ask('Please choose an item');
conv.ask(new Carousel({
title: `All Items`,
items: {
'WorksWithGoogleAssistantItemKey1':{
title: `My Message`,
description: `No description required`,
image:{
url: 'https://i.imgur.com/sdUL0T7.png',
accessibilityText: `item1`,
},
},
'GoogleHomeItemKey1': {
title: `Test1`,
description: `blah blah`,
image: {
url: 'https://i.imgur.com/sdUL0T7.png',
accessibilityText: `item2`,
},
},
'SomeRandomKey1':{
title: `Test2`,
description: `blah blah blah`,
image: {
url: 'https://i.imgur.com/sdUL0T7.png',
accessibilityText: `item3`,
},
},
},
}));
// Add Actions on Goole responses to your agent's response
agent.add(conv);
}
When I test it in Actions on Google Simulator, it is working perfectly. However, when I click on the carousel item (say first one) it does not trigger the intent associated with the title. For example, in Simulator if I type "My message" the intent will be triggered but when I click on the carousel item with the same title "My message" the following happens:
So my question is how can I trigger "My message" intent by clicking on carousel item. Any solution or suggestion would be appreciated.
When a list carousel card(or item) is tapped, it generates an event that will hit your webhook, unlike the simple text message.
1st way (if your webhook handling the response)
So you need to handle it in your code.
Generally, it should have intent as actions_intent_OPTION. from there you need to segregate it.
2nd way (if your code is not handling the response)
In this way, your intent must be able to handle actions_intent_OPTION event generated by the carousel(or list).
for that, your intent need to add the event as shown in below image (Basically it tells the dialogflow that whenever the actions_intent_OPTION events triggered, this intent is capable to handle it, but currently in your case, no intent matches the description and it's going to Default Fallback Intent)
So whenever the list item tapped it can handle the flow.
For more refer this documentation.
Is it possible to configure the response in DialogFlow in such way that
when I enter the Facebook quick reply I will leave the title blank?
I want the user to get only the options without a title.
For example if I have:
Title: Choose an item
Quick reply 1: A
Quick reply 2: B
Quick reply 3: C
Can I somehow remove the title from displaying on FB?
Please advise.
If you see quick reply payload docs ,
The properties are,
text String
Non-empty message text to send with the quick replies. text or
attachment must be set.
attachment Object
An attachment to send with the quick replies. text or attachment must
be set.
quick_replies Array
An array of objects the describe the quick reply buttons to send. A
maximum of 13 quick replies are supported.
Format must be like,
{
"text": "Pick a color:", // non-empty string
"quick_replies":[
{
"content_type":"text",
"title":"Red",
"payload":"<POSTBACK_PAYLOAD>",
"image_url":"http://example.com/img/red.png"
},{
"content_type":"text",
"title":"Green",
"payload":"<POSTBACK_PAYLOAD>",
"image_url":"http://example.com/img/green.png"
}
]
}
I little late but this is when I saw the post. If case you strill need a solution I accomplished the aforementioned by using a custom payload like this:
{
"facebook": {
"attachment":{
"type":"template",
"payload":{
"template_type":"generic"
}
},
"quick_replies":[
{
"content_type":"user_email",
"title":"Red",
"payload":"<POSTBACK_PAYLOAD>",
"image_url":"http://example.com/img/red.png"
},{
"content_type":"text",
"title":"Green",
"payload":"<POSTBACK_PAYLOAD>",
"image_url":"http://example.com/img/green.png"
}
]
}
In the attachment payload you can create any rich content you like, card, carousel, etc. and then attach some quick reply buttons without a title. Also in the quickReply section you can change the text for any other like user_email or user_phone_number.
Hope this help
I'm facing a very strange issue that is probably linked to cache.
So here it is .
I have developped a bot in nodejs for telegram.
This bot HAD in the past a custom keyboard that was not a "inline_keyboard"
I decided to change that behaviour and have implemented inline_keyboard.
current code is something like that :
var options = {
parse_mode: "Markdown",
disable_web_page_preview: true,
reply_markup: JSON.stringify({
inline_keyboard: [
[{
text: '🇫🇰 English',
callback_data: "SET ENGLISH"
},{
text: '🇫🇷 Français',
callback_data: "SET FRENCH"
}]
]
})
};
bot.sendMessage(msg.chat.id, "Please choose your language",options);
Inline_keyboard is working fine but my old code (that has been deleted) is still appearing to my users and is very anoying.
Here it is; it keeps on appearing when my users log into my chat.
I have been the following ressources :
https://core.telegram.org/bots/api#replykeyboardremove
How do you remove reply keyboard without sending a message in Telegram?
https://core.telegram.org/bots/api#editmessagereplymarkup
But i don't see how to implement it so I can remove this annoying chat for my users.
Any suggestions ?
Thx for your support
there may be different solutions to do so, my suggestion:
you can use the very first answer of each user to remove keyboard, first use editMessageText to remove keyboard and then send him the appropriate answer.(note that persist chatIDs that you have removed their keyboard, so you will do this for each user just once)
bot.on('callback_query', function onCallbackQuery(callbackQuery) {
if(!didWeRemoveHisKeyboard(callbackQuery.from.id))
removeHisKeyboard(callbackQuery)
//then handle the user response
})
removeHisKeyboard = function(callbackQuery){
bot.editMessageText(callbackQuery.message.text,
{message_id:callbackQuery.message.message_id , chat_id:callbackQuery.from.id,
reply_markup: {
remove_keyboard: true
}}).catch((err) => {
//some error handling
}).then(function(res){
if(res)
addThisChatToHandledList(callbackQuery.from.id)
})
}
note that you may need some modification on this code based on the node_module you're using.