microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feature/pabot-httpcontext-botid

Branches

Tags

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

Clone

HTTPS

Download ZIP

core/samples/AllInvokesBot/Program.cs

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