Bot framework Directline -Change Bot name Run time - c#

Is it possible to change the name of the bot during runtime. Current the name which i have added in portal is getting displayed under bot message. Is it possible to update it in run time rather than displaying the name configured in portal.

You can intercept all messages that are exchanged between user and bot, and you can check the value of activity.From.Name to detect if the message sent from your bot, and then you can specify a new value for activity.From.Name property, which would help achieve your requirement to show updated display name in webchat.
public async Task LogAsync(IActivity activity)
{
if (activity.From.Name== "fehanbasicbot")
{
activity.From.Name = "testbot";
}
}
Test result:
My bot settings:
In webchat:

Related

Change History Time Azure Communication Services

I'm trying to create a simple chat app using Azure Communication Services SDK for .NET.
I managed to add participants to a thread following
this example.
I read the documentation for class ChatParticipant and I found out that it can show the time from which the chat history is shared with the participant. The default date is 1/1/1970 00:00.
I would like to make this date variable, so that a user can only see messages from the moment he joined the chat on.
Is there a way to do it?
Thank you in advance
Can you try to set the property for ShareHistoryTime at the time of adding a participant to the Chat thread?. e.g in the below example, it is set to current time.
// ThreadId : Chat ThreadId , participantUserId : participant communication user Identifier
ChatThreadClient chatThreadClient =
chatClient.GetChatThreadClient(ThreadId);
chatThreadClient.AddParticipant(new ChatParticipant(
new CommunicationUserIdentifier(participantUserId))
{
DisplayName = displayName,
ShareHistoryTime = DateTimeOffset.Now
});
You can refer Chat Participant Properties here

conversation reference (concurrent dictionary become blank) after IIS pool recycle

We have a bot design in Bot framework-4 using .Net c# sdk. This bot is hosted on IIS and available
on different channel such as Directline, MS Teams etc. We want to send proactive messages to all the user in MS teams to notify them irrespective of if they communicated with bot or not. The Proactive messages will be 1:1 message.
After doing lot of R&D we found that we will be only able to send Proactive message to user only when there conversation reference is present. (let me know if other way is also possible.)
Using below link and Sample to send Proactive message to user:
Proactive Message Sample
Document Referred
We are using cosmos DB container and auto save middleware for bot conversation state and user state management.
Code in ConfigureServices method of Startup.cs file:
var blobDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Blob service in your .bot file.");
var BlobDb = blobDbService as BlobStorageService;
var dataStore = new AzureBlobStorage(BlobDb.ConnectionString, BlobDb.Container);
var userState = new UserState(dataStore);
var conversationState = new ConversationState(dataStore);
services.AddSingleton(dataStore);
services.AddSingleton(userState);
services.AddSingleton(conversationState);
services.AddSingleton<ConcurrentDictionary<string, ConversationReference>>();
services.AddSingleton(new BotStateSet(userState, conversationState));
services.AddBot<EnterpriseTiBOT>(options =>
{
// Autosave State Middleware (saves bot state after each turn)
options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState));
}
Code to Store Conversation Reference for each user:
private void AddConversationReference(Activity activity)
{
var conversationReference = activity.GetConversationReference();
_conversationReferences.AddOrUpdate(conversationReference.User.Id, conversationReference, (key, newValue) => conversationReference);
}
protected override async Task OnStartAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
{
AddConversationReference(dc.Context, cancellationToken);
}
Code in notifyContoller is same as the code from GitHub Sample. There are 2 issues we are facing :
The concurrent dictionary having conversation reference become blank when the IIS pool is recycled and we are not able to send the proactive message to the user, how to store it in Blob storage and access the same in Notify controller?
We want to send proactive message to all the user whether they have communicated with bot or not, any way to achieve this? Tried 3rd approach from this article. But the challenge is, we are not able to send message to user based on User ID or user principle name.
There are multiple ways to store the conversation and user info. You should store these details in more persistent place rather than in memory. Here is a sample app code which stores user detail and along with the conversation Id in cosmos DB at the time of installation of the app. You could look into the implementation part. It can be any storage (blob, SQL).
For sending proactive message, User must have access to your app. You could make your app install for everyone in the tenant from Teams admin portal. Here is a reference documentation for managing the app from admin portal.
You need to have the conversation ID (between a bot and user) for sending a proactive message. And the conversation Id is created when the bot is installed for an user Or in team/group where user is part of.
I want to add comment to the answer but I do not have enough reputation to do so. Just to eleborate point 1 , if you want to ask where can we get and save the conversation refences, you can get it via method named: OnConversationUpdateActivityAsync.
It took me some time to get to this, so I think it is useful to share.
You can get a lot of information eg user ID, channel ID from the activity, here is some sample code:
public class ProactiveBot : ActivityHandler
{
...
...
protected override Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
var conversationReferences = turnContext.Activity.GetConversationReference();
//this is your user's ID
string userId = conversationReference.User.Id;
//this is the bot's ID and will be the same for all activities under same bot.
string botId = conversationReference.Bot.Id;
...
...
...
}
}

