MS Bot framework emulator chang user id - c#

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

Related

Why an installed app is not listed by Ms Graph API?

I am trying to upgrade an app which belongs to a chat. If the app is not installed, below code successfully install it:
await graph.Chats["19:7f...3#thread.v2"].InstalledApps
.Request()
.AddAsync(teamsAppInstallation);
But once the app is added, below code shows zero entries:
var installedApps = await graph.Chats["19:7f...3#thread.v2"].InstalledApps.Request().GetAsync();
I was expecting to see my app there. My target is to call Upgrade() for the app, because it should allow me to add ConversationReferences in one of the event functions (e.g. OnTurnAsync), that will allow me to send proactive message to the chat. Am I doing something wrong?
Permissions for an application are set:
TeamsAppInstallation.ReadWriteSelfForChat.All
TeamsAppInstallation.ReadWriteForUser.All
The authentication with the Graph API is done successfully, as I can create a chat, list channels etc.
https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token
data:
grant_type=client_credentials&client_id={ MS_APP_ID_ENC }&client_secret={ MS_APP_PASS_ENC }&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
I was adding the app to the chat both manually and with C# request:
var teamsAppInstallation = new TeamsAppInstallation {
AdditionalData = new Dictionary<string, object>()
{
{
"teamsApp#odata.bind", "https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/0c...68/"}
}
};
var installedApp = await graph.Chats["19:7f...3#thread.v2"].InstalledApps. Request().AddAsync(teamsAppInstallation);
And the app was added. It can be used in the chat.
It turned out that I've used wrong application permissions. Even though TeamsAppInstallation.ReadWriteSelfForChat.Al is listed in the docs, I needed to add TeamsAppInstallation.ReadWriteForChat.All to make it working.

Testing Slack Interactive Messages Locally

I'm currently using SlackConnector Repo https://github.com/noobot/SlackConnector. I've created a bot and it sends interactive messages to my chat. I would like to add functionality to my interactive buttons but upon clicking them i get this response. Darn – that didn’t work. Only Slack Apps can add interactive elements to messages. Manage your apps here: https://api.slack.com/apps/ So it looks like I need a request URL to get my past my current roadblock. Is there a way to Test the Interactive Message button locally?
List<SlackAttachment> attachments = new List<SlackAttachment>();
List<SlackAttachmentAction> actions = new List<SlackAttachmentAction>();
actions.Add(new SlackAttachmentAction
{
Name = "game",
Text = "chess",
Type = "button",
Value = "Chess"
});
actions.Add(new SlackAttachmentAction
{
Name = "game",
Text = "Falken's Maze",
Type = "button",
Value = "Maze"
});
actions.Add( new SlackAttachmentAction
{
Name = "game",
Text = "Thermonuclear War",
Type = "danger",
Value = "war"
});
attachments.Add(new SlackAttachment
{
Text = "Choose a game to play",
Fallback = "You are unable to choose a game",
CallbackId = "wopr_game",
ColorHex = "#3AA3E3",
Actions = actions
});
connection.Say(new BotMessage
{
ChatHub = chatHub,
Text = "Usage: !talk <user>",
Attachments = attachments
});
return Task.CompletedTask;
One thing I tried was I set the request URL to use a url generated from https://webhook.site/#/ and I still get the same response upon clicking
It looks to me like you have two problems.
You don't have a Slack app
Interactive Messages only work if you have a registered Slack app. That is why you got that error message. But you can easily create one. Just go here and click on "Create a new app". One reason you need one is that you need to tell Slack to which URL to send the request, after a user clicks a button.
Slack can't reach your local app
Slack's interactive messages will only work with apps that can be reached from the public Internet. So if you want to develop your app locally you need to open your web server to the Internet. There are many ways to do it, one secure way is to use a VPN tunnel service. One provider for this kind of service is ngrok, which is also recommended in the official Slack tutorials. I use it myself and it works great.

Microsoft Bot Framework DirectLine Can't Access Conversations

