DirectLine API: Define a new ChannelId - node.js

I'm implementing a new channel for my bot's front end using the botframework-directlinejs NodeJS SDK. This channel will provide some custom back-channel functionality; however, my bot needs to know that the conversation it is communicating with is via this channel before it can construct an activity to use it.
From what I can gather from the 'Activity' object in the API, the channelId field should be set by the channel.
However,
myChannel.postActivity({
type: 'message',
text: 'hi',
from: {
id: "Node test user",
},
channelId: 'myChannel'
}).subscribe(
id => console.log("Posted activity, assigned ID ", id),
error => console.log("Error posting activity", error)
);
indeed sends the message 'hi' to my bot, but the channelId comes out as 'directline'.
Performing this same operation in Fiddler as a post to https://directline.botframework.com/v3/directline/conversations/<conversationID>/activities has the same response.
My suspicion is that the 'channelId' property of the Activity object is read-only, and that the API adds this value.
Is it possible to set a custom id of the channel?

No, it is not possible to set a custom channel id. There is a corresponding connector service for each channel type. If you're using Direct Line, the channelId should be directline.
You can send custom information through channel data though:
BotChat.App({
botConnection: Object.assign({}, dl, {
postActivity: activity => {
var newActivity = Object.assign({}, activity, { channelData: { "MyKey": "MyValue" } });
return dl.postActivity(newActivity);
}
}),
bot: bot,
user: user,
resize: 'detect',
}, document.getElementById('bot'));

Related

TEAMS bot in node.js: 'Authorization has been denied for this request' in CreateConversation method

I have a TEAMS node.js bot running locally (with ngrok). I receive messages from TEAMS client and echo works
context.sendActivity(`You said '${context.activity.text}'`);
Now I want to send a 1to1 message to this user, but I receive
Error: Authorization has been denied for this request
when creating a conversation.
My code:
var sUserId = "29:1shb_5I6CkkerBVq4qPqcv5dGwDfkXx11Jbjc1UnGCIv"
var sServiceUrl = "https://smba.trafficmanager.net/emea/";
var sTenantId = "942369d2-208e-438b-894c-0d0e1510cf61";
var credentials = new BotConnector.MicrosoftAppCredentials({
appId: "xxxxxxx",
appPassword: "yyyyyyyy"
});
var connectorClient = new BotConnector.ConnectorClient(credentials, { baseUri: sServiceUrl });
const parameters = {
members: [ { id: sUserId } ],
isGroup: false,
channelData:
{
tenant: {
id: sTenantId
}
}
};
var conversationResource = await connectorClient.conversations.createConversation(parameters);
// I get the error here, next is not executed
await connectorClient.conversations.sendToConversation(conversationResource.id, {
type: "message",
from: { id: "xxxxxxx" },
recipient: { id: sUserId },
text: 'This a message from Bot Connector Client (NodeJS)'
});
appId & appPassword are valid (from .env file), if they are wrong I can not receive messages from TEAMS client
I have the same code to create a conversation in a .NET bot and it works for me:
var parameters = new ConversationParameters
{
Members = new[] { new ChannelAccount(sUserId) },
ChannelData = new TeamsChannelData
{
Tenant = new TenantInfo(sTenantId),
},
};
retValue = await connectorClient.Conversations.CreateConversationAsync(parameters);
What is wrong in my node.js code?
Thanks,
Diego
Have you trusted the service? It don't think so based on your code, and it's a classic cause of 401 in your case.
In node.js, do the following:
MicrosoftAppCredentials.trustServiceUrl(serviceUrl);
If you want more details around that, have a look to the documentation about getting 401 when sending proactive messages here
And also this SO answer about Teams and Proactive messaging, in particular last block.
Proactive messaging bot in Teams without mentioning the bot beforehand

Botframework v4 Directline integration: Is there a way to get the conversation id generated from directline transfer to the Chatbot (nodejs code)

