microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
944814957fafe45d9274628ad394b4491590ede6

Branches

Tags

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

Clone

HTTPS

Download ZIP

Samples/Samples.Dialogs/Program.cs

313lines · modecode

1using System.Text.Json;
2using System.Text.Json.Serialization;
3
4using Microsoft.Teams.Apps.Activities;
5using Microsoft.Teams.Apps.Activities.Invokes;
6using Microsoft.Teams.Apps.Extensions;
7using Microsoft.Teams.Common;
8using Microsoft.Teams.Plugins.AspNetCore.DevTools.Extensions;
9using Microsoft.Teams.Plugins.AspNetCore.Extensions;
10
11var builder = WebApplication.CreateBuilder(args);
12builder.Services.AddOpenApi();
13builder.AddTeams().AddTeamsDevTools();
14
15var app = builder.Build();
16
17if (app.Environment.IsDevelopment())
18{
19 app.MapOpenApi();
20}
21
22app.UseHttpsRedirection();
23var teams = app.UseTeams();
24app.AddTab("dialog-form", "Web/dialog-form");
25
26teams.OnMessage(async context =>
27{
28 var activity = context.Activity;
29 context.Log.Info($"[MESSAGE] Received: {SanitizeForLog(activity.Text)}");
30 context.Log.Info($"[MESSAGE] From: {SanitizeForLog(activity.From?.Name ?? "unknown")}");
31
32 var card = CreateDialogLauncherCard();
33 await context.Send(card);
34});
35
36teams.OnTaskFetch(context =>
37{
38 var activity = context.Activity;
39 context.Log.Info("[TASK_FETCH] Task fetch request received");
40
41 var data = activity.Value?.Data as JsonElement?;
42 if (data == null)
43 {
44 context.Log.Info("[TASK_FETCH] No data found in the activity value");
45 return Task.FromResult(new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.MessageTask("No data found in the activity value")));
46 }
47
48 var dialogType = data.Value.TryGetProperty("opendialogtype", out var dialogTypeElement) && dialogTypeElement.ValueKind == JsonValueKind.String
49 ? dialogTypeElement.GetString()
50 : null;
51
52 context.Log.Info($"[TASK_FETCH] Dialog type: {dialogType}");
53
54 var response = dialogType switch
55 {
56 "simple_form" => CreateSimpleFormDialog(),
57 "webpage_dialog" => CreateWebpageDialog(app.Configuration, context.Log),
58 "multi_step_form" => CreateMultiStepFormDialog(),
59 "mixed_example" => CreateMixedExampleDialog(),
60 _ => new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.MessageTask("Unknown dialog type"))
61 };
62 return Task.FromResult(response);
63});
64
65teams.OnTaskSubmit(async context =>
66{
67 var activity = context.Activity;
68 context.Log.Info("[TASK_SUBMIT] Task submit request received");
69
70 var data = activity.Value?.Data as JsonElement?;
71 if (data == null)
72 {
73 context.Log.Info("[TASK_SUBMIT] No data found in the activity value");
74 return new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.MessageTask("No data found in the activity value"));
75 }
76
77 var submissionType = data.Value.TryGetProperty("submissiondialogtype", out var submissionTypeObj) && submissionTypeObj.ValueKind == JsonValueKind.String
78 ? submissionTypeObj.ToString()
79 : null;
80
81 context.Log.Info($"[TASK_SUBMIT] Submission type: {submissionType}");
82
83 string? GetFormValue(string key)
84 {
85 if (data.Value.TryGetProperty(key, out var val))
86 {
87 if (val is JsonElement element)
88 return element.GetString();
89 return val.ToString();
90 }
91 return null;
92 }
93
94 switch (submissionType)
95 {
96 case "simple_form":
97 var name = GetFormValue("name") ?? "Unknown";
98 await context.Send($"Hi {name}, thanks for submitting the form!");
99 return new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.MessageTask("Form was submitted"));
100
101 case "webpage_dialog":
102 var webName = GetFormValue("name") ?? "Unknown";
103 var email = GetFormValue("email") ?? "No email";
104 await context.Send($"Hi {webName}, thanks for submitting the form! We got that your email is {email}");
105 return new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.MessageTask("Form submitted successfully"));
106
107 case "webpage_dialog_step_1":
108 var nameStep1 = GetFormValue("name") ?? "Unknown";
109 var nextStepCardJson = $$"""
110 {
111 "type": "AdaptiveCard",
112 "version": "1.4",
113 "body": [
114 { "type": "TextBlock", "text": "Email", "size": "Large", "weight": "Bolder" },
115 { "type": "Input.Text", "id": "email", "label": "Email", "placeholder": "Enter your email", "isRequired": true }
116 ],
117 "actions": [{ "type": "Action.Submit", "title": "Submit", "data": {"submissiondialogtype": "webpage_dialog_step_2", "name": "{{nameStep1}}"} }]
118 }
119 """;
120
121 var nextStepCard = JsonSerializer.Deserialize<Microsoft.Teams.Cards.AdaptiveCard>(nextStepCardJson)
122 ?? throw new InvalidOperationException("Failed to deserialize next step card");
123
124 var nextStepTaskInfo = new Microsoft.Teams.Api.TaskModules.TaskInfo
125 {
126 Title = $"Thanks {nameStep1} - Get Email",
127 Card = new Microsoft.Teams.Api.Attachment
128 {
129 ContentType = new Microsoft.Teams.Api.ContentType("application/vnd.microsoft.card.adaptive"),
130 Content = nextStepCard
131 }
132 };
133 return new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.ContinueTask(nextStepTaskInfo));
134
135 case "webpage_dialog_step_2":
136 var nameStep2 = GetFormValue("name") ?? "Unknown";
137 var emailStep2 = GetFormValue("email") ?? "No email";
138 await context.Send($"Hi {nameStep2}, thanks for submitting the form! We got that your email is {emailStep2}");
139 return new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.MessageTask("Multi-step form completed successfully"));
140
141 default:
142 return new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.MessageTask("Unknown submission type"));
143 }
144});
145
146app.Run();
147
148static string SanitizeForLog(string? input)
149{
150 if (input == null) return "";
151 return input.Replace("\r", "").Replace("\n", "");
152}
153
154static Microsoft.Teams.Cards.AdaptiveCard CreateDialogLauncherCard()
155{
156 var card = new Microsoft.Teams.Cards.AdaptiveCard
157 {
158 Body = new List<Microsoft.Teams.Cards.CardElement>
159 {
160 new Microsoft.Teams.Cards.TextBlock("Select the examples you want to see!")
161 {
162 Size = Microsoft.Teams.Cards.TextSize.Large,
163 Weight = Microsoft.Teams.Cards.TextWeight.Bolder
164 }
165 },
166 Actions = new List<Microsoft.Teams.Cards.Action>
167 {
168 new Microsoft.Teams.Cards.TaskFetchAction(
169 Microsoft.Teams.Cards.TaskFetchAction.FromObject(new { opendialogtype = "simple_form" }))
170 {
171 Title = "Simple form test"
172 },
173 new Microsoft.Teams.Cards.TaskFetchAction(
174 Microsoft.Teams.Cards.TaskFetchAction.FromObject(new { opendialogtype = "webpage_dialog" }))
175 {
176 Title = "Webpage Dialog"
177 },
178 new Microsoft.Teams.Cards.TaskFetchAction(
179 Microsoft.Teams.Cards.TaskFetchAction.FromObject(new { opendialogtype = "multi_step_form" }))
180 {
181 Title = "Multi-step Form"
182 },
183 new Microsoft.Teams.Cards.TaskFetchAction(
184 Microsoft.Teams.Cards.TaskFetchAction.FromObject(new { opendialogtype = "mixed_example" }))
185 {
186 Title = "Mixed Example"
187 }
188 }
189 };
190
191 var serializedCard = JsonSerializer.Serialize(card, new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull });
192 Console.WriteLine($"[DEBUG] Launcher Card JSON: {serializedCard}");
193
194 return card;
195}
196
197static Microsoft.Teams.Api.TaskModules.Response CreateSimpleFormDialog()
198{
199 var cardJson = """
200 {
201 "type": "AdaptiveCard",
202 "version": "1.4",
203 "body": [
204 { "type": "TextBlock", "text": "This is a simple form", "size": "Large", "weight": "Bolder" },
205 { "type": "Input.Text", "id": "name", "label": "Name", "placeholder": "Enter your name", "isRequired": true }
206 ],
207 "actions": [{"type": "Action.Submit", "title": "Submit", "data": {"submissiondialogtype": "simple_form"}}]
208 }
209 """;
210
211 var dialogCard = JsonSerializer.Deserialize<Microsoft.Teams.Cards.AdaptiveCard>(cardJson)
212 ?? throw new InvalidOperationException("Failed to deserialize simple form card");
213
214 var serializedCard = JsonSerializer.Serialize(dialogCard);
215 Console.WriteLine($"[DEBUG] Simple Form Card JSON: {serializedCard}");
216
217 var taskInfo = new Microsoft.Teams.Api.TaskModules.TaskInfo
218 {
219 Title = "Simple Form Dialog",
220 Card = new Microsoft.Teams.Api.Attachment
221 {
222 ContentType = new Microsoft.Teams.Api.ContentType("application/vnd.microsoft.card.adaptive"),
223 Content = dialogCard
224 }
225 };
226
227 var continueTask = new Microsoft.Teams.Api.TaskModules.ContinueTask(taskInfo);
228
229 Console.WriteLine($"[DEBUG] continueTask.Value is null: {continueTask.Value == null}");
230 Console.WriteLine($"[DEBUG] continueTask.Value.Title: '{continueTask.Value?.Title}'");
231 Console.WriteLine($"[DEBUG] continueTask.Value.Card is null: {continueTask.Value?.Card == null}");
232
233 var debugOptions = new JsonSerializerOptions
234 {
235 DefaultIgnoreCondition = JsonIgnoreCondition.Never,
236 WriteIndented = true
237 };
238 var continueTaskJson = JsonSerializer.Serialize(continueTask, debugOptions);
239 Console.WriteLine($"[DEBUG] ContinueTask JSON (no ignore): {continueTaskJson}");
240
241 var response = new Microsoft.Teams.Api.TaskModules.Response(continueTask);
242 var serializedResponse = JsonSerializer.Serialize(response, debugOptions);
243 Console.WriteLine($"[DEBUG] Response JSON (no ignore): {serializedResponse}");
244
245 return response;
246}
247
248static Microsoft.Teams.Api.TaskModules.Response CreateWebpageDialog(IConfiguration configuration, Microsoft.Teams.Common.Logging.ILogger log)
249{
250 var botEndpoint = configuration["BotEndpoint"];
251 if (string.IsNullOrEmpty(botEndpoint))
252 {
253 log.Warn("No remote endpoint detected. Using webpages for dialog will not work as expected");
254 botEndpoint = "http://localhost:3978";
255 }
256 else
257 {
258 log.Info($"Using BotEndpoint: {botEndpoint}/tabs/dialog-form");
259 }
260
261 var taskInfo = new Microsoft.Teams.Api.TaskModules.TaskInfo
262 {
263 Title = "Webpage Dialog",
264 Width = new Union<int, Microsoft.Teams.Api.TaskModules.Size>(1000),
265 Height = new Union<int, Microsoft.Teams.Api.TaskModules.Size>(800),
266 Url = $"{botEndpoint}/tabs/dialog-form"
267 };
268
269 return new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.ContinueTask(taskInfo));
270}
271
272static Microsoft.Teams.Api.TaskModules.Response CreateMultiStepFormDialog()
273{
274 var cardJson = """
275 {
276 "type": "AdaptiveCard",
277 "version": "1.4",
278 "body": [
279 { "type": "TextBlock", "text": "This is a multi-step form", "size": "Large", "weight": "Bolder" },
280 { "type": "Input.Text", "id": "name", "label": "Name", "placeholder": "Enter your name", "isRequired": true }
281 ],
282 "actions": [{ "type": "Action.Submit", "title": "Submit", "data": {"submissiondialogtype": "webpage_dialog_step_1"} }]
283 }
284 """;
285
286 var dialogCard = JsonSerializer.Deserialize<Microsoft.Teams.Cards.AdaptiveCard>(cardJson)
287 ?? throw new InvalidOperationException("Failed to deserialize multi-step form card");
288
289 var taskInfo = new Microsoft.Teams.Api.TaskModules.TaskInfo
290 {
291 Title = "Multi-step Form Dialog",
292 Card = new Microsoft.Teams.Api.Attachment
293 {
294 ContentType = new Microsoft.Teams.Api.ContentType("application/vnd.microsoft.card.adaptive"),
295 Content = dialogCard
296 }
297 };
298
299 return new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.ContinueTask(taskInfo));
300}
301
302static Microsoft.Teams.Api.TaskModules.Response CreateMixedExampleDialog()
303{
304 var taskInfo = new Microsoft.Teams.Api.TaskModules.TaskInfo
305 {
306 Title = "Mixed Example (C# Sample)",
307 Width = new Union<int, Microsoft.Teams.Api.TaskModules.Size>(800),
308 Height = new Union<int, Microsoft.Teams.Api.TaskModules.Size>(600),
309 Url = "https://teams.microsoft.com/l/task/example-mixed"
310 };
311
312 return new Microsoft.Teams.Api.TaskModules.Response(new Microsoft.Teams.Api.TaskModules.ContinueTask(taskInfo));
313}
314