microsoft/teams.net

Public

mirrored from https://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
e2efe052792ba394b46f2004d1390a3cdfcd0c1e

Branches

Tags

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

Clone

HTTPS

Download ZIP

core/samples/AllInvokesBot/Program.cs

288lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using System.Text.Json;
5using System.Text.Json.Nodes;
6using AllInvokesBot;
7using Microsoft.Teams.Bot.Apps;
8using Microsoft.Teams.Bot.Apps.Handlers;
9using Microsoft.Teams.Bot.Apps.Schema;
10using Microsoft.Teams.Bot.Core.Hosting;
11
12WebApplicationBuilder webAppBuilder = WebApplication.CreateSlimBuilder(args);
13webAppBuilder.Services.AddTeamsBotApplication();
14WebApplication webApp = webAppBuilder.Build();
15
16TeamsBotApplication bot = webApp.UseBotApplication<TeamsBotApplication>();
17
18// ==================== MESSAGE - SEND SIMPLE CARD ====================
19bot.OnMessage(async (context, cancellationToken) =>
20{
21 Console.WriteLine("✓ OnMessage");
22
23 JsonObject card = Cards.CreateWelcomeCard();
24
25 TeamsAttachment attachment = TeamsAttachment.CreateBuilder()
26 .WithAdaptiveCard(card)
27 .Build();
28
29 await context.SendActivityAsync(new MessageActivity([attachment]), cancellationToken);
30});
31
32// ==================== ADAPTIVE CARD ACTION ====================
33bot.OnAdaptiveCardAction(async (context, cancellationToken) =>
34{
35 Console.WriteLine("✓ OnAdaptiveCardAction");
36 AdaptiveCardActionValue? value = context.Activity.Value;
37 AdaptiveCardAction? action = value?.Action;
38 string? verb = action?.Verb;
39 Dictionary<string, object>? data = action?.Data;
40
41 Console.WriteLine($" Verb: {verb}");
42 Console.WriteLine($" Data: {JsonSerializer.Serialize(data)}");
43
44 // Handle file upload request
45 if (verb == "requestFileUpload")
46 {
47 JsonObject fileConsentCard = Cards.CreateFileConsentCard();
48 TeamsAttachment fileConsentCardResponse = TeamsAttachment.CreateBuilder()
49 .WithContent(fileConsentCard).WithContentType(AttachmentContentType.FileConsentCard)
50 .WithName("file_consent.json").Build();
51 await context.SendActivityAsync(new MessageActivity([fileConsentCardResponse]), cancellationToken);
52
53 return AdaptiveCardResponse.CreateMessageResponse("File Consent requested!");
54 }
55
56 string? message = data != null && data.TryGetValue("message", out object? msgValue) ? msgValue?.ToString() : null;
57
58 JsonObject adaptiveActionCard = Cards.CreateAdaptiveActionResponseCard(verb, message);
59 TeamsAttachment adaptiveActionCardResponse = TeamsAttachment.CreateBuilder().WithAdaptiveCard(adaptiveActionCard).Build();
60 await context.SendActivityAsync(new MessageActivity([adaptiveActionCardResponse]), cancellationToken);
61
62 return AdaptiveCardResponse.CreateMessageResponse("Action submitted!");
63});
64
65// ==================== TASK MODULE - FETCH ====================
66bot.OnTaskFetch(async (context, cancellationToken) =>
67{
68 Console.WriteLine("✓ OnTaskFetch");
69 TeamsAttachment taskModuleCardResponse = TeamsAttachment.CreateBuilder()
70 .WithAdaptiveCard(Cards.CreateTaskModuleCard()).Build();
71 return TaskModuleResponse.CreateBuilder()
72 .WithType(TaskModuleResponseType.Continue)
73 .WithTitle("Task")
74 .WithHeight("medium")
75 .WithWidth("medium")
76 .WithCard(taskModuleCardResponse)
77 .Build();
78
79});
80
81// ==================== TASK MODULE - SUBMIT ====================
82bot.OnTaskSubmit(async (context, cancellationToken) =>
83{
84 Console.WriteLine("✓ OnTaskSubmit");
85 return TaskModuleResponse.CreateBuilder()
86 .WithType(TaskModuleResponseType.Message)
87 .WithMessage("Done")
88 .Build();
89});
90
91// ==================== FILE CONSENT ====================
92bot.OnFileConsent(async (context, cancellationToken) =>
93{
94 Console.WriteLine("✓ OnFileConsent");
95
96 FileConsentValue? value = context.Activity.Value;
97 string? action = value?.Action;
98 FileUploadInfo? uploadInfo = value?.UploadInfo;
99 object? consentContext = value?.Context;
100
101 if (action == "accept")
102 {
103 Console.WriteLine($" File accepted!");
104
105 // Upload the file
106 string? uploadUrl = uploadInfo?.UploadUrl?.ToString();
107 string? fileName = uploadInfo?.Name;
108 string? contentUrl = uploadInfo?.ContentUrl?.ToString();
109 string? uniqueId = uploadInfo?.UniqueId;
110
111 if (uploadUrl != null && contentUrl != null)
112 {
113 // Create sample file content
114 string fileContent = "This is a sample file uploaded via file consent!";
115 byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(fileContent);
116 int fileSize = fileBytes.Length;
117
118 using HttpClient httpClient = new();
119 using ByteArrayContent content = new(fileBytes);
120 content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
121 content.Headers.ContentRange = new System.Net.Http.Headers.ContentRangeHeaderValue(0, fileSize - 1, fileSize);
122
123 try
124 {
125 HttpResponseMessage uploadResponse = await httpClient.PutAsync(uploadUrl, content, cancellationToken);
126 Console.WriteLine($" Upload Status: {uploadResponse.StatusCode}");
127
128 if (uploadResponse.IsSuccessStatusCode)
129 {
130 JsonObject fileInfoContent = Cards.CreateFileInfoCard(uniqueId, uploadInfo?.FileType);
131
132 TeamsAttachment fileUploadResponse = TeamsAttachment.CreateBuilder()
133 .WithName(fileName)
134 .WithContentType(AttachmentContentType.FileInfoCard)
135 .WithContentUrl(contentUrl != null ? new Uri(contentUrl) : null)
136 .WithContent(fileInfoContent).Build();
137
138 await context.SendActivityAsync(new MessageActivity([fileUploadResponse]), cancellationToken);
139 }
140 else
141 {
142 Console.WriteLine($" File upload failed: {await uploadResponse.Content.ReadAsStringAsync(cancellationToken)}");
143 }
144 }
145 catch (Exception ex)
146 {
147 Console.WriteLine($" File upload error: {ex.Message}");
148 }
149 }
150 }
151 else if (action == "decline")
152 {
153 Console.WriteLine($" File declined!");
154 Console.WriteLine($" Context: {JsonSerializer.Serialize(consentContext)}");
155 }
156
157 return AdaptiveCardResponse.CreateBuilder()
158 .WithStatusCode(200)
159 .Build();
160});
161
162/*
163// ==================== EXECUTE ACTION ====================
164bot.OnExecuteAction(async (context, cancellationToken) =>
165{
166 Console.WriteLine("✓ OnExecuteAction");
167
168 var responseBody = new JsonObject
169 {
170 ["status"] = "completed"
171 };
172
173 return new CoreInvokeResponse(200, responseBody);
174});
175
176// ==================== HANDOFF ====================
177bot.OnHandoff(async (context, cancellationToken) =>
178{
179 Console.WriteLine("✓ OnHandoff");
180 return new CoreInvokeResponse(200);
181});
182
183// ==================== SEARCH ====================
184bot.OnSearch(async (context, cancellationToken) =>
185{
186 Console.WriteLine("✓ OnSearch");
187
188 var responseBody = new JsonObject
189 {
190 ["results"] = new JsonArray
191 {
192 new JsonObject
193 {
194 ["id"] = "1",
195 ["title"] = "Result"
196 }
197 }
198 };
199
200 return new CoreInvokeResponse(200, responseBody);
201});
202
203// ==================== MESSAGE SUBMIT ACTION ====================
204bot.OnMessageSubmitAction(async (context, cancellationToken) =>
205{
206 Console.WriteLine("✓ OnMessageSubmitAction");
207
208 var data = context.Activity.Value;
209 Console.WriteLine($" Data: {System.Text.Json.JsonSerializer.Serialize(data)}");
210
211 // Extract data fields
212 var jsonData = System.Text.Json.JsonSerializer.Deserialize<System.Text.Json.JsonElement>(
213 System.Text.Json.JsonSerializer.Serialize(data));
214
215 string? action = jsonData.TryGetProperty("action", out var a) ? a.GetString() : "unknown";
216 string? value = jsonData.TryGetProperty("value", out var v) ? v.GetString() : "no value";
217
218 Console.WriteLine($" Action: {action}");
219 Console.WriteLine($" Value: {value}");
220
221 var responseBody = new JsonObject
222 {
223 ["statusCode"] = 200,
224 ["type"] = "application/vnd.microsoft.activity.message",
225 ["value"] = $"Message action '{action}' submitted! Value: {value}"
226 };
227
228 return new CoreInvokeResponse(200, responseBody);
229});
230
231// ==================== CONFIG FETCH ====================
232bot.OnConfigFetch(async (context, cancellationToken) =>
233{
234 Console.WriteLine("✓ OnConfigFetch");
235
236 var card = new
237 {
238 contentType = AttachmentContentType.AdaptiveCard,
239 content = new
240 {
241 type = "AdaptiveCard",
242 version = "1.4",
243 body = new object[]
244 {
245 new { type = "TextBlock", text = "Extension Settings", size = "large", weight = "bolder" },
246 new { type = "TextBlock", text = "Configure your messaging extension settings below:", wrap = true },
247 new { type = "Input.Text", id = "apiKey", label = "API Key", placeholder = "Enter your API key" },
248 new { type = "Input.Toggle", id = "enableNotifications", label = "Enable Notifications", value = "true" }
249 },
250 actions = new object[]
251 {
252 new { type = "Action.Submit", title = "Save Settings" }
253 }
254 }
255 };
256
257 var response = TaskModuleResponse.CreateBuilder()
258 .WithType(TaskModuleResponseType.Continue)
259 .WithTitle("Configure Messaging Extension")
260 .WithHeight(TaskModuleSize.Medium)
261 .WithWidth(TaskModuleSize.Medium)
262 .WithCard(card)
263 .Build();
264
265 return new CoreInvokeResponse<MessageExtensionResponse>(200, response);
266});
267
268// ==================== CONFIG SUBMIT ====================
269bot.OnConfigSubmit(async (context, cancellationToken) =>
270{
271 Console.WriteLine("✓ OnConfigSubmit");
272
273 var data = context.Activity.Value;
274 Console.WriteLine($" Config data: {System.Text.Json.JsonSerializer.Serialize(data)}");
275
276 // In a real app, you would save these settings to a database
277 // associated with the user/team
278
279 var response = TaskModuleResponse.CreateBuilder()
280 .WithType(TaskModuleResponseType.Message)
281 .WithMessage("Settings saved successfully!")
282 .Build();
283
284 return new CoreInvokeResponse<MessageExtensionResponse>(200, response);
285});
286*/
287
288webApp.Run();
289