I am trying to use the Microsoft Bot Framework DirectLine API to read and add messages to existing conversations between other users and my bot. From what I've read I believe this should be possible when using the master-secret but it's just not working for me. I'm using a WebAPI to try and access two of my existing conversations (on Facebook & Skype) as follows:
[HttpPost]
[Route("remind")]
public string Remind()
{
var secret = System.Configuration.ConfigurationManager.AppSettings["secret"];
var uri = new Uri("https://directline.botframework.com/");
var creds = new DirectLineClientCredentials(secret);
DirectLineClient client = new DirectLineClient(uri, creds);
Conversations convs = new Conversations(client);
var conversationIDs = new string[] { "0000000000000000-0000000000000000", "00:0123456789abcdefghijklmnopqrstuvwxyz0123456789-A-_0123456798ABCDEF" }; // Existing Facebook & Skype conversations
// Send a message to each conversation:
foreach (var conversationID in conversationIDs)
{
Message message = new Message(conversationId: conversationID, fromProperty: "My Bot", text: "Hey dude, remember that thing!");
Console.WriteLine(message.Text);
convs.PostMessage(conversationID, message); // FAILS - This executes but doesn't do anything.
}
// Try reading the messages from a conversation (just to test if it's working):
string waterMark = null;
var set = convs.GetMessages(conversationIDs[0], waterMark); // FAILS - This fails with a 404 not found.
waterMark = set.Watermark;
return "Done :-)";
}
It fails silently calling PostMessage() and fails with a 404 for the GetMessages(). I seem to be doing the right thing, the bot is live etc and works very well in Facebook & Skype separately from the DirectLine API. It only works if I create a new conversation using the DirectLine API, I can then access its messages and post new messages to it.
This question sort of helps but doesn't quite tell me what to do to fix it:
Difficulty accessing messages in an existing conversation in Microsoft Bot Framework
Any help would be much appreciated.
Thanks
For security reasons, you can't use DirectLine to spy on messages from another conversation. For the scenario you describe (escalating to a human) there a number of different ways to approach this. One is to have your bot broker conversations between the accounts (i.e. Facebook End User <-> Your Bot <-> Facebook Support Person). Each is talking to the bot, and the bot passes the message through to the other user. (Could also be Facebook User <-> Your Bot <-> Skype User) Your bot would have to store last n messages to provide context. Alternatively, I've seen folks build their own customer support chat interface using direct line that sits on the far side. Hope this helps

Sending a tweet from a C# Application (unattended)

How can I send a tweet from an unattended C# application? So far, I've tried TweetSharp, but that isn't working for me (no errors, but no success either). Here's the background info...
I have set up two twitter accounts to test this (lets call them TwitterSender and TwitterReceiver). TwitterReceiver is "following" TwitterSender. I went to dev.twitter.com and logged in as TwitterSender and clicked the "Create New App" button. From here, I was able to find things called "API Key", "API Secret", "Consumer Key", "Consumer Secret", "Access Token", and "Access Token Secret". When I'm logged in as TwitterSender I can see that I have granted read/write/direct message access. How can I tie all this together so that I can simply run the C# console application and have it send a tweet ("Hello World!") from TwitterSender so that any followers (e.g. TwitterReceiver) will get it? I'm OK with hard-coding user/password in plain-text. In the code below, I get no errors at all, but ultimately TwitterStatus ends up being null, and there is no indication that a tweet was sent either from the perspective of TwitterSender or TwitterReceiver.
TwitterClientInfo twitterClientInfo = new TwitterClientInfo();
twitterClientInfo.ConsumerKey = ConsumerKey; //Read ConsumerKey out of the app.config
twitterClientInfo.ConsumerSecret = ConsumerSecret; //Read the ConsumerSecret out the app.config
TwitterService twitterService = new TwitterService(twitterClientInfo);
twitterService.AuthenticateWith(AccessToken, AccessTokenSecret);
Console.WriteLine("Enter a Tweet");
string tweetMessage;
tweetMessage = Console.ReadLine();
TwitterStatus twitterStatus = twitterService.SendTweet(tweetMessage);
I got this working finally! In short, to send a tweet from, say, a Windows form without requiring a user to log in, you would do the following:
go to dev.twitter.com, log in as the account you want to send tweets from, and then create an "Application". A twitter "Application" in this sense is really just an authorization mechanism and not something that a user interacts with at all.
You will be asked for a website during the process of creating the application...After watching a Turkish video tutorial on how this was done, I entered http://www.google.com/tr, but it's likely that Uzbekistan ("uz" I believe) would work equally well). No, I have no idea why you need this.
Leave "Callback URL" blank and uncheck "Allow this application to sign in with Twitter".
Set the permissions of your application to read/write
Generate your OAuth keys - there should be four keys: the "API Key" (AKA Consumer Key), "API Secret" (AKA ConsumerSecret), "Token Key", and "Token Secret".
Now, go to twitter.com and log into your account (different than dev.twitter.com). Under "Settings" (hidden under the gear icon I think), there should be an "Apps" tab where you should see the application that you just created. You may need to grant it permissions from here (or it may already be set). You can also revoke permissions here.
Using Visual Studio 2012 and .NET framework 4.5 (NOT VS2010), get TweetSharp from NuGet. This project is no longer maintained or supported by the original developer, so don't expect much documentation or guidance if things don't work.
Write your code. For example, in a button click event...
var service = new TweetSharp.TwitterService("ConsumerKey","ConsumerSecret","TokenKey","TokenSecretKey"); //Replace keys with values from step #5
var twitterStatus = service.SendTweet(new SendTweetOptions() { Status ="Hello World" });
if (twitterStatus != null)
{
MessageBox.Show("It worked");
}
Note - You can't send the exact same tweet more than once per ___ (some undocumented amount of time). When there is an authentication problem, twitterStatus will return null - if that happens, check your keys, perhaps repermission and regenerate them again.