This might be very simple, but I cannot find any reference regarding this.
I integrated the chat bot in the web app using direct line API; I’m using this API to generate conversation id:
POST: https://directline.botframework.com/v3/directline/conversations
I’m trying to get the generated conversation id from the above API (from web app code) to the chatbot code (NodeJS). Is there a way or any reference to do this?
one way as per this issue comment is to send data to bot before starting the conversation using:
var params = BotChat.queryParams(location.search);
var my_token = params['my_token'];
var botConnection = new BotChat.DirectLine({
secret: 'DIRECTLINE_SECRET'
});
BotChat.App({
botConnection: botConnection
,user: { id: 'USER_ID', name: 'User' } // user.id auto updates after first user message
}, document.getElementById("bot"));
botConnection.connectionStatus$.subscribe(function (status) {
if (status == 2) { // wait for connection is 'OnLine' to send data to bot
var convID = botConnection.conversationId;
botConnection.postActivity({
from: { id: convID } // because first time user ID == conversation ID
,type: 'event'
,name: 'registerUserData' // event name as we need
,value: my_token // data attached to event
}).subscribe(function (activityId) {
// This subscription is a MUST
// If I remove this handler the postActivity not reaches the bot
});
}
});
Here you subscribe to the botConnection.connectionStatus$ and when the status is equal to 2, you get the conversation ID from the botConnection object.
Then, you can add this middleware code in the bot code to get the data:
bot.use({ receive: function(event, next) {
if (!!event && !!event.address && event.name == 'registerUserData') {
var message = new builder.Message().address(event.address).text('my_token:' + event.value);
bot.send(message, function (err) {}); // simulate proactive message to user
}
next();
} });
Hope this helps.
I resolve it using Botframework Web Chat back channel, here's the link for reference:
https://github.com/Microsoft/BotFramework-WebChat
After I generated the conversation id using directline API:
POST: https://directline.botframework.com/v3/directline/conversations
I send data from the web app to the chatbot via backchannel.
<div id="webchat"></div>
<script>
(async function () {
// We are using a customized store to add hooks to connect event
const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
// When we receive DIRECT_LINE/CONNECT_FULFILLED action, we will send an event activity using WEB_CHAT/SEND_EVENT
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'webchat/join',
value: { conversation_id: conversationID }
}
});
}
return next(action);
});
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token }),
store
}, document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
//Note: conversationID and token is generated in the backend code of the web app.
</script>

Initiate twilio flex chat using node.js

