Dialogflow : followEventInput - javascript

I want to use follow-up intent. My user says something which launch an intent, send a response and launch another one, which sends a response and launch another one... I use those function
function send_message_follow(res,output,token,quote,id,action,parametre){
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({
"fulfillmentText" : output,
"outputContexts": [
{
"name": id + "/contexts/connected",
"lifespanCount": 5,
"parameters": {
"token": token,
"quote" : quote
}
}
],
"followupEventInput": {
"name": action,
"languageCode": "fr",
"parameters": {
"param": parametre,
}
}
}));`
function send_message_final(res,output,token,quote,id){
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({
"fulfillmentText" : output,
"outputContexts": [
{
"name": id + "/contexts/connected",
"lifespanCount": 5,
"parameters": {
"token": token,
"quote" : quote
}
}
]
}));
However, output is not shown with send_message_follow. I works only with send_message_final. I could add the 1rst output as a parameter to catch for the other ones, but this shows only 1 block of message. I want 1 per intent.
Is there a way to fix this ? Thanks

No, there is no way to "fix" this. Follow up events are a way to redirect from the currently match intent to another intent. The currently match intent does not have a chance to respond before it is redirected. This means you will only have one response from the intent that is redirected to last. You can't compile response from multiple intent responses by redirecting through multiple intents with follow up events.
When a followup event is triggered from the webhook, the event specified in the webhook response is triggered. Triggering the event through a webhook sends the request back through Dialogflow for matching without responding to the user. The response to the user is sent as if the user triggered the event that was triggered in the webhook. After the second intent is matched by the event, Dialogflow will do any necessary work (like webhook calls or additional prompts for required parameters) and send a response back as if the second intent was the originally matched intent.
A user sends a request to Dialogflow.
"Intent 1" is matched by Dialogflow.
A webhook request is sent to your fulfillment server, which indicates that intent 1 was matched.
Your fulfillment server responds to the webhook request with a followup event response.
Dialogflow re-matches intent 2 based on the followup event sent in the webhook response.
Dialogflow sends a response to the user based solely on intent 2 being matched. Dialogflow may send another webhook call indicating intent 2 was matched, or send a prompt for unfulfilled required parameters (if configured) for intent 2.

Related

Commenting in real time using getstream

I'm working with the js/node api of getstream and I'm trying to add a realtime feature to the comments on the activities, but I'm receiving a 403 error, displaying I dont have permission.
I've tried using targetFeeds: '[timeline:userid]' but it wrecks the application.
Also I tried to use the notification feed as in the documents is being used, and I can set targetFeeds like this: '[notification:userid]' which obviously is not the desired thing to do because this will cause that every message on different activities of this user will be shown on the callback.
client.reactions.add("comment", activityId, {
"text": newComment,
"profileImage": 'https://i.pravatar.cc/300',
"timestamp": date,
"from": userId,
"id": foreignId,
},
{targetFeeds: [`CommentsFeed:${activityId}`]});
And the response of the 403 is the next one:
{
code: 17
detail: "You don't have permission to do this"
duration: "0.18ms"
exception: "NotAllowedException"
status_code: 403
}
The expected result is not having the 403, that will trigger the callback I implemented.
The default permission settings allow users to only write activities to their own feeds; in this case you are adding an activity to CommentsFeed:${activityId}.
You can request support (support#getstream.io) to whitelist this for you app(s). Just make sure to mention this case and include your applications.

Google Calendar API - Push notifications not working

I'm using the Google Calendar API and am trying to receive push notifications when a calendar event is triggered https://developers.google.com/calendar/v3/push
I think everything is setup correctly...
gapi.client.calendar.events.watch({
calendarId: 'primary',
resource: {
id: uuid,
type: 'web_hook',
address: window.location.href,
},
}, (err, response) => {
if (err) {
console.log('err:', err);
} else {
console.log('response:', response);
}
}).then((res) => {
console.log('res:', res);
});
But I guess not. I get a 200 response when I call the above code
{
"kind": "api#channel",
"id": "...",
"resourceId": "...",
"resourceUri": "https://content.googleapis.com/calendar/v3/calendars/primary/events?alt=json&maxResults=250&alt=json",
"expiration": "1554203159000"
}
I believe I should also be receiving a sync message, but I am not (https://developers.google.com/calendar/v3/push#sync)
To test things I am modifying an event within the calendar itself (changing the title, date, deleting, etc), and I expect something to happen in my browser, but nothing.
I'm not familiar with Push notifications in general, so not exactly sure what to expect.
I'm already authenticated and displaying events as per https://developers.google.com/calendar/quickstart/js
What am I missing? Any help is really appreciated!
Thanks in advance!
I suspect you are miss understanding exactly what push notifications is.
There are two primary ways to track when a resource has changed. You can poll that resource often and check for any changes in the resource.
For example Your application could run every five minutes and make a request to Google asking to have the event returned to you. When that event is returned you will then check if there are any changes in the event created by the user. This method of checking for changes is very time consuming and requires resources to constantly poll the server looking for changes. A better way of doing it is using Push notifications
Push notifications notify your application when a change has been made.
This document describes how to use push notifications that inform your application when a resource changes.
Its set up by enabling a watch
POST https://www.googleapis.com/calendar/v3/calendars/my_calendar#gmail.com/events/watch
Authorization: Bearer auth_token_for_current_user
Content-Type: application/json
{
"id": "01234567-89ab-cdef-0123456789ab", // Your channel ID.
"type": "web_hook",
"address": "https:/examle.com/notifications", // Your receiving URL.
...
"token": "target=myApp-myCalendarChannelDest", // (Optional) Your channel token.
"expiration": 1426325213000 // (Optional) Your requested channel expiration time.
}
This tells Googles servers that you would like to be notified when ever someone makes a change to the event. This sets up a web hook to https:/examle.com/notifications which will be notified as soon as there is a change to the event.
Name of the event, date time are normally changes i dont think you will get a push notification if someone else is added to the event.
What this is not
The server is NOT going to send you a message 10 minutes before the event is due. Thats user notification and something completely different and not part of the Google Calendar api.

Firebase FCM error: 'InvalidRegistration'

I am currently trying to send a PushNotification to a Device Group using FCM with the help of Firebase Cloud Functions but once the notification is sent, it returns with code 200 but with failure :
SUCCESS response= {
multicast_id: 8834986220110966000,
success: 0,
failure: 1,
canonical_ids: 0,
results: [ { error: 'InvalidRegistration' } ]
}
Here is the code I am using to send this notification... what am I missing?
const options = {
method: 'POST',
uri: 'https://fcm.googleapis.com/fcm/send',
headers: {
'Authorization': 'key=' + serverKey,
},
body: {
to: groupId,
data: {
subject: message
},
notification: {
title: title,
body: body,
badge: 1,
},
content_available: true
},
json: true
};
return rqstProm(options)
.then((parsedBody) => {
console.log('SUCCESS response=', parsedBody);
})
.catch((err) => {
console.log('FAILED err=', err);
});
Where JSON values title, body, subject, message are String
In my case, I was sending notifications to topic ("topics/my-topic"). I was missing prepending / in the starting of topic so I was getting the same issue. SO topic should be /topics/my-topic.
May be this helps!!
There is an easier way to send a message to a device group from a Cloud Function. Use admin.messaging().sendToDeviceGroup(). Sample code and instructions are in this guide.
I think your current method is failing because there is something wrong with the group notification key provided in groupId. It should be the string key value that was returned when you created the device group. The error codes are listed in this table. For 200/InvalidRegistration it says:
Check the format of the registration token you pass to the server.
Make sure it matches the registration token the client app receives
from registering with Firebase Notifications. Do not truncate or add
additional characters.
I was losing my mind with this InvalidRegistration error.
Eventually the problem was that I was subscribing my device to "example" but sending the notification json to: "example".
But we actually need to send to "/topics/example"
2 hours of my life wasted..
A registration token is tied to a certain group of senders. When a client app registers for FCM, it must specify which senders are allowed to send messages. You should use one of those sender IDs when sending messages to the client app.
Al you need to do is add a http header 'project_id' with your sender id.
I was getting InvalidRegistration:
Basic meaning: you are using the wrong token. Why? This may happen when you a new registrationToken is given to you in onNewToken (docs), but for some reason you are using the old token. That could happen when:
You're using a different push notification library which remembers token (stores it somewhere locally) and you didn't update that library with the new token.
Your application (or other library dependencies) implements another FirebaseMessagingService, and they conflict. Only one service can accept (react to) to the action sent by the FirebaseMessaging Android library's when a new token is given to it. You can double check this by opening the AndroidManifest.xml in Android Studio and selecting the Merged Manifest tab at the bottom of the tab. You can also place debuggers in each Service from each library you use. You'll see that only one service's onNewToken gets called.
When they conflict, one doesn't get the correct token, and the FCM registration token that gets registered would be wrong. Sending a message to a wrong registration, gets you InvalidRegistration.
for me, it was a mistake that I was passing an Id from my models instead of the tokens of the users
InvalidRegistration simply means that the token is either invalid or expired. You can uninstall the app and then reinstall and get a new token and then try with that token. This will definitely solve your problem.
You can read more here.

Why is my Service Worker's push event data/payload null?

I have made multiple attempts to get desktop notifications working in Chrome, but I have not found a single source of documentation that covers a step by step procedure to get desktop notifications to work correctly. Each resource I have come across is either outdated or inconsistent with others.
The problem I am facing is: once the Service Worker receives the push event,
self.addEventListener('push', function (event) {
console.log(event);
event.waitUntil(
self.registration.showNotification(
event.data.title,
{
body: event.data.body,
icon: event.data.icon,
tag: event.data.tag
}));
});
event.data is null. I expect it to have data that I am sending as JSON in a POST request like this:
POST https://fcm.googleapis.com/fcm/send HTTP/1.1
Content-Type: application/json
Authorization: key=<FCM Server Key here>
{
"data": {
"title": "Foo",
"body": "Bar"
},
"to": "<recipient ID here>"
}
The weird thing is the registration script gets a "subscription endpoint" that looks like https://android.googleapis.com/gcm/<recipient ID here>, but I cannot get the POST to go through unless I follow other examples on the web that say to put the recipient ID as the to field in the JSON I am sending.
Of all the examples I have come across, there are multiple URLs that POST calls are being made to:
https://fcm.googleapis.com/fcm/send
https://android.googleapis.com/gcm/send
https://gcm-http.googleapis.com/gcm/send
I have tried all three, with each attempt having the recipient at the end of the API address (like https://fcm.googleapis.com/fcm/send/<recipient ID here> and alternatively in the JSON body. My goal is to get Foo and Bar from the data I am sending into the self.registration.showNotification( method of the service worker.
Why is event.data null? Can anyone point me to a complete guide from start to finish that favors FCM over GCM? Any help would be appreciated.
You may want to check the following statement from the documentation,
A downside to the current implementation of the Push API in Chrome is that you can't send any data with a push message. Nope, nothing. The reason for this is that in a future implementation, payload data will have to be encrypted on your server before it's sent to a push messaging endpoint. This way the endpoint, whatever push provider it is, will not be able to easily view the content of the push message. This also protects against other vulnerabilities like poor validation of HTTPS certificates and man-in-the-middle attacks between your server and the push provider. However, this encryption isn't supported yet, so in the meantime you'll need to perform a fetch to get information needed to populate a notification.
Reading further, you may want to try using fetch() to get data from an API, convert the response to an object and use it to populate notification. This same method was also used in this related SO post.
In addition to that, you may want to also check the response of #Indici Indici in the thread wherein he stated that push event does not contain data values; instead it contains different events which contains information(s). Here is the sample code that was provided as a possible workaround to receive notification in Firebase service-worker in "push" event:
self.addEventListener('push', function(event) {
if (event.data) {
const dataText = event.data.text();
notificationTitle = 'Custom Notification';
notificationOptions.body = 'Message: ' + `${dataText}`;
var title = event.data.notification.title;
var message = event.data.notification.message;
var icon = event.data.notification.icon;
var notificationTag = event.data.notification.tag;
}
}
For receive data need:
self.addEventListener('push', function(event) {
var jsonData = JSON.parse(event.data.text());
// jsonData -> here is you data
const options = {
body: 'set you body',
icon: 'img/apple-icon-120x120.png',
badge: 'img/apple-icon-120x120.png'
};
event.waitUntil(self.registration.showNotification(jsonData.data.title, options));
});

How to send push notifications to multiple devices using Firebase Cloud Messaging

I was findind a way to deliver push messages from my expressJS server to my ionic app and I found GCM. With GCM I could deliver the message passing a list of tokens, like this :
sender.send(message, {
registrationTokens: deviceTokens
}, function (err, response) {
if (err) console.error(err);
else console.log('response' + JSON.stringify(response));
});
But as I found that GCM became FCM I was trying to do the same using FCM, but no luck until now. I've heard about sending topics but I couldn't find an example.
Can anyone give an example on how send topic messages using FCM ?
my FCM code: (working with just 1 token)
var FCM = require('fcm-node');
var serverKey = 'xxx';
var fcm = new FCM(serverKey);
var message = {
to: 'device-token',
notification: {
title: event.title,
body: event.information
}
};
fcm.send(message, function (err, response) {
if (err) {
console.log("Something has gone wrong! \n" + err);
} else {
console.log("Successfully sent with response: \n ", JSON.stringify(response));
}
});
I reckon you are using fcm push library for your push notification,
if you want to send same notification to multiple users then use "registration_ids" parameter instead of "to". this tag accepts an array of strings.
ex:
registration_ids:["registrationkey1","registrationkey2"].
note: limit is 100 key at a time.
I think it is documented pretty well by Google. Basically, there are two ways to send notifications to multiple groups:
Topic Messaging : You have the client subscribe to specific topics and then while sending notifications you just modify the request to target a specific topic. All the clients subscribed to that topic would receive the message.
POST request to this end point.
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=SERVER_AUTHORIZATION_KEY
{
"to": "/topics/foo-bar",
"data": {
"message": "This is a Firebase Cloud Messaging Topic Message!"
}
}
How you subscribe to a specific topic depends on the device context. Documentation for Android and IOS are mentioned in the link I provide.
Device Groups : This is basically building on the approach you have provided you have the registration tokens of the devices you want to target. You can form a device group like so:
POST request
https://android.googleapis.com/gcm/notification
Content-Type:application/json
Authorization:key=API_KEY
project_id:SENDER_ID
{
"operation": "create",
"notification_key_name": "appUser-Chris",
"registration_ids": ["4", "8", "15", "16", "23", "42"]
}
The following request returns a notification_key which you can use in the to field to send notifications. Yes, You will have to save this notification_key somewhere and use it simply like:
POST request
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=SERVER_AUTHORIZATION_KEY
{
"to": "aUniqueKey", //This is your notification_key
"data": {
"hello": "This is a Firebase Cloud Messaging Device Group Message!",
}
}
Ofcourse, you can add and remove devices from the group and all the other fine control. Like I mentioned, it is all documented very well and should get you started without a hiccup.

Categories

Resources