Display User Picture in Lync 2013

I am working on small application using the lync 2013 sdk. Is there any way provided in sdk where I can implement a functionality to allow user to upload his picture using any API provided in the SDK.
If it is possible then what and where is the best way to store it, if the users are configured in the active directory?
Waiting for a positive response from your side.
Regards
Amit
You can get a stream to the photo via the SDK using
var photoStream = Client.Self.Contact.GetContactInformation(ContactInformationType.Photo) as System.IO.Stream
And whilst you can read the stream you can't write to it as you are at this point looking at contact information from AD.
Kind of feels like you want to write something to change the photo in the photoThumbnails attribute of AD not in Lync.
Update as of 12/11/2013
The latest Lync update (Lync Client CU3 (November Update)) has the option to set a photo added back to the GUI.
Link to the KB Article
Link to the Download
Article with explanations and screenshots can be found here: Lync Client CU3 (November Update) – Show a picture from a website!.
Original Answer
Though this is a different problem, my answer to this question (Displaying a photo for an Application endpoint) is valid here as well:
Basicly, there is an option to set a user's photo to an URL, but it is no longer displayed in the Lync 2013 client interface (it was there in the Lync 2010 client). If you can get your code to publish the image to a web-accessible location, you could publish the URL to it and change your user picture that way.
For reference, the answer to the other question:
Publishing presence information (which includes photo settings) is done on the LocalEndpoint.LocalOwnerPresence. Both UserEndpoint and ApplicationEndpoint derive from LocalEndpoint, so this should be doable really.
The actual publishing gets slightly complex because there are a lot of different combinations of 'levels' to publish on:
First, there are a bunch of InstanceID values that you need to know about, read up on them here: Presence data source and category instance ID
Second, there is a value for who this presence applies to, see Microsoft.Rtc.Collaboration.Presence.PresenceRelationshipLevel. Don't publish on Unknown, you'll get an exception.
public enum PresenceRelationshipLevel
{
Unknown = -1,
Everyone = 0,
External = 100,
Colleagues = 200,
Workgroup = 300,
Personal = 400,
Blocked = 32000,
}
You need to publish a PresenceCategoryWithMetaData for the user photo properties, which is part of container 0x5, "Presentity information".
var photoPresence = new PresenceCategoryWithMetaData(
0x5, // The container id
(int)PresenceRelationshipLevel.Everyone,
new ContactCard(0x5) // Same container ID again
{
IsAllowedToShowPhoto = true,
PhotoUri = "<uri to your photo here"
});
You can set an ExpiryPolicy on this object too, should be self explainatory really. Then publish this presence object on your endpoint:
Endpoint.LocalOwnerPresence.BeginPublishPresence(new[] { photoPresence }, cb => {
Endpoint.LocalOwnerPresence.EndPublishPresence(cb);
}, null);
And that should do it, really. I ended up explicitly publishing to all relationship levels because it didn't cascade the data as logically expected.

Categories

Resources