How to add state management in Web Chat BOT created with water fall dialog's using C# MS BOT framework SDK V4?

I have Chat Bot created using C# SDK V4 and it has multiple water fall dialog classes each for performing specific action when a certain option is selected. The BOT has authentication also embedded using Oauth Prompt.
Channel: Web Channel
SDK: SDKV4
Language: C#
Now, I want to have the state management handled or kept in the water fall dialog as the example i see is on top of normal echo bot and if i implement the same lines on my existing bot having water fall dialog it is not working.
Coming to reason why i want state management as After authenticating the user using Oauth Prompt i am displaying the options based upon the logged in User
Now 2 or more users log in simultaneously or one after the other the other login is getting taken and data of second logged in user is getting displayed for the first user when he toggles back and forth with in the options displayed for selection.
When i logged a query on how to maintain the logged in user or refresh the logged in user i was suggested to have state management technique hence this query on how to do it in a water all dialog.
If state management is not the correct option then can you please let me know how to refresh or maintain the logged in user id?
This suspect the issue is tied to the props you are passing to Direct Line when you start up Web Chat. Referenced under Integrate with Javascript, the docs state:
Assigning userID as a static value is not recommended since this will cause all users to share state. Please see the API userID entry for more information.
When you make a call to generate a token, the userID (which should be unique to the user) should be passed along at that point, else you will run into issues of shared state.
Here is a bit of the code I run for accessing a local API that gets and returns a direct line token. As you can see, the userID is passed in the request which is then baked into the token when returned.
// Listen for incoming requests.
server.post('/directline/token', (req, res) => {
// userId must start with `dl_`
const userId = (req.body && req.body.id) ? req.body.id : `dl_${ Date.now() + Math.random().toString(36) }`;
const options = {
method: 'POST',
uri: 'https://directline.botframework.com/v3/directline/tokens/generate',
headers: {
Authorization: `Bearer ${ process.env.directLineSecret }`,
'Access-Control-Allow-Origin': '*'
},
json: {
user: {
ID: userId
}
}
};
request.post(options, (error, response, body) => {
if (!error && response.statusCode < 300) {
res.send(body);
console.log('Someone requested a token...');
} else if (response.statusCode >= 400 && response.statusCode < 500) {
res.send(response.statusCode);
} else if (response.statusCode >= 500) {
res.status(response.statusCode);
res.send('Call to retrieve token from DirectLine failed');
}
});
});
Hope of help!

MS Bot framework emulator chang user id

