Sending images or buttons on facebook messenger via ibm watson configuered via botkit - facebook-messenger

I have made a wotson chat bot, deployed on facebbok messenger the broker is a node app just like in this github example. I'm recieving text responses perfectly but how do I configure the bot to send images or buttons to the fb messenger. I have tried Respond with JSON option in watson dialog.
JSON:
{
"output": {
},
"context":{
"facebook":{
"message":{
"attachment":{
"type":"image",
"payload":{
"url":"https://petersapparel.com/img/shirt.png"
}
}
}
}
}
}
I Think there is some problem with my JSON.

To send buttons define message with template_type generic and buttons with type postback
controller.hears('test', 'message_received', function(bot, message) {
var attachment = {
'type':'template',
'payload':{
'template_type':'generic',
'elements':[
{
'title':'Chocolate Cookie',
'image_url':'http://cookies.com/cookie.png',
'subtitle':'A delicious chocolate cookie',
'buttons':[
{
'type':'postback',
'title':'Eat Cookie',
'payload':'chocolate'
}
]
},
]
}
};
bot.reply(message, {
attachment: attachment,
});
});
To send attachment define attachment message with resource url and call upload method.
controller.hears('test', 'message_received', function(bot, message) {
var attachment = {
"type":"image",
"payload":{
"url":"https://pbs.twimg.com/profile_images/803642201653858305/IAW1DBPw_400x400.png",
"is_reusable": true
}
};
controller.api.attachment_upload.upload(attachment, function (err, attachmentId) {
if(err) {
// Error
} else {
var image = {
"attachment":{
"type":"image",
"payload": {
"attachment_id": attachmentId
}
}
};
bot.reply(message, image);
}
});
}
Check Botkit Messenger documentation.

Related

NextJS API routes how to handle multiple requests with MongoDB

I have an API route. Inside of this route I handle requests coming from my components with MongodDB. My problem is that I am sending a PUT request from one of my components to that route and it is working. But now I want to send another PUT request from another component. How will I achieve this?
if (req.method === "PUT") {
try {
const { _id, id, change } = req.body;
let set = `settings.$[el].${id}`;
const data = await db
.collection("Todos")
.updateOne(
{ _id: _id },
{ $set: { [set]: change } },
{ arrayFilters: [{ "el._id": id }] }
);
res.status(201).json(data);
} catch (err) {
res.status(500).json({ message: "Unable to instert the data." });
}
}
This is for my one request and now I want to send another one but also with another data. If I send it there will conflict so it fails. Some basic solutions I found but they are not sustainable.
One way is to create a new route /api/newRoute.
Another way is when you send the request add to its body a variable that differentiates between the two. For example:
body: {
// your original data
type: "newType" // this variable can be named anything you like
}
In the api route you can use the following code example:
if (req.method === "PUT" && req.body.type == "newType") {
try {
// your new code
} catch (err) {
// your new code
}
}

React Native S3 image upload returns "Stream Closed" using XHR

After updating React Native version to latest 0.63.2 and trying to upload the image to S3 bucket XHR returns error Stream Closed image upload was working fine with version 0.61.5
The Code
uploadProfile({ variables: { filetype: mime } }).then(
({ data: { uploadUserProfile } }) => {
const { presignedUrl, url } = uploadUserProfile;
console.log('presignedUrl', { presignedUrl, url });
// uploading to s3 bucket
const xhr = new XMLHttpRequest();
xhr.open('PUT', presignedUrl);
xhr.onreadystatechange = async function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
updateAccount({
variables: {
data: {
profile: url,
},
},
});
} else {
if (/Request has expired/g.test(xhr.response))
Toast({ message: 'slow network connection' });
else {
console.log({
response: xhr.response,
responseText: xhr.responseText,
status: xhr.status,
});
Toast({ message: 'internal server error' });
await report({
error: {
response: xhr.response,
responseText: xhr.responseText,
status: xhr.status,
},
}); // reporting error
}
}
}
};
xhr.setRequestHeader('Content-Type', mime);
xhr.send({ uri: path, type: mime });
setLoading(false);
},
);
When the user wants to upload a profile image first App send a request to the server and get return the pre-signed URL and upload from client-side this how App was working.
I upgraded Flipper to version 0.51.2 and it worked for me.
Go to android/gradle.properties and add this line
FLIPPER_VERSION=0.52.1
You should have the following lines in your android/app/build.gradle
dependencies {
// ....
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
}
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
// ...
}
upgrading flipper version solves the issue for me, If upgrading flipper version doesn't solve for you then try this solution.
Whoever is still struggling with this issue. it's happening because of Flipper network plugin.
I disabled it and things work just fine.
My workaround to make this work is commenting outline number 43
38 NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
39 NetworkingModule.setCustomClientBuilder(
40 new NetworkingModule.CustomClientBuilder() {
41 #Override
42 public void apply(OkHttpClient.Builder builder) {
43 // builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
44 }
45 });
46 client.addPlugin(networkFlipperPlugin);
in this file android/app/src/debug/java/com/maxyride/app/drivers/ReactNativeFlipper.java
found this answer link

Office UI Outlook addin using auth is unstable

