Skip to content

Commit 109a99f

Browse files
authored
Merge pull request #1594 from OfficeDev/v-jegadeesh/ailabelcsharp
AI formating - csharp
2 parents cb9c5bb + 9639b2c commit 109a99f

File tree

3 files changed

+266
-1
lines changed

3 files changed

+266
-1
lines changed

samples/bot-conversation/csharp/Bots/TeamsConversationBot.cs

Lines changed: 223 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
using Microsoft.Bot.Builder.Integration.AspNet.Core;
2121
using System.Collections.Concurrent;
2222
using System.Collections;
23+
using Microsoft.AspNetCore.Http;
24+
using static System.Net.Mime.MediaTypeNames;
2325

2426
namespace Microsoft.BotBuilderSamples.Bots
2527
{
@@ -67,6 +69,16 @@ protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivi
6769
await CheckReadUserCount(turnContext, cancellationToken);
6870
else if (text.Contains("reset"))
6971
await ResetReadUserCount(turnContext, cancellationToken);
72+
else if (text.Contains("label"))
73+
await AddAILabel(turnContext, cancellationToken);
74+
else if (text.Contains("feedback"))
75+
await AddFeedbackButtons(turnContext, cancellationToken);
76+
else if (text.Contains("sensitivity"))
77+
await AddSensitivityLabel(turnContext, cancellationToken);
78+
else if (text.Contains("citation"))
79+
await AddCitations(turnContext, cancellationToken);
80+
else if (text.Contains("aitext"))
81+
await SendAIMessage(turnContext, cancellationToken);
7082
else
7183
await CardActivityAsync(turnContext, false, cancellationToken);
7284
}
@@ -82,6 +94,186 @@ protected override async Task OnTeamsMembersAddedAsync(IList<TeamsChannelAccount
8294
}
8395
}
8496

