Hello,
Last week (2017/03/03) I created a NodeJS bot in Azure using "Basic" template and configure DirectLine channel.
I added this code in bot:
bot.on('lookupUser', function (address) {
if (address) {
var message = new builder.Message().address(address).text(JSON.stringify(address));
bot.send(message, function (err) {});
}
});
...to get a first message from bot including the deserialized address object with user and conversation ids.
The client code to embed WebChat control in index.html is:
```
BotChat.App({
directLine: { secret: 'DIRECTLINE_SECRET_FROM_BOT_FRAMEWORK' },
user: { id: 'TOKEN_ID', name: 'User' }
}, document.getElementById("bot"));
````
Then, I got 'TOKEN_ID' in the bot message. That code works until 2017/03/03!
So, today (2017/03/06) I am receiving as user id the same value as conversation id.
I tried creating a new bot and new secrets, but no way to get user id from BotChat.App again.
驴Something wrong in my code? 驴Something changed in DirecLine?
Thank you.
UPDATED with more results
I added this exact code to my bot.
Before the client sends any messages, this code fires and shows the user.id as the conversationID. So far as I know this is correct behavior, because the only time the user.id is sent to the system is along with a message from the client.
After the user sends a message, this code fires two more times. The first time it shows the same result. The second time it shows user.id as the supplied user.id.
@dandriscoll did anything change with how lookupUser is fired?
OK, you are right. I have to check the second lookupUser message after the user write something.
There is a way to send parameters (like USER ID) to the bot before the user sends the first message?
or There is a way to send hidden messages from client to the bot through directline?
We need a USER ID to define the bot behavior.
Thanks in advance.
Hi @inmarktech, I believe the calls to lookupUser are coming from ConversationUpdate activities we send to your bot to know it has joined the conversation.
We made a recent change to expand the situations where we send a ConversationUpdate activity. Previously we only set it when the conversation was started. Now we send them when the bot is added to the conversation and when each user posts a message to the conversation for the first time.
One of these activities (typically the first, but not always) contains the bot's ID in the membersAdded array, and the from field is populated with a placeholder value.
When the user joins, we send another activity with the user's ID in the membersAdded array.
Thanks @billba and @dandriscoll for your feedback.
I resolved what I need (send data to bot before start the conversation) using this code in client:
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
});
}
});
Then, in bot code I added this middleware code to get 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();
} });
That's exactly what I was going to suggest. Nice work.
By the way, you shouldn't have to wait for the connectionStatus to change to Online. postActivity does this internally. (Please let me know if it doesn't). Also you don't need to send from: { id: conversationId }, you can send the actual user id you want. UPDATE: I just tried this and indeed postActivity waits for connectionStatus to change to Online and then posts.
I send the activity correctly, but in the bot code, the event.name appears to me as undefined. What am I doing wrong?
bot.use({ receive: function(event, next) {
var message3 = new builder.Message().address(event.address).text('Hi!'+event.name);
bot.send(message3, function (err) {}); // simulate proactive message to user
} });
hello .. @billba can you convert this code into c# so i can also use this code.
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();
} });
@UsamaAslam sorry I only speak JavaScript :-(
Most helpful comment
By the way, you shouldn't have to wait for the
connectionStatusto change toOnline.postActivitydoes this internally. (Please let me know if it doesn't). Also you don't need to sendfrom: { id: conversationId }, you can send the actual user id you want. UPDATE: I just tried this and indeedpostActivitywaits forconnectionStatusto change toOnlineand then posts.