I have connected Dialogflow agent to a Facebook page, and i'm displaying Facebook card response using the fulfillment feature in Dialogflow. i can't figure out how to catch the card button click event. I need the chat to move to the next intent on button click. However button click doesn't trigger anything.
Here's the fulfillment code used to create button
function getState(agent){
state = agent.parameters.State;
return getAd()
.then(result => {
for(const item of result.result){
agent.add(new Card({
title: item.nmi,
imageUrl: 'url',
text: item.structuredAddress.singleAddressLine,
buttonText: item.nmi,
buttonUrl: 'uri'
})
);
}
})
.catch(() => {
agent.add(`I'm sorry.`);
});
}`
You can use the payload field in the postback button to send a
specific message back to dialogflow when the button is clicked.
If you combine this with the parameters, you can use them to trigger
specific intents, or just to send the information of the product
clicked
check the original answer Here
Related
I currently have a node bot embedded on my web app via direct line but I am struggling to attach:
Spotify Audio
I am trying to do so by using the URL attachment or an adaptive card, but the spotify embed doesn't play
Below is the code I use:
var send = {
text: "stuff",
attachments: [
contentType: "audio/ogg",
contentUrl: "spotifyEmbedUrl"
]
}
await stepContext.context.sendActivity(send);
I am unsure on how I can get spotify audio to play.
Is there a way I can return HTML code (and so get around it by adding an iframe into the chat etc?)
OR maybe I could create a modal popup that I could create the embed iframe?
Any help would be appreciated!
Unfortunately, you can't just send a file to a web page and it automatically start playing. Additionally, while Spotify provides embed URLs, which are not a direct link to an audio file, you can't simply tell the browser to play the file.
However, Spotify provides the embed code for displaying a play button that can be used in a page to play a song. Assuming you are using Web Chat in a web site (and even if you're not, this will give you an idea) and that, from the code you supplied, you are wanting to send the song in an activity, you can achieve this by sending the embed code in the activity, instead, via Web Chat's store. When the activity is received, the embed code is passed to a function to update the page and, thus, display the play button.
Be aware, the play button is essentially a UI widget, not a media player. There is no functionality available for telling the play button to auto play, stop, or anything else. The most you can do is display the button after which the user will be required to interact with it.
Also, this is a someone bare bones, simplified implementation. There are many things that aren't accounted for - please don't consider this a complete solution. There are aspects you will need to consider (e.g. multiple cards that utilize a postBack action).
In your bot: You want to send the embed code in an activity. Whether that is an event, message, or something else, is up to you. As you can see below, I have chosen to send a hero card that initiates a postBack when the button is pressed (a postBack sends data behind the scenes without displaying the action to the user).
const card = CardFactory.heroCard(
"Rome Wasn't Built in a Day",
null,
CardFactory.actions([
{
type: 'postBack',
title: 'Read more',
value: `<iframe src="https://open.spotify.com/embed/track/6lzd7dxYNuVSvh7sJDHIa3" width="300" height="380" frameborder="0" allowtransparency="true" allow="encrypted-media"></iframe>`
}
]),
{
subtitle: 'Artist: Morcheeba',
text: 'Album: Parts of the Process - released 2003'
}
);
await stepContext.context.sendActivity({ attachments: [card]});
Web Chat: First, use Web Chat's store to filter on incoming activities that include attachments where the button type (action) is postBack. When the condition is met, get the last card rendered and assign an event listener. When the card's button is clicked, get the 'spotify' container element and update the innerHTML with the embed code that was sent in the activity, thus displaying the play button.*
Please note, the setTimeout() used below is necessary for enabling the click action. Without the time out, the event listener being appended to the button would occur before the store finished processing the incoming activity.
<div id="webchat" role="main"></div>
<div class='spotify'></div>
[...]
const store = window.WebChat.createStore( {}, ( { dispatch } ) => next => action => {
if ( action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' ) {
const activity = action.payload?.activity;
if (activity.attachments && activity.attachments[0].content.buttons[0]?.type === 'postBack') {
setTimeout(() => {
const spotifyIframe = activity.attachments[0].content.buttons[0].value
let cards = document.querySelectorAll( '.ac-adaptiveCard' )
let cardLength = cards.length;
let card = cards[ cardLength - 1 ];
card.querySelectorAll( 'button' ).forEach( button => {
button.addEventListener( 'click', ( e ) => {
e.preventDefault();
const spotifyContainer = document.querySelector( '.spotify' );
spotifyContainer.innerHTML = spotifyIframe
} )
} );
}, 300);
}
next( action );
} );
Hope of help!
I'm trying to use Fulfillment with a Webhook to return a JSON to Dialogflow that will show a card in Google Assistant. I got the JSON directly from here:
https://developers.google.com/actions/conversation-api-playground
However, the card is not showing in the Google Assistant Simulator.
The simulator has a tab called "Response" and I can see the json response.
No errors in the error tab.
Have you added a subTitle to the basic card? That might be the issue here.
conv.ask(new BasicCard({
text: 'This is the Text',
title: 'Title',
subtitle: "This is a subtitle",
buttons: new Button({
title: 'Read More',
url: 'https://assistant.google.com/',
}),
image: new Image({
url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
alt: 'Image alternate text',
}),
}));
Please make these changes and try again.
what key should I use in
var notification = new Notification('hi', {
icon: 'xxx.png',
body: "click me",
})
to override the bottom text on notification ?
Currently I'm using a stripe payment button as a way to charge users. however, the process for this is:
they get an email, the email has a pay button.
once you press the button, the button launches a page with a stripe pay button.
pressing the stripe pay button opens the card payment.
I'd like to be able go straight from the user pressing the email's pay button to the card payment page opening up, instead of them having to press another button.
I've been using https://stripe.com/docs/checkout. I think that calling the stripecheckout.open directly would do the trick, however, I'm not sure how to format this call correctly with javascript.
For example, when the email pay button is pressed, the stripe pay button is generated like this
res.write('<script ');
res.write('src="https://checkout.stripe.com/v2/checkout.js" class="stripe-button"');
res.write('data-key="' + body[0].data_key + '"');
res.write('data-amount="' + body[0].data_amount +'"');
res.write('data-name="' + body[0].data_name + '"');
data_desc_string = body[0].data_description;
data_desc_short = data_desc_string.substring(7);
res.write('data-description="' + data_desc_short + '"');
res.write('data-currency="usd">');
res.write('</script>');
I'm not sure how I should rewrite it just for the stripecheckout.open.
The Custom Buttons section of the Checkout docs details how to call StripeCheckout.open().
In your case, you simply call StripeCheckout.open() once the page has loaded (because you want it to appear immediately) instead of in response to a button click (as in the example).
How exactly you'd go about that would vary with the JS framework you're using. Using jQuery as in their example code, you'd bind to $(document).ready():
<script src="https://checkout.stripe.com/v2/checkout.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
<button id="customButton">Purchase</button>
<script>
$(document).ready(function(){
var token = function(res){
var $input = $('<input type=hidden name=stripeToken />').val(res.id);
$('form').append($input).submit();
};
StripeCheckout.open({
key: 'pk_test_czwzkTp2tactuLOEOqbMTRzG',
address: true,
amount: 5000,
currency: 'usd',
name: 'Joes Pistachios',
description: 'A bag of Pistachios',
panelLabel: 'Checkout',
token: token
});
return false;
});
</script>
I am writing a Chrome extension, in which there is a dialog-like window to let users input the username and password, which are then sent back to background page to make a request for the token in OAuth 2.0.
To send the username and password from dialog window back to background page, I used the following codes (inside the dialog window .html file):
<script>
function usrpwd(){
var up = {};
up.usr = document.login_form.usr.value;
up.pwd = document.login_form.pwd.value;
chrome.tabs.sendRequest(window.dialogArguments,up);
window.close();
}
</script>
where the window.dialogArguments is supposed to be the tab ID of the extension's background page.
And the dialog window is opened in background page by
chrome.contextMenus.create({
"title" : "show Modal Dialog",
"contexts" : ["all", "page"],
"onclick": handle_click
});
function handle_click(){
chrome.tabs.getSelected(null, function(tab){
console.log('tab ', tab);
window.showModalDialog("login_popup.html", tab.id, "dialogHeight:300px; dialogLeft:200px;");
});
}
The tab.id is supposed to be the ID of the background page, and it will be passed to dialog window and assigned to window.dialogArguments.
Also in the background page, the username and password are received by,
chrome.extension.onRequest.addListener(
function(request){
console.log("Username: ", request.usr);
console.log("Username: ", request.pwd);
}
);
However, console.log('tab ', tab) inside the handle_click function always shows that the getSelected tab is the tab where the context menu got clicked, not the background page. So I am wondering how to get the tab ID of the background page in this case. Or is there any other better ways to communicate between dialog window and background page?
Thanks a lot!
Background pages do not have a tabId, since they are not tabs.
To send a message to the background page, use chrome.extension.sendRequest (extension instead of tabs).
PS. Full demo