microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
docs/update-release-process

Branches

Tags

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

Clone

HTTPS

Download ZIP

core/samples/CompatBot/EchoBot.cs

232lines · 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.Apps.BotBuilder;
9using Microsoft.Teams.Core;
10using Microsoft.Teams.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 TeamsChannelAccount mm = await TeamsApiClient.GetMemberAsync(turnContext, turnContext.Activity.From.Id, cancellationToken);
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 Activity 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 TeamDetails teamDetails = await TeamsApiClient.GetTeamDetailsAsync(turnContext, null, cancellationToken);
52 await turnContext.SendActivityAsync(JsonConvert.SerializeObject(teamDetails, Formatting.Indented), cancellationToken: cancellationToken);
53
54 TeamsPagedMembersResult pagedMembersResult;
55 List<TeamsChannelAccount> members = [];
56 string continuationToken = null!;
57 do
58 {
59 pagedMembersResult = await TeamsApiClient.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), cancellationToken: cancellationToken);
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 CoreActivity incomingCoreActivity = ((Activity)turnContext.Activity).FromBotFrameworkActivity();
76 Microsoft.Teams.Core.Schema.ConversationAccount? incomingFrom = incomingCoreActivity.From;
77 Microsoft.Teams.Core.Schema.ConversationAccount? incomingRecipient = incomingCoreActivity.Recipient;
78#pragma warning disable ExperimentalTeamsTargeted
79 incomingFrom!.IsTargeted = true;
80#pragma warning restore ExperimentalTeamsTargeted
81 CoreActivity tm = CoreActivity.CreateBuilder()
82 .WithConversation(incomingCoreActivity.Conversation!)
83 .WithProperty("text", "Hello TM !")
84 .WithRecipient(incomingFrom)
85 .WithFrom(incomingRecipient)
86 //.WithServiceUrl(activity.ServiceUrl!)
87 .WithServiceUrl("https://pilot1.botapi.skype.com/amer/9a9b49fd-1dc5-4217-88b3-ecf855e91b0e/")
88 .Build();
89
90 await teamsBotApp.ConversationClient.SendActivityAsync(tm, cancellationToken: cancellationToken);
91
92 ResourceResponse res = await turnContext.SendActivityAsync(
93 MessageFactory.Text("I'm going to add and remove reactions to this message."), cancellationToken);
94
95 await Task.Delay(500, cancellationToken);
96
97 await teamsBotApp.ConversationClient.AddReactionAsync(
98 turnContext.Activity.Conversation.Id,
99 res.Id,
100 "laugh",
101 new Uri("https://pilot1.botapi.skype.com/amer/9a9b49fd-1dc5-4217-88b3-ecf855e91b0e/"),
102 //incomingCoreActivity.ServiceUrl!,
103 AgenticIdentity.FromAccount(incomingRecipient),
104 null,
105 cancellationToken);
106
107 await Task.Delay(500, cancellationToken);
108
109 await teamsBotApp.ConversationClient.AddReactionAsync(
110 turnContext.Activity.Conversation.Id,
111 res.Id,
112 "sad",
113 incomingCoreActivity.ServiceUrl!,
114 AgenticIdentity.FromAccount(incomingRecipient),
115 null,
116 cancellationToken);
117
118 await Task.Delay(500, cancellationToken);
119
120 await teamsBotApp.ConversationClient.DeleteReactionAsync(
121 turnContext.Activity.Conversation.Id,
122 res.Id,
123 "laugh",
124 //new Uri("https://pilot1.botapi.skype.com/amer/9a9b49fd-1dc5-4217-88b3-ecf855e91b0e/"),
125 incomingCoreActivity.ServiceUrl!,
126 AgenticIdentity.FromAccount(incomingRecipient),
127 null,
128 cancellationToken);
129
130 // Card submission triggers OnInvokeActivityAsync below.
131 Attachment attachment = new()
132 {
133 ContentType = "application/vnd.microsoft.card.adaptive",
134 Content = Cards.FeedbackCardObj
135 };
136 IMessageActivity attachmentReply = MessageFactory.Attachment(attachment);
137 await turnContext.SendActivityAsync(attachmentReply, cancellationToken);
138
139 }
140
141
142 protected override async Task OnMessageReactionActivityAsync(ITurnContext<IMessageReactionActivity> turnContext, CancellationToken cancellationToken)
143 {
144 await turnContext.SendActivityAsync(MessageFactory.Text("Message reaction received."), cancellationToken);
145 }
146
147 protected override async Task OnInstallationUpdateActivityAsync(ITurnContext<IInstallationUpdateActivity> turnContext, CancellationToken cancellationToken)
148 {
149 await turnContext.SendActivityAsync(MessageFactory.Text("Installation update received."), cancellationToken);
150 await turnContext.SendActivityAsync(MessageFactory.Text($"Send a proactive messages to `/api/notify/{turnContext.Activity.Conversation.Id}`"), cancellationToken);
151 }
152
153 protected override async Task OnInstallationUpdateAddAsync(ITurnContext<IInstallationUpdateActivity> turnContext, CancellationToken cancellationToken)
154 {
155 await turnContext.SendActivityAsync(MessageFactory.Text("Installation update Add received."), cancellationToken);
156 await turnContext.SendActivityAsync(MessageFactory.Text($"Send a proactive messages to `/api/notify/{turnContext.Activity.Conversation.Id}`"), cancellationToken);
157 }
158
159 protected override async Task<Microsoft.Bot.Builder.InvokeResponse> OnInvokeActivityAsync(ITurnContext<IInvokeActivity> turnContext, CancellationToken cancellationToken)
160 {
161 logger.LogInformation("Invoke Activity received: {Name}", turnContext.Activity.Name);
162 JObject actionValue = JObject.FromObject(turnContext.Activity.Value);
163 JObject? action = actionValue["action"] as JObject;
164 JObject? actionData = action?["data"] as JObject;
165 string? userInput = actionData?["feedback"]?.ToString();
166 //var userInput = actionValue["userInput"]?.ToString();
167
168 logger.LogInformation("Action: {Action}, User Input: {UserInput}", action, userInput);
169
170
171
172 Attachment attachment = new()
173 {
174 ContentType = "application/vnd.microsoft.card.adaptive",
175 Content = Cards.ResponseCard(userInput)
176 };
177
178 IMessageActivity card = MessageFactory.Attachment(attachment);
179 await turnContext.SendActivityAsync(card, cancellationToken);
180
181 return new Microsoft.Bot.Builder.InvokeResponse
182 {
183 Status = 200,
184 Body = new { value = "invokes from compat bot" }
185 };
186 }
187
188 protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
189 {
190 await turnContext.SendActivityAsync(MessageFactory.Text("Welcome."), cancellationToken);
191 await turnContext.SendActivityAsync(MessageFactory.Text($"Send a proactive messages to `/api/notify/{turnContext.Activity.Conversation.Id}`"), cancellationToken);
192 }
193
194 protected override Task OnMembersRemovedAsync(IList<ChannelAccount> membersRemoved, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
195 {
196 return turnContext.SendActivityAsync(MessageFactory.Text("Bye."), cancellationToken);
197 }
198
199 protected override async Task OnTeamsMeetingStartAsync(MeetingStartEventDetails meeting, ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
200 {
201 await turnContext.SendActivityAsync(MessageFactory.Text("Welcome to meeting: "), cancellationToken);
202 await turnContext.SendActivityAsync(MessageFactory.Text($"{meeting.Title} {meeting.MeetingType}"), cancellationToken);
203 }
204
205 private static async Task SendUpdateDeleteActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
206 {
207 ConversationReference cr = turnContext.Activity.GetConversationReference();
208 Activity reply = (Activity)Activity.CreateMessageActivity();
209 reply.ApplyConversationReference(cr, isIncoming: false);
210 reply.Text = "This is a proactive message sent using the Conversations API.";
211
212 ResourceResponse[] res = await turnContext.Adapter.SendActivitiesAsync(turnContext, [reply], cancellationToken);
213
214 await Task.Delay(2000, cancellationToken);
215
216 Activity updatedActivity = (Activity)Activity.CreateMessageActivity();
217 updatedActivity.ApplyConversationReference(cr, isIncoming: false);
218 updatedActivity.Id = res[0].Id;
219 updatedActivity.Text = "This message has been updated.";
220
221 await turnContext.Adapter.UpdateActivityAsync(turnContext, updatedActivity, cancellationToken);
222
223 await Task.Delay(2000, cancellationToken);
224
225 ConversationReference deleteReference = cr;
226 deleteReference.ActivityId = res[0].Id;
227 await turnContext.Adapter.DeleteActivityAsync(turnContext, deleteReference, cancellationToken);
228
229 await turnContext.SendActivityAsync(MessageFactory.Text("Proactive message sent and deleted."), cancellationToken);
230 }
231
232}
233