DialogFlow NodeJs - Set Response Message after webhookClient.setFollowupEvent - node.js

I am using https://github.com/dialogflow/dialogflow-fulfillment-nodejs to create fulfillment webhook for dialogflow.
Currently I have intent that have 1 required parameter with prompt (so the agent will ask specific question for this parameter) and enable webhook call for this intent.
In the webhook, I check the parameter if that parameter is valid (call external api or something else), then I will trigger setFollowupEvent to move to other intent. But if the parameter is not valid, then I will trigger setFollowupEvent to return to this intent so the user should input it again. But I want to give the user a reason why that parameter is not valid.
The code is something like this
function registerUserStartHandler(agent) {
let payload = request.body.originalDetectIntentRequest.payload;
let senderDetail = getSenderDetail(payload);
return isUserRegistered(senderDetail.senderId, senderDetail.platformType).then((res) => {
if (res) {
agent.add('User already registered, enter another user');
//register_user_ask_user is this same intent (so I just returned to current intent if failed)
agent.setFollowupEvent('register_user_ask_user');
} else {
agent.setFollowupEvent('register_user_ask_other_info');
}
return Promise.resolve();
})
}
But, currently dialogflow will return to user the prompt message that I defined for that required parameter not the reason message.
How to replace this prompt message with my message from webhook?

Related

Check if command is run in a server?

I am making a bot in discord js, but I wanna check if the command is run in a specific server. How could I do this?
I have tried searching the internet but I couldn't find anything except for checking if member has permission or role.
If you're using interactions (slash commands):
// Where `interaction` is your `Interaction` object
if (interaction.guildId === "your guild id here") {
// Your guild-specific logic here
}
Or if you're using message-based commands:
// Where `message` is your `Message` object
if (message.guildId === "your guild id here") {
// Your guild-specific logic here
}
Based if you want to use slash commands or not. I think, that you are new to discord.js, so I would recommend normal commands.
You can use message event to run function when someone sends the message. In the funcion, you get the message as 1st parameter. First you have to get the message content via the .content property and then use the .startsWith function to check if it is the command that you need, then you can just compare the guild id, that you get from the .guildId property.
Code (untested):
client.on("messageCreate", message => {
if (message.content.startsWith("your command") && message.guildId === "your guild id") {
//your code
}
})

Google Action asking for parameters before account linking

I am using OAuth Authorisation Flow for my google action and for some reason, it is asking for parameters then initiating account linking and then asking for parameters again.
Example Response:
Code
app.intent('Create Channel Intent', async (conv, params) => {
if (!conv.user.access.token) {
conv.ask(new SignIn());
} else {
var locale = conv.user.locale;
if (locale === 'hi-IN') {
var accessToken = conv.user.access.token;
var channelNameRaw = params.channelname;
var channelNameData = await helperFunctions.hinditranslate(channelNameRaw);
var channelNameLwr = channelNameData.toLowerCase();
var channelName = helperFunctions.replaceWhitespacesFunc(channelNameLwr);
const headers = await helperFunctions.login(accessToken);
const speechText = await helperFunctions.createChannel(channelName, headers);
conv.ask(speechText);
} else {
var accessToken = conv.user.access.token;
var channelNameRaw = params.channelname;
var channelNameData = channelNameRaw.toLowerCase();
var channelName = helperFunctions.replaceWhitespacesFunc(channelNameData);
const headers = await helperFunctions.login(accessToken);
const speechText = await helperFunctions.createChannel(channelName, headers);
conv.ask(speechText);
}
}
});
Dialogflow
You shouldn't add training phrase to your SignIn event intent. If the intent which asks for signin permission has training phares would be enough. Because it directs to actions_intent_SIGN_IN event and continues on there unless user didn't signed in yet. I guess you made these two action in one intent so this makes it confused and tries to call same intent and asks for parameters.
If you had to use this way try to use context so you can pass parameter values to this intent on second call.
I am %99 sure that your intent's sloth filling is off.
Your Create Channel Intent has channelname as required parameter. Without Sloth-filling, intents won't call your server/code until every required parameter is fulfilled.
What happening is:
You are calling Create Channel intent and it asks for channel name as it is mandatory
User gives a channel name, intent calls your code as all required parameters are fulfilled.
Your code trigger sign_in intent as user haven't signed in yet.
User gives permission which triggers actions_intent_SIGN_IN event
Your Create Channel Intent has been called as it has actions_intent_SIGN_IN as trigger and asks for channelname as this intent is brand new.
To fix do one of this:
Enable sloth-filling at the bottom of intent.
Add an output context and add #[CONTEXT-NAME].channelname as default value to channelname parameter (without bracelets) . You can assign default values by clicking the appearing 3 dot when your mouse is over the parameter.
Split Capturing sign_in event from your Create Channel Intent
Hope it helps.