97+
private async Task AddAILabel(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
98+
{
99+
await turnContext.SendActivityAsync(
100+
new Activity
101+
{
102+
Type = ActivityTypes.Message,
103+
Text = "Hey I'm a friendly AI bot. This message is generated via AI",
104+
Entities = new List<Entity>
105+
{
106+
new Entity
107+
{
108+
Type = "https://schema.org/Message",
109+
Properties = JObject.FromObject(new Dictionary<string, object>
110+
{
111+
{ "@type", "Message" },
112+
{ "@context", "https://schema.org" },
113+
{ "additionalType", new List<string> { "AIGeneratedContent" } }
114+
})
115+
}
116+
}
117+
}
118+
);
119+
}
120+
121+
private async Task AddFeedbackButtons(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
122+
{
123+
await turnContext.SendActivityAsync(
124+
new Activity
125+
{
126+
Type = ActivityTypes.Message,
127+
Text = "This is an example for Feedback buttons that helps to provide feedback for a bot message",
128+
ChannelData = new { feedbackLoopEnabled = true },
129+
}
130+
);
131+
}
132+
133+
private async Task AddSensitivityLabel(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
134+
{
135+
await turnContext.SendActivityAsync(
136+
new Activity
137+
{
138+
Type = ActivityTypes.Message,
139+
Text = "This is an example for sensitivity label that helps users identify the confidentiality of a message",
140+
Entities = new List<Entity>
141+
{
142+
new Entity
143+
{
144+
Type = "https://schema.org/Message",
145+
Properties = JObject.FromObject(new Dictionary<string, object>
146+
{
147+
{ "@type", "Message" },
148+
{ "@context", "https://schema.org" }, // AI Generated label
149+
{ "usageInfo", new Dictionary<string, object>
150+
{
151+
{ "@type", "CreativeWork" },
152+
{ "description", "Please be mindful of sharing outside of your team" }, // Sensitivity description
153+
{ "name", "Confidential \\ Contoso FTE" } // Sensitivity title
154+
}
155+
}
156+
})
157+
}
158+
}
159+
}, cancellationToken);
160+
}
161+
162+
private async Task SendAIMessage(ITurnContext<IMessageActivity> context, CancellationToken cancellationToken)
163+
{
164+
await context.SendActivityAsync(
165+
new Activity
166+
{
167+
Type = ActivityTypes.Message,
168+
Text = "Hey I'm a friendly AI bot. This message is generated via AI [1]",
169+
ChannelData = JObject.FromObject(new Dictionary<string, object>
170+
{
171+
{ "feedbackLoopEnabled", true }
172+
}),
173+
Entities = new List<Entity>
174+
{
175+
new Entity
176+
{
177+
Type = "https://schema.org/Message",
178+
Properties = JObject.FromObject(new Dictionary<string, object>
179+
{
180+
{ "@type", "Message" },
181+
{ "@context", "https://schema.org" },
182+
{ "usageInfo", new Dictionary<string, object>
183+
{
184+
{ "@type", "CreativeWork" },
185+
{ "@id", "sensitivity1" }
186+
}
187+
},
188+
{ "additionalType", new List<string> { "AIGeneratedContent" } },
189+
{ "citation", new List<object>
190+
{
191+
new Dictionary<string, object>
192+
{
193+
{ "@type", "Claim" },
194+
{ "position", 1 },
195+
{ "appearance", new Dictionary<string, object>
196+
{
197+
{ "@type", "DigitalDocument" },
198+
{ "name", "Some secret citation" },
199+
{ "url", "https://example.com/claim-1" },
200+
{ "abstract", "Excerpt" },
201+
{ "encodingFormat", "docx" },
202+
{ "keywords", new List<string> { "Keyword1 - 1", "Keyword1 - 2", "Keyword1 - 3" } },
203+
{ "usageInfo", new Dictionary<string, object>
204+
{
205+
{ "@type", "CreativeWork" },
206+
{ "@id", "sensitivity1" },
207+
{ "name", "Sensitivity title" },
208+
{ "description", "Sensitivity description" }
209+
}
210+
}
211+
}
212+
}
213+
}
214+
}
215+
}
216+
})
217+
}
218+
}
219+
}, cancellationToken);
220+
}
221+
222+
private async Task AddCitations(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
223+
{
224+
await turnContext.SendActivityAsync(
225+
new Activity
226+
{
227+
Type = ActivityTypes.Message,
228+
Text = "Hey I'm a friendly AI bot. This message is generated through AI [1]", // cite with [1]
229+
Entities = new List<Entity>
230+
{
231+
new Entity
232+
{
233+
Type = "https://schema.org/Message",
234+
Properties = JObject.FromObject(new Dictionary<string, object>
235+
{
236+
{ "@type", "Message" },
237+
{ "@context", "https://schema.org" },
238+
{ "citation", new List<object>
239+
{
240+
new Dictionary<string, object>
241+
{
242+
{ "@type", "Claim" },
243+
{ "position", 1 }, // Required. Must match the [1] in the text
244+
{ "appearance", new Dictionary<string, object>
245+
{
246+
{ "@type", "DigitalDocument" },
247+
{ "name", "AI bot" }, // Title
248+
{ "url", "https://example.com/claim-1" }, // Hyperlink on the title
249+
{ "abstract", "Excerpt description" }, // Appears in the citation pop-up window
250+
{ "text", "{\"type\":\"AdaptiveCard\",\"$schema\":\"http://adaptivecards.io/schemas/adaptive-card.json\",\"version\":\"1.6\",\"body\":[{\"type\":\"TextBlock\",\"text\":\"Adaptive Card text\"}]}" }, // Stringified Adaptive Card
251+
{ "keywords", new List<string> { "keyword 1", "keyword 2", "keyword 3" } }, // Appears in the citation pop-up window
252+
{ "encodingFormat", "application/vnd.microsoft.card.adaptive" },
253+
{ "usageInfo", new Dictionary<string, object>
254+
{
255+
{ "@type", "CreativeWork" },
256+
{ "name", "Confidential \\ Contoso FTE" }, // Sensitivity title
257+
{ "description", "Only accessible to Contoso FTE" } // Sensitivity description
258+
}
259+
},
260+
{ "image", new Dictionary<string, object>
261+
{
262+
{ "@type", "ImageObject" },
263+
{ "name", "Microsoft Word" }
264+
}
265+
}
266+
}
267+
}
268+
}
269+
}
270+
}
271+
})
272+
}
273+
}
274+
}, cancellationToken);
275+
}
276+
85277
/// <summary>
86278
/// Checks the count of members who have read the message sent by MessageAllMembers command
87279
/// </summary>
@@ -199,6 +391,36 @@ private async Task CardActivityAsync(ITurnContext<IMessageActivity> turnContext,
199391
Type = ActionTypes.MessageBack,
200392
Title = "Reset read count",
201393
Text = "reset"
394+
},
395+
new CardAction
396+
{
397+
Type = ActionTypes.MessageBack,
398+
Title = "AI label",
399+
Text = "label"
400+
},
401+
new CardAction
402+
{
403+
Type = ActionTypes.MessageBack,
404+
Title = "Feedback buttons",
405+
Text = "feedback"
406+
},
407+
new CardAction
408+
{
409+
Type = ActionTypes.MessageBack,
410+
Title = "Sensitivity label",
411+
Text = "sensitivity"
412+
},
413+
new CardAction
414+
{
415+
Type = ActionTypes.MessageBack,
416+
Title = "Citations",
417+
Text = "citation"
418+
},
419+
new CardAction
420+
{
421+
Type = ActionTypes.MessageBack,
422+
Title = "Send AI message",
423+
Text = "aitext"
202424
}
203425
}
204426
};
@@ -512,4 +734,4 @@ protected override async Task OnTeamsMessageSoftDeleteAsync(ITurnContext<IMessag
512734
await turnContext.SendActivityAsync(replyActivity, cancellationToken);
513735
}
514736
}
515-
}
737+
}

