Bot Framework相关文档:https://docs.botframework.com/en-us/csharp/builder/sdkreference/attachments.html
Bot Framework提供的回复样式不仅仅是语言框。如果我们写下这样的代码:
1 Activity reply = activity.CreateReply($"You sent {activity.Text} which was {length} characters"); 2 await connector.Conversations.ReplyToActivityAsync(reply);
(本代码来自官方文档)
我们注意到这里的Activity类(https://docs.botframework.com/en-us/csharp/builder/sdkreference/activities.html)的属性没有被妥善设置,所以使用了默认值。而在实际情况中,Activity类通常可以被设置各种各样的属性。
1 public class Activity : IActivity, IContactRelationUpdateActivity, IMessageActivity, ITypingActivity, IConversationUpdateActivity, IActionActivity 2 { 3 /// <summary>Initializes a new instance of the Activity class.</summary> 4 public Activity(); 5 /// <summary>Initializes a new instance of the Activity class.</summary> 6 public Activity(string type = null, string id = null, DateTime? timestamp = null, string serviceUrl = null, string channelId = null, ChannelAccount from = null, ConversationAccount conversation = null, ChannelAccount recipient = null, string textFormat = null, string attachmentLayout = null, IList<ChannelAccount> membersAdded = null, IList<ChannelAccount> membersRemoved = null, string topicName = null, bool? historyDisclosed = null, string locale = null, string text = null, string summary = null, IList<Attachment> attachments = null, IList<Entity> entities = null, object channelData = null, string action = null, string replyToId = null);
(本代码来自类定义)
首先,Activity类有一个这样的属性:ActivityType
当Type(通常)被设置为Message时,能做的事情是最多的。下面我介绍4个属性,这4个属性都是Message能完成的。
1,Text&Locale/TextFormat属性:主要是文本和区域,文本格式这几个属性。
文本和区域:
Description | Example | |
---|---|---|
Text | A text payload in markdown syntax which will be rendered as appropriate on each channel | Hello, how are you? |
Locale | The locale of the sender (if known) | en |
文本格式:
Description | Notes | |
---|---|---|
plain | The text should be treated as raw text and no formatting applied at all | |
markdown | The text should be treated as markdown formatting and rendered on the channel as appropriate | default |
xml | The text is simple XML markup (subset of HTML) | Skype Only |
具体的规范可以自行查阅文档。
2,Attachment属性:是一系列附件对象,其中Rich Card就在这里;除此之外还可以设置多个Rich Card是以转盘的形式显示还是列表的形式。
Description | Example | |
---|---|---|
ContentType | The contentType of the ContentUrl property | image/png |
ContentUrl | A link to content of type ContentType | http://somedomain.com/cat.jpg |
Content | An embedded object of type contentType | If contentType = "application/vnd.microsoft.hero" then Content would be a JSON object for the HeroCard |
下表是AttachmentLayout属性:
Description | Notes | |
---|---|---|
list | Multiple attachments should be shown as a list | default |
carousel | multiple attachments should be shown as a carousel if possible, else fall back to a list |
3,Entities属性:Entities属性是一系列开放式schema.org对象,允许在通道和机器人之间交换常见的上下文元数据。当设置了这样的属性,我们就可以很好地串起上下文来分析。
其中,Mention实体就可以通过设置来感知自己有没有被提起(比如说有没有人通过@机器人 的方式使用它)。
Description | |
---|---|
type | type of the entity ("mention") |
mentioned | ChannelAccount of the person or user who was mentioned |
text | the text in the Activity.Text property which represents the mention. (this can be empty or null) |
而Place实体可以通过channels发送地址、地理信息。
The Place Object
Property | Description |
---|---|
Type | 'Place' |
Address | string description or PostalAddress (future) |
Geo | GeoCoordinates |
HasMap | URL to a map or complex "Map" object (future) |
Name | Name of the place |
GeoCoordinates Object
Property | Description |
---|---|
Type | 'GeoCoordinates' |
Name | Name of the place |
Longitude | Longitude of the location WGS 84 |
Latitude | Latitude of the location WGS 84 |
Elevation | Elevation of the location WGS 84 |
4,ChannelData property:可以传递额外的属性,更详细地描述每个channel启用的message。
当Type不是Message时,将会有其他的对应措施。比如说,
Conversation Update代表它的状态被改变,比如把bot添加到会话中,或者更改会话对象。
Contact Relation Update代表bot被用户在联系人列表中添加/删除了。
Typing可以告诉双方一个“正在打字”的状态。
Ping是用来测试Bot的。
Delete是用来删除用户的个人身份信息的。
我们在初次接触Bot时,应该重点掌握Message这种类型。
现在我们来读一段代码:
1 ……(创建了一个connector) 2 3 Activity replyToConversation = message.CreateReply("Should go to conversation, with a carousel"); 4 replyToConversation.Recipient = message.From; 5 replyToConversation.Type = "message"; 6 replyToConversation.AttachmentLayout = AttachmentLayouts.Carousel; 7 replyToConversation.Attachments = new List<Attachment>(); 8 Dictionary<string, string> cardContentList = new Dictionary<string, string>(); 9 cardContentList.Add("PigLatin", "https://<ImageUrl1>"); 10 cardContentList.Add("Pork Shoulder", "https://<ImageUrl2>"); 11 cardContentList.Add("Bacon", "https://<ImageUrl3>"); 12 foreach(KeyValuePair<string, string> cardContent in cardContentList) 13 { 14 List<CardImage> cardImages = new List<CardImage>(); 15 cardImages.Add(new CardImage(url:cardContent.Value )); 16 List<CardAction> cardButtons = new List<CardAction>(); 17 CardAction plButton = new CardAction() 18 { 19 Value = $"https://en.wikipedia.org/wiki/{cardContent.Key}", 20 Type = "openUrl", 21 Title = "WikiPedia Page" 22 }; 23 cardButtons.Add(plButton); 24 HeroCard plCard = new HeroCard() 25 { 26 Title = $"I'm a hero card about {cardContent.Key}", 27 Subtitle = $"{cardContent.Key} Wikipedia Page", 28 Images = cardImages, 29 Buttons = cardButtons 30 }; 31 Attachment plAttachment = plCard.ToAttachment(); 32 replyToConversation.Attachments.Add(plAttachment); 33 } 34 replyToConversation.AttachmentLayout = AttachmentLayoutTypes.Carousel; 35 var reply = await connector.Conversations.SendToConversationAsync(replyToConversation);
请关注第4行,设置了这个Activity类的收件人就是这个Activity的发起者(一对一对话中这一行可以被去掉)。
第5行中,设置了Type为Message。
第6行中,设置了显示模式为转盘。
第7行,表示这个activity要加入一些attachment(比如说别的文章会提到的Rich Card),初始化了一个List。
后面将三种东西打包作为三个整体使用。
后面的代码有兴趣的可以尝试,我在别的文章里会解释这些卡片的详细含义。