microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
next/core

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

core/samples/CompatBot/EchoBot.cs

230lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using Microsoft.Bot.Builder;
5using Microsoft.Bot.Builder.Teams;
6using Microsoft.Bot.Schema;
7using Microsoft.Bot.Schema.Teams;
8using Microsoft.Teams.Bot.Compat;
9using Microsoft.Teams.Bot.Core;
10using Microsoft.Teams.Bot.Core.Schema;
11using Newtonsoft.Json;
12using Newtonsoft.Json.Linq;
13
14namespace CompatBot;
15
16public class ConversationData
17{
18 public int MessageCount { get; set; } = 0;
19
20}
21
22internal class EchoBot(BotApplication teamsBotApp, ConversationState conversationState, ILogger<EchoBot> logger)
23 : TeamsActivityHandler
24{
25 public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default)
26 {
27 await base.OnTurnAsync(turnContext, cancellationToken);
28
29 await conversationState.SaveChangesAsync(turnContext, false, cancellationToken);
30 }
31 protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
32 {
33 logger.LogInformation("OnMessage");
34 IStatePropertyAccessor<ConversationData> conversationStateAccessors = conversationState.CreateProperty<ConversationData>(nameof(ConversationData));
35 ConversationData conversationData = await conversationStateAccessors.GetAsync(turnContext, () => new ConversationData(), cancellationToken);
36
37 var mm = await CompatTeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id);
38 string replyText = $"Echo {mm.Name} from BF Compat [{conversationData.MessageCount++}]: {turnContext.Activity.Text}";
39
40 // Targeted Messaging via BF compat layer: setting isTargeted on the BF ChannelAccount
41 // causes the compat layer to set CoreActivity.Recipient.IsTargeted, which appends
42 // ?isTargetedActivity=true to the URL making the message visible only to that user.
43 var act = MessageFactory.Text(replyText, replyText);
44 act.Recipient = new ChannelAccount();
45 act.Recipient.Properties.Add("isTargeted", true);
46 await turnContext.SendActivityAsync(act, cancellationToken);
47
48
49 if (turnContext.Activity.Conversation.IsGroup == true)
50 {
51 var teamDetails = await CompatTeamsInfo.GetTeamDetailsAsync(turnContext, null, cancellationToken);
52 await turnContext.SendActivityAsync(JsonConvert.SerializeObject(teamDetails, Formatting.Indented));
53
54 TeamsPagedMembersResult pagedMembersResult;
55 List<TeamsChannelAccount> members = new List<TeamsChannelAccount>();
56 string continuationToken = null!;
57 do
58 {
59 pagedMembersResult = await CompatTeamsInfo.GetPagedMembersAsync(
60 turnContext,
61 5,
62 continuationToken,
63 cancellationToken
64 );
65
66 continuationToken = pagedMembersResult.ContinuationToken;
67 members.AddRange(pagedMembersResult.Members);
68 } while (continuationToken != null);
69
70 await turnContext.SendActivityAsync(JsonConvert.SerializeObject(members.Select(m => m.Name).ToList(), Formatting.Indented));
71 }
72
73 // Targeted Messaging via Core SDK (preferred): sends directly through ConversationClient
74 // to bypass the BF compat layer's ApplyConversationReference which would overwrite the Recipient.
75 var incomingCoreActivity = ((Activity)turnContext.Activity).FromCompatActivity();
76 var incomingFrom = incomingCoreActivity.From;
77 var incomingRecipient = incomingCoreActivity.Recipient;
78 incomingFrom!.IsTargeted = true;
79 CoreActivity tm = CoreActivity.CreateBuilder()
80 .WithConversation(incomingCoreActivity.Conversation!)
81 .WithProperty("text", "Hello TM !")
82 .WithRecipient(incomingFrom)
83 .WithFrom(incomingRecipient)
84 //.WithServiceUrl(activity.ServiceUrl!)
85 .WithServiceUrl("https://pilot1.botapi.skype.com/amer/9a9b49fd-1dc5-4217-88b3-ecf855e91b0e/")
86 .Build();
87
88 await teamsBotApp.ConversationClient.SendActivityAsync(tm, cancellationToken: cancellationToken);
89
90 var res = await turnContext.SendActivityAsync(
91 MessageFactory.Text("I'm going to add and remove reactions to this message."), cancellationToken);
92
93 await Task.Delay(500, cancellationToken);
94
95 await teamsBotApp.ConversationClient.AddReactionAsync(
96 turnContext.Activity.Conversation.Id,
97 res.Id,
98 "laugh",
99 new Uri("https://pilot1.botapi.skype.com/amer/9a9b49fd-1dc5-4217-88b3-ecf855e91b0e/"),
100 //incomingCoreActivity.ServiceUrl!,
101 AgenticIdentity.FromAccount(incomingRecipient),
102 null,
103 cancellationToken);
104
105 await Task.Delay(500, cancellationToken);
106
107 await teamsBotApp.ConversationClient.AddReactionAsync(
108 turnContext.Activity.Conversation.Id,
109 res.Id,
110 "sad",
111 incomingCoreActivity.ServiceUrl!,
112 AgenticIdentity.FromAccount(incomingRecipient),
113 null,
114 cancellationToken);
115
116 await Task.Delay(500, cancellationToken);
117
118 await teamsBotApp.ConversationClient.DeleteReactionAsync(
119 turnContext.Activity.Conversation.Id,
120 res.Id,
121 "laugh",
122 //new Uri("https://pilot1.botapi.skype.com/amer/9a9b49fd-1dc5-4217-88b3-ecf855e91b0e/"),
123 incomingCoreActivity.ServiceUrl!,
124 AgenticIdentity.FromAccount(incomingRecipient),
125 null,
126 cancellationToken);
127
128 // Card submission triggers OnInvokeActivityAsync below.
129 Attachment attachment = new()
130 {
131 ContentType = "application/vnd.microsoft.card.adaptive",
132 Content = Cards.FeedbackCardObj
133 };
134 IMessageActivity attachmentReply = MessageFactory.Attachment(attachment);
135 await turnContext.SendActivityAsync(attachmentReply, cancellationToken);
136
137 }
138
139
140 protected override async Task OnMessageReactionActivityAsync(ITurnContext<IMessageReactionActivity> turnContext, CancellationToken cancellationToken)
141 {
142 await turnContext.SendActivityAsync(MessageFactory.Text("Message reaction received."), cancellationToken);
143 }
144
145 protected override async Task OnInstallationUpdateActivityAsync(ITurnContext<IInstallationUpdateActivity> turnContext, CancellationToken cancellationToken)
146 {
147 await turnContext.SendActivityAsync(MessageFactory.Text("Installation update received."), cancellationToken);
148 await turnContext.SendActivityAsync(MessageFactory.Text($"Send a proactive messages to `/api/notify/{turnContext.Activity.Conversation.Id}`"), cancellationToken);
149 }
150
151 protected override async Task OnInstallationUpdateAddAsync(ITurnContext<IInstallationUpdateActivity> turnContext, CancellationToken cancellationToken)
152 {
153 await turnContext.SendActivityAsync(MessageFactory.Text("Installation update Add received."), cancellationToken);
154 await turnContext.SendActivityAsync(MessageFactory.Text($"Send a proactive messages to `/api/notify/{turnContext.Activity.Conversation.Id}`"), cancellationToken);
155 }
156
157 protected override async Task<Microsoft.Bot.Builder.InvokeResponse> OnInvokeActivityAsync(ITurnContext<IInvokeActivity> turnContext, CancellationToken cancellationToken)
158 {
159 logger.LogInformation("Invoke Activity received: {Name}", turnContext.Activity.Name);
160 JObject actionValue = JObject.FromObject(turnContext.Activity.Value);
161 JObject? action = actionValue["action"] as JObject;
162 JObject? actionData = action?["data"] as JObject;
163 string? userInput = actionData?["feedback"]?.ToString();
164 //var userInput = actionValue["userInput"]?.ToString();
165
166 logger.LogInformation("Action: {Action}, User Input: {UserInput}", action, userInput);
167
168
169
170 Attachment attachment = new()
171 {
172 ContentType = "application/vnd.microsoft.card.adaptive",
173 Content = Cards.ResponseCard(userInput)
174 };
175
176 IMessageActivity card = MessageFactory.Attachment(attachment);
177 await turnContext.SendActivityAsync(card, cancellationToken);
178
179 return new Microsoft.Bot.Builder.InvokeResponse
180 {
181 Status = 200,
182 Body = new { value = "invokes from compat bot" }
183 };
184 }
185
186 protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
187 {
188 await turnContext.SendActivityAsync(MessageFactory.Text("Welcome."), cancellationToken);
189 await turnContext.SendActivityAsync(MessageFactory.Text($"Send a proactive messages to `/api/notify/{turnContext.Activity.Conversation.Id}`"), cancellationToken);
190 }
191
192 protected override Task OnMembersRemovedAsync(IList<ChannelAccount> membersRemoved, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
193 {
194 return turnContext.SendActivityAsync(MessageFactory.Text("Bye."), cancellationToken);
195 }
196
197 protected override async Task OnTeamsMeetingStartAsync(MeetingStartEventDetails meeting, ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
198 {
199 await turnContext.SendActivityAsync(MessageFactory.Text("Welcome to meeting: "), cancellationToken);
200 await turnContext.SendActivityAsync(MessageFactory.Text($"{meeting.Title} {meeting.MeetingType}"), cancellationToken);
201 }
202
203 private static async Task SendUpdateDeleteActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
204 {
205 ConversationReference cr = turnContext.Activity.GetConversationReference();
206 Activity reply = (Activity)Activity.CreateMessageActivity();
207 reply.ApplyConversationReference(cr, isIncoming: false);
208 reply.Text = "This is a proactive message sent using the Conversations API.";
209
210 ResourceResponse[] res = await turnContext.Adapter.SendActivitiesAsync(turnContext, [reply], cancellationToken);
211
212 await Task.Delay(2000, cancellationToken);
213
214 Activity updatedActivity = (Activity)Activity.CreateMessageActivity();
215 updatedActivity.ApplyConversationReference(cr, isIncoming: false);
216 updatedActivity.Id = res[0].Id;
217 updatedActivity.Text = "This message has been updated.";
218
219 await turnContext.Adapter.UpdateActivityAsync(turnContext, updatedActivity, cancellationToken);
220
221 await Task.Delay(2000, cancellationToken);
222
223 ConversationReference deleteReference = cr;
224 deleteReference.ActivityId = res[0].Id;
225 await turnContext.Adapter.DeleteActivityAsync(turnContext, deleteReference, cancellationToken);
226
227 await turnContext.SendActivityAsync(MessageFactory.Text("Proactive message sent and deleted."), cancellationToken);
228 }
229
230}
231