Is there a way to change the default user id (which is 'default-user') in bot emulator?
Or maybe it supports something about multi conversations in the same time?
I want to emulate two different users at the same time (because I have multiple user types in my project.
When I try to create new conversation like this
....
var connector = new ConnectorClient(new Uri(context.Activity.ServiceUrl));
var userAccount = new ChannelAccount("//here we need to provide user id which is always default-user", "Provider");
var botAccount = context.Activity.Recipient;
var conversation = await connector.Conversations.CreateDirectConversationAsync(botAccount, userAccount);
var message = context.MakeMessage();
message.Recipient = userAccount;
message.From = botAccount;
message.Conversation = new ConversationAccount(false, conversation.Id);
await connector.Conversations.SendToConversationAsync((Activity) message);
My emulator opens new conversation in the same chat-window
Bot Framework Channel Emulator had the functions you need in the previous versions. In the latest one AFAIK changing user id and group conversation simulation are not available out of the box. However the good thing is that what this tool is doing - it is just sending http requests to your WebApi endpoint. It means that you can catch those requests using Fiddler or any other similar tool and then edit and reissue the request. It is a workaround, but for testing pusposes I think it is okay to use such an approach.
Below is the Fiddler screen and screen of debug session to show it is working:
If you want to go further and automate it - there is a REST Api documentation on botframework site, so you can build your own client.
I work on the Bot Framework Emulator. We've recently added the ability to override generated user ids to be used in conversations without the need of a tool like Fiddler. You can utilize this feature in our latest release. I hope you find this useful for your scenario.
I don't know a way of having multiple conversations with different users, but you cant change the id/name of the user that is currently sending messages.
You can do this by editing the config file that the emulator uses to store its settings.
On linux I found this settings file here:
~/.config/botframework-emulator/botframework-emulator/server.json
You'll find a section "users" in that json file.
Change that section to:
"users": {
"currentUserId": "default-user2",
"usersById": {
"default-user": {
"id": "default-user",
"name": "User"
},
"default-user2": {
"id": "default-user2",
"name": "User2"
}
}
You'll need to restart the emulator and then your conversation should be with User2 now instead of User.
When you want to change it back you just need to change:
"currentUserId": "default-user2",
back to
"currentUserId": "default-user",
On windows follow these steps:
go to directory
%APPDATA%\botframework-emulator\botframework-emulator
locate server.json file
In the sections of users replace default-user
with id you need (in my case romel)
"users": {
"currentUserId": "default-user",
"usersById": {
"default-user": {
"id": "romel",
"name": "User"
}
}
}
restart bot emulator

How to bind and update a list view Item to a RequestBin http page

I'm developing a graphic user interface where the user can send a message to mutuple user using Twilio API in c#
I'm trying to bind a list view to the status of each number being sent and I also want to know the status of the message every time the user click on refresh list view
public void sendSMS(string ssid, string token , string fromNumber, List<string>TOnumbersList ,string msgBody )
{
TwilioClient.Init(ssid, token);
foreach (var toNumber in TOnumbersList)
{
var message = MessageResource.Create(
to: new PhoneNumber(toNumber),
from: new PhoneNumber(fromNumber),
body: msgBody,
provideFeedback: true,
statusCallback: new Uri("http://requestb.in/1jnk4451"));
ListViewItem items = new ListViewItem(message.To);//This show the number being sent to ( delivered number)
items.SubItems.Add(message.Status.ToString()); //Refresh the status WHERE number = message.To
items.SubItems.Add(message.ErrorCode.ToString());//Show error code in case
items.SubItems.Add(message.ErrorMessage); // In case error message show them
listView1.Items.AddRange(new ListViewItem[] { items });
}
}
Twilio API is doing the perfect job updating the status so everytime I go click the link I can see the status. as explained in this documentation Track Delivery Status of Messages in C#
But is It possible to bind a list view so it can be updated everytime the user click on refresh list view ?
Or what is the best way to dynamically show the message status from the URI http://requestb.in/1jnk4451? Maybe embedding a webpage would be better ?
Thank you
Twilio developer evangelist here.
Rather than using the RequestBin URL, if you provide a URL to your own application then you can write an endpoint that receives the status updates of the messages. That way you can store the status yourself and update the list view without having to loop through all the messages.
[Edit] In more detail:
When you send an SMS message with Twilio using the REST API you can set a statusCallback URL to receive updates about the message as it processes through from Twilio to the network and the device.
Twilio will make HTTP requests to this URL as the message goes through each state, the possible states being queued, failed, sent, delivered, or undelivered. Twilio sends a number of parameters as part of this request, some are general ones about the message and some are about the actual status.
To receive these requests you need to set up a web server. I'm not a C# developer I'm afraid, however we have a guide on how to set up a C# and ASP.NET MVC environment that can receive webhooks that should be able to help you there.
Let me know if this helps a bit more!

Categories

Resources