samples/bot-conversation/csharp/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,27 @@ You can interact with this bot in Teams by sending it a message, or selecting a
222222
- Message is restored
223223
![message-undelete](Images/38.Message_Restored.png)
224224
225+
- `AI label` - enables user to identify that the message was generated using AI.
226+
![AI-label](Images/AI-label.png)
227+
228+
- `Citations` - enables user to refer to the source of the bot's message through in-text citations and the reference.
229+
![Citations](Images/citations.png)
230+
231+
- `Feedback buttons` - enables user to provide positive or negative feedback based on their experience.
232+
![Feedback-buttons](Images/Feedback-buttons.png)
233+
234+
![Feedback-buttons1](Images/Feedback-buttons1.png)
235+
236+
![Feedback-buttons2](Images/Feedback-buttons2.png)
237+
238+
![Feedback-buttons3](Images/Feedback-buttons3.png)
239+
240+
- `Sensitivity label` - enables user to understand the confidentiality of the bot's message.
241+
![Sensitivity-label](Images/Sensitivity-label.png)
242+
243+
- `Send AI message` - Replies back with a bot message containing all formats: AI label, Citations, Feedback buttons, and Sensitivity label.
244+
![sendtext](Images/sendtext.png)
245+
225246
You can select an option from the command list by typing ```@TeamsConversationBot``` into the compose message area and ```What can I do?``` text above the compose area.
226247
227248
## Deploy the bot to Azure
@@ -236,5 +257,7 @@ To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](htt
236257
- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0)
237258
- [Messages in bot conversations](https://learn.microsoft.com/microsoftteams/platform/bots/how-to/conversations/conversation-messages?tabs=dotnet)
238259
- [Receive a read receipt](https://learn.microsoft.com/microsoftteams/platform/bots/how-to/conversations/conversation-messages?branch=pr-en-us-9184&tabs=dotnet1%2Capp-manifest-v112-or-later%2Cdotnet2%2Cdotnet3%2Cdotnet4%2Cdotnet5%2Cdotnet#receive-a-read-receipt)
260+
- [Format AI bot messages](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/format-ai-bot-messages?branch=pr-en-us-10798&tabs=js)
261+
239262
240263
<img src="https://pnptelemetry.azurewebsites.net/microsoft-teams-samples/samples/bot-conversation-csharp" />

samples/bot-conversation/csharp/TeamsApp/appPackage/manifest.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,26 @@
5757
{
5858
"title": "MessageAllMembersUsingAadId",
5959
"description": "Send 1 to 1 message to all members of the current conversation using their AADId"
60+
},
61+
{
62+
"title": "AI label",
63+
"description": "AI label added to your bot message specifies that the message is generated by AI"
64+
},
65+
{
66+
"title": "sensitivity",
67+
"description": "Sensitivity label added to your bot message specifies the confidentiality of a message"
68+
},
69+
{
70+
"title": "Feedback buttons",
71+
"description": "Feedback buttons that helps to provide feedback for a bot message"
72+
},
73+
{
74+
"title": "citation",
75+
"description": "Used to cite the sources of the bot message"
76+
},
77+
{
78+
"title": "SendAIText",
79+
"description": "Sends an AI generated message in text format using bot"
6080
}
6181
]
6282
}

0 commit comments

Comments
 (0)