We're currently developing a Office UI addin using React. The addin should make a connection with a backend api and authenticate the user using bearer tokens. The backend api is protected by Azure AD.
We based our solution on the example that is offered by Microsoft: https://github.com/OfficeDev/PnP-OfficeAddins/tree/master/Samples/auth/Office-Add-in-Microsoft-Graph-React This uses msal.js for the authentication.
The login dialog is opened like so:
await Office.context.ui.displayDialogAsync(dialogLoginUrl, { height: 40, width: 30 }, result => {
if (result.status === Office.AsyncResultStatus.Failed) {
displayError(`${result.error.code} ${result.error.message}`);
} else {
loginDialog = result.value;
loginDialog.addEventHandler(Office.EventType.DialogMessageReceived, processLoginMessage);
loginDialog.addEventHandler(Office.EventType.DialogEventReceived, processLoginDialogEvent);
}
});
And the following code runs within the dialog:
import { UserAgentApplication } from "msal";
(() => {
// The initialize function must be run each time a new page is loaded
Office.initialize = () => {
const config = {
auth: {
clientId: "",
authority: "",
redirectUri: "https://localhost:3000/login.html",
navigateToLoginRequestUrl: false
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: false
}
};
const userAgentApp = new UserAgentApplication(config);
const authCallback = (error, response) => {
if (!error) {
if (response.tokenType === "id_token") {
localStorage.setItem("loggedIn", "yes");
} else {
// The tokenType is access_token, so send success message and token.
Office.context.ui.messageParent(JSON.stringify({ status: "success", result: response.accessToken }));
}
} else {
const errorData = `errorCode: ${error.errorCode}
message: ${error.errorMessage}
errorStack: ${error.stack}`;
Office.context.ui.messageParent(JSON.stringify({ status: "failure", result: errorData }));
}
};
userAgentApp.handleRedirectCallback(authCallback);
const request = {
scopes: ["api://..."]
};
if (localStorage.getItem("loggedIn") === "yes") {
userAgentApp.acquireTokenRedirect(request);
} else {
// This will login the user and then the (response.tokenType === "id_token")
// path in authCallback below will run, which sets localStorage.loggedIn to "yes"
// and then the dialog is redirected back to this script, so the
// acquireTokenRedirect above runs.
userAgentApp.loginRedirect(request);
}
};
})();
Unfortunately this doesn't seem lead to a stable addin. The authentication dialog sometimes works as expected, but sometimes it doesn't. In Outlook on macOS it seems to work fine, but in Outlook on Windows the handling of the callback is not always working correctly. Also in the web version of Outlook it doesn't work as expected.
The question is whether someone has a working solution using React and msal.js in a Outlook addin.

Can't get notification payload from firebase-sw on Ionic PWA

I've searched a lot for this problem that I'm stuck on for a week.
I have an Ionic PWA project that receive some notifications from firebase, I can receive the notifications with no problem and can get the payload on foreground (app is open), but I cant get the payload when the app is closed and I don't figure out what is goning on, so I came here to ask the masters to help me.
messaging.setBackgroundMessageHandler(function(payload) {
var notificationTitle = 'Teste';
var notificationOptions = {
body: 'Background Message body.',
tag: 'campanhas',
data: payload.data,
icon: 'https://firebasestorage.googleapis.com/v0/b/hemotomobile-edeb9.appspot.com/o/logo.png?alt=media&token=4a9fc487-b8cf-4d3c-875c-774454ff6f50'
};
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
self.addEventListener('notificationclick', function(event) {
event.notification.close();
event.waitUntil(clients.matchAll({
type: "window"
}).then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow)
return clients.openWindow('/');
}));
});
and on my provider for the notifications, I use this code:
public receiveMessage() {
console.log('notification')
this.messaging.onMessage((payload) => {
console.log('payload',payload)
});
}
I call this provider on my tabs-page:
ionViewDidLoad(){
this.notification.receiveMessage()
}
So, can anyone help me to get the payload when the PWA is closed?
have you tried by initializing firebase in the service worker and using it ,
self.addEventListener("notificationclick", (event) => {
//your code
});
importScripts("https://www.gstatic.com/firebasejs/4.7.0/firebase.js")
importScripts("https://www.gstatic.com/firebasejs/4.7.0/firebase-messaging.js")
// Initialize Firebase
firebase.initializeApp({
'messagingSenderId': 'your sender id'
});
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
//your code
});
this.messaging.onMessage((payload) => {
//your code
});
self.addEventListener('notificationclose', function (event) {
self.registration.getNotifications().then(function (notifications) {
notifications.forEach(function (notification) {
notification.close()
})
});
})
I have tried by using above code in the service worker and it is showing notification when the application is closed , if you want to show the notification when the browser is closed make sure you have enabled the Continue running background apps when Google Chrome is closed option in chrome settings.

Passing in an array of values to an express POST route

I have a mongoose model called Todo that looks like this:
content: [{
contentType: {
type: String,
default: null
},
contentValue: {
type: String,
default: null
}
}]
My express POST route looks like this:
app.post('/todos', authenticate, (req, res) => {
var todo = new Todo({
content: req.body.content
});
res.send(todo)
//I am sending instead of sending the result for testing
});
When I send int test data using Postman the content array is coming back empty "content": []
I have tried several formats of Body in postman including:
{
"content[contentType]": "reminder",
"content[contentValue]": "Will it blend"
}
and
{
"content": {
"contentType": "reminder",
"contentValue": "Will it blend"
}
}
However both come back with empty array.
{
"content": []
}
Do I need to change something on my POST route and\or send in teh data in an alternate format?
content here is a todo sub document, so you should treat it like the following:
app.post('/todos', authenticate, (req, res) => {
var content = req.body.content;
var todo = new Todo();
todo.content.push(content);
todo.save(function(err) {
if (err) throw err;
res.json(todo.toJSON())
//I am sending instead of sending the result for testing
});
});
See: Mongoose SubDocuments

Resources