I am developing a bot based on a .NET Bot Builder SDK.
Is it possible for a bot to pass some debug information together with the message, so I can see it in the Details section of the Bot Framework Chanel Emulator when the message is clicked?
Great Question. Yes, it is entirely possible. You can use the ChannelData property of your activity you are responding with. The data entered into the ChannelData property must be valid JSON For example:
var reply = activity.CreateReply("test");
string json = #"{
CustomField1: 'Field one value',
CustomField2Array: [
'First Element',
'Second Element'
]
}";
reply.ChannelData = JObject.Parse(json);
await context.PostAsync(reply);
In the emulator this will appear as:
"channelData": {
"CustomField1": "Field one value",
"CustomField2Array": [
"First Element",
"Second Element"
]
}
Related
I'm trying to send an activity with an adaptive card attachment and include a mention to the user who created the post. From reading online I found you can't currently include mentions in adaptive cards. Is there a way to mention someone when sending the activity, for example in another attachment?. I have tried setting the activity.Text = mention, this works however it creates two posts, the first with the mention and then another post with the adaptive card as a separate message. I feel there must be a way to do this, else if you created a post and someone responded to you, you'd never know automatically on reply. Also note I'm not using Flow.
Code
Teams Post
Have you thought about (a) sending the adaptive card and (b) sending a "Reply" message to the original Adaptive Card you sent? I haven't done this before, but I'm guessing the id that comes back from turnContext.SendActivityAsync (on the ResourceResponse instance) is the id you can use to "reply" to the message you just created.
Update: I got it working. This is -very- rough code but hopefully enough that you can figure out/adjust to your scenario:
var result = connector.Conversations.SendToConversationAsync([your conversation id], activity).Result;
// I'm re-using the same activity just as a test, you can do whatever (e.g. create a new one)
activity.Text = "Msg 2";
var conversationReference = activity.GetReplyConversationReference(result);
conversationReference.Conversation.Id = conversationReference.Conversation.Id + ";messageid=" + result.Id;
activity.ApplyConversationReference(conversationReference);
connector.Conversations.SendToConversationAsync(conversationReference.Conversation.Id, activity);
So note, really important, you need to change your conversation id to add ";messageid=" to the end, and ADD the reference the message you just posted.
Here's a screenshot:
Hope that helps, and thanks for this - gave me a chance to learn something useful!
Currently Adaptive Card #mention is in developer preview but you can achieve the #Mention in adaptive card with Adaptive card 1.2 version.
You can #Mention a user in adaptive card using following JSON
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"text": "Hi <at>Mention_Name</at> This is new feature in Adaptive Card version 1.2 Please test..."
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"channelId": {
"entities": [
{
"type": "mention",
"text": "<at>Name</at>",
"mentioned": {
"id": "29:124124124124",
"name": "Mungo"
}
}
]
}
}
You need to specify channelID, and mentioned ID which you can fetch from the activity object itself
On the Slack website, I can format a message like this:
{
"text": "<http://google.com|link to google>"
}
And in the message it will appear like this:
link to google
But I am trying to write a bot and those links aren't working. Using my websocket connection I can send a message like this:
var send = new MessageToSlack()
{
type = "message",
channel = msg.channel,
text = $"http://google.com"
};
ws.SendAsync(JsonConvert.SerializeObject(send), b => { });
And Slack will correctly interpret http://google.com as a link and display it like:
http://google.com
But if I try to send a message with the link in angle brackets with the pipe between the link and the link text (which works on Slack's site) like this:
var send = new MessageToSlack()
{
type = "message",
channel = msg.channel,
text = $"<http://google.com|to google>"
};
ws.SendAsync(JsonConvert.SerializeObject(send), b => { });
I end up with:
<http://google.com|to google>
So how do I get this working from my bot? Why is it not able to parse by links correctly? What am I missing?
As far as I can see from the docs, this should work. Here in the section on formatting messages it says:
The RTM API only supports posting simple messages formatted using our default message formatting mode.
And links to here which does mention links with the pipe character, so I think it should work.
(note MessageToSlack is just an ordinary .NET class with type, channel and text properties that gets serialized by JSON.Net and appears to give the correct JSON. ws is my websocket connection from the WebSocketSharp nuget package)
JSON:
{
"id": 1,
"type": "message",
"channel": "C6QRKT0EA",
"text": "<http://google.com|to google>"
}
Edit: So it seems if I switch from replying with the web socket connection and instead post to https://slack.com/api/chat.postMessage, it will work correctly, but it's a bit more fiddly to use and the documentation led me to believe that the links should work without needing to jump through that particular hoop. Am I just misreading the docs? Or are docs just not very clear on this point?
Try to enable markdown support by adding "mrkdwn": true to your json
{
"type": "message",
"channel": "C6QRKT0EA",
"text": "<http://google.com|to google>",
"mrkdwn": true
}
Read Message Formatting section. Hope it will help.
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
I am writing a custom Teams bot. I got some questions about Activity.Text field:
How is it encoded? I see some <at> tags when the bot is #mentioned, but I also see some '. Can I use HttpUtility.HtmlDecodeto decode it?
Is there any document about the details of the Activity.Text field? The schema says it is
Text of the message that is sent from user to bot or bot to user. See the channel's documentation for limits imposed upon the contents of this property.
But it does not talk about the details about the field.
Nothing special about Activity.Text in Teams except for the tags. In general, depending on the Activity.TextFormat, the message you send might contain markdown or XML, but in general the message you receive from a user will be plain text.
Anything additional, like if the user sends bold text to your bot, can be extracted from the attachments object in the incoming payload, e.g. :
"attachments": [
{
"contentType": "text/html",
"content": "<div><span itemscope=\"\" itemtype=\"http://schema.skype.com/Mention\" itemid=\"0\">Teams TestBot</span> |echo| <strong><strong>Hi</strong></strong></div>"
}
]
I'm trying to implement a domain search in our website, but I have no clue how... the WHOIS service I registered by, gave me an API key to use... When I use the following address in my browser's url,
http://api.robowhois.com/v1/availability/example.com
a login box appears, asking me for my username and password, when I type in my username and password which is the key they gave me, a page appears with the following
{
"response": {
"available": false
}
}
I'm sorry to say, but I've been searching for weeks on how to solve this but at the end my last resort was to turn to stack overflow... can someone please help, is there a way on how to use and call the url and use the info?
You already got the information you need. It responds with a JSON object saying it's not available.
To retrieve the information as you wish, you can use Jquery, just put your URL in a function as in the examples and get data.response.available value and assign it to your textbox etc. For more information how to make JSON calls and parse them, check out this documentation in Jquery website.
RoboWhois is a web service that provides an API suite to access WHOIS
records and domain related information with a unified, consistent
interface. Using RoboWhois API you can retrieve WHOIS details parsed
as convenient JSON structure.
In order to check the availability of a given domain you have to send a http get request to the robowhois api http://api.robowhois.com/v1/availability/example.com
The server does answer the request by sending http response containing json which looks like this:
{
"response": {
"available": false
}
}
which means the domain is no longer available.
In order to use the information contained in the json response you should deserialize the json object to a c# object. You can do this for example with the json.net library.
Here is a small example from the documentation on how to use json.net to deserialize a json:
Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "ExpiryDate": "2008-12-28T00:00:00",
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);