Regarding retrieving prompts

[We have a Dialogflow bot consisting of two intents. Each intent contains some set of questions.
The user answers the questions(prompts) and this process continues. We are getting the fulfillment text only after the intent is completed but we need to get the fulfillment text(Each and every prompt) after completing every question in that particular intent.
Help us in finding the solution.
You can use webhook for slot filling. (under the "Enable webhook call for this intent", enable Enable webhook call for slot filling button). By doing this, you can still stay in intent handler function and prompt what you need until you can finish your steps.
For example:
function flight(agent) {
const city = agent.parameters['geo-city'];
const time = agent.parameters['time'];
const gotCity = city.length > 0;
const gotTime = time.length > 0;
if(gotCity && gotTime) {
agent.add(`Nice, you want to fly to ${city} at ${time}.`);
} else if (gotCity && !gotTime) {
agent.add('Let me know which time you want to fly');
} else if (gotTime && !gotCity) {
agent.add('Let me know which city you want to fly to');
} else {
agent.add('Let me know which city and time you want to fly');
}
}
Also you can use this functionality on actions-on-google library.
Check for more information:
Webhook for slot filling
Enable Webhook for Slot Filling. Dialogflow will call your server to see if you can provide the pending information that your user didn’t.

Account linking Google actions via api.api

We are using api.api with fulfillment
After asking to sign in with the code:
app.askForSignIn();
We get intent call for input.unknown
We added sign handler but it is not called
const SIGN_IN = 'sign.in';
actionMap.set(SIGN_IN, signInLogic);
function signInLogic(app) {
let intent = app.getIntent();
console.log('signInLogic start intent: ', intent);
}
What needs to define in api.ai as intent to get the correct intent call?
I could not find a place to define system intents

Facebook Messenger Bot, can someone tell me how i catch the answer of a something i asked

So i working on my Facebook Messenger Bot.
I want to know ho can i catch a answer for a question like
Bot: Enter your E-mail
User: enters e-mail
Bot: adress was added
My code looks like the sample app from Facebook
app.post('/webhook', function (req, res) {
var data = req.body;
// Make sure this is a page subscription
if (data.object == 'page') {
// Iterate over each entry
// There may be multiple if batched
data.entry.forEach(function(pageEntry) {
var pageID = pageEntry.id;
var timeOfEvent = pageEntry.time;
// Iterate over each messaging event
pageEntry.messaging.forEach(function(messagingEvent) {
if (messagingEvent.optin) {
receivedAuthentication(messagingEvent);
} else if (messagingEvent.message) {
receivedMessage(messagingEvent);
} else if (messagingEvent.delivery) {
receivedDeliveryConfirmation(messagingEvent);
} else if (messagingEvent.postback) {
receivedPostback(messagingEvent);
} else {
console.log("Webhook received unknown messagingEvent: ", messagingEvent);
}
});
});
// Assume all went well.
//
// You must send back a 200, within 20 seconds, to let us know you've
// successfully received the callback. Otherwise, the request will time out.
res.sendStatus(200);
}
});
You can set a flag for their ID that the E-Mail prompt was sent, and then after they respond check to see if it's an E-mail, and if so, then save it and echo it back to them.
If the bot is based on question/answer, what I normally do to handle response tracking is treat the bot like a finite state automata. Assign every "state" your bot can be in to some unique state identifier, and use said state identifier to determine what the user is replying to. You could also store callbacks instead of state ids, but high level this will behave the same way.
For Example:
First define a finite automata. In this case, lets assume it's:
0 --> 1 --> 2
Where 0 means new user, 1 means waiting for email response, 2 means user successfully completed registration.
User messages bot
We check our database and see it's a new user. We assume
state==0.
Because state is 0, we ignore what was sent and prompt for email
Change state to 1 to denote the email was prompted.
User replies with email.
We check database and see state==1. We use the "1" routine to do fancy stuff to verify the email and store it.
Change state to 2 to denote the email was received and the program has ended.
Note:
If the conversation id for the platform you're targeting is reset
after a certain amount of inactivity (or if you just want the bot to
mimic real conversations), store the time of each user's last
interaction and purge all inactive conversations well after the
conversation has been terminated.

Resources