I am having difficulty getting twilio flex to show messages created using the API using node.js.
I am creating a channel, adding a member, creating a message on the channel using the member.
The flex dashboard shows the incoming chat request in the task list, I can answer the chat request but none of the messages I save to the channel are show.
The interesting thing is if I use the twilio-flex-webchat.min.js script and initiate a chat from a web page and then get the ChannelSid for that conversation (using https://chat.twilio.com/v2/Services/ISXXXX/Channels) I can use the APIs to create messages for this channel and they appear on the flex dashboard. But I need all this to work via node.js.
I compared the task, channel, reservation, member and message twilio objects both for chat conversations using the twilio-flex-webchat.min.js web library and the objects created by the node.js code. I cannot find any notable difference.
Does anybody have any insights?
Here is my code.
const accountSid = 'ACXXXXXXXXXX';
const authToken = 'XXXXXXXXXXXXXXXX';
const workspaceSid = 'WSXXXXXXXXXXXXXXXx';
const workFlowSid = 'WWXXXXXXXXXXXXXXXXXXXXXX';
const serviceSid = 'ISXXXXXXXXXXXXXXXXXXXXXX';
const client = require('twilio')(accountSid, authToken);
(async () => {
//create channel
let channel = await client.chat.services(serviceSid)
.channels
.create({
attributes: JSON.stringify({
status: "ACTIVE",
from: "Some Person",
channel_type: "web"
}),
workflowSid: workFlowSid,
taskChannel: 'chat',
friendlyName: 'Flex WebChat',
type: 'private'
});
//create a member in this channel
let member = await client.chat.services(serviceSid)
.channels(channel.sid)
.members
.create({ identity: 'WEB_CLIENT' });
//post a message to this channel from the member
let message = await client.chat.services(serviceSid)
.channels(channel.sid)
.messages.create({ body: 'This is a test message', to: channel.sid, from: 'WEB_CLIENT' });
//create a task for my programable chat channel and associate the channel sid for my current conversation
let task = await client.taskrouter.workspaces(workspaceSid)
.tasks
.create({
attributes: JSON.stringify({
channelSid: channel.sid,
channelType: "web"
}),
workflowSid: workFlowSid,
taskChannel: 'chat',
});
})();
Thanks
Before adding a message and creating a Task, you need to create a proxy session, add the members as participants and then update the channel attributes:
{
"status": "ACTIVE",
"forwarding": true,
"twilioNumber": firstParticipant.proxyIdentifier,
"serviceNumber": someIdentity,
"from": from,
"channel_type": "sms",
"proxySession": session.sid
}

How to get `fcm_options.link` functioning in firebase web notifications

I'm trying to get my FCM web notifications to contain a clickable link to my site, using the firebase admin SDK (version 7.0.0) for node.js. As far as I can tell I'm following the documentation to a T, but I'm unable to get the link working. To clarify, my notifications are working fine otherwise, it's just the link that I haven't got to work.
The documentation states:
For notification messages sent from the app server, the FCM JavaScript API supports the fcm_options.link key. Typically this is set to a page in your web app
I've included webpush.fcm_options.link inside my notification message. I've made sure to include an explicit notification payload in my message, as the documentation states that data messages don't support fcm_options.link.
Here's the structure of my message currently:
{
notification: {
title: 'Title',
body: 'Body',
},
data: {
// my data here
},
webpush: {
notification: {
requireInteraction: true,
icon: '/icons/notification.png'
},
fcm_options: {
link: 'https://example.com/'
}
},
// android: {},
// apns: {},
topic: 'sometopic'
};
Here's the function I'm using to send the message:
const admin = require('firebase-admin')
const sendMessage = message => {
admin
.messaging()
.send(message)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
});
};
The link property should be working according to the documentation: my url includes https and my notification is being sent from the app server, and includes an explicit notification payload. At the moment, clicking on the notification just makes it disappear, with nothing else happening.
UPDATE: I worked out what the issue was - my service worker was using the importScripts function, but I was using an out-of-date version of the firebase script that didn't support fcm_options.link. I changed it to my current version of firebase (5.8.5) and it works. All sorted!
in notification try This
"notification":{
"title":"IssA",
"body":"Lafi",
"icon": "Icon URL",
"click_action": "Your URL here"
}
In the last version, using firebase admin in node js, this is the right configuration:
var message = {
notification: {
title: "",
body: ""
},
webpush: {
fcmOptions: {
link: "https://yourlink.web.app"
}
}
};

subscription error in subscribing to a pusher presence channel

I'm trying to go through a basic presence channel example with pusher.js and I'm getting a pusher subscription_error , invalid auth response for channel, expected channel_data field
var presenceChannel = pusher.subscribe('presence-' + room);
presenceChannel.bind_all(function(err) {
console.log("err: " + err);
});
presenceChannel.bind('pusher:subscription_succeeded', function(members) {
members.each(function(member) {
console.log(member);
});
});
Is there some sort of initialization that I need to do to create a presence channel beforehand? Or can I just connect to one and it will create a presence channel. Does subscribing to a presence channel add my presence info to it as a member?
So it looks like authorization on presence endpoints need to be implemented and have a userinfo parameter passed in which I wasn't doing server side.
var presenceData = {
user_id: request.auth.credentials.id,
user_info: {
uname: request.auth.credentials.uname
}
};
var auth = pusher.authenticate(socketId, channel, presenceData);

Resources