microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feature/user-agent-header

Branches

Tags

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

Clone

HTTPS

Download ZIP

core/src/Microsoft.Teams.Bot.Apps/Schema/TeamsActivity.cs

214lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using System.Text;
5using System.Text.Json;
6using System.Text.Json.Serialization;
7using System.Text.Json.Serialization.Metadata;
8using Microsoft.Teams.Bot.Apps.Schema.Entities;
9using Microsoft.Teams.Bot.Core.Schema;
10
11namespace Microsoft.Teams.Bot.Apps.Schema;
12
13/// <summary>
14/// Teams Activity schema.
15/// </summary>
16[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2227: Collection Properties should be read only", Justification = "<Pending>")]
17public class TeamsActivity : CoreActivity
18{
19 /// <summary>
20 /// Creates a new instance of the TeamsActivity class from the specified Activity object.
21 /// </summary>
22 /// <param name="activity">The Activity instance to convert. Cannot be null.</param>
23 /// <returns>A TeamsActivity object that represents the specified Activity.</returns>
24 public static TeamsActivity FromActivity(CoreActivity activity)
25 {
26 ArgumentNullException.ThrowIfNull(activity);
27
28 return TeamsActivityType.ActivityDeserializerMap.TryGetValue(activity.Type, out var factory)
29 ? factory.FromActivity(activity)
30 : new TeamsActivity(activity); // Fallback to base type
31 }
32
33 /// <summary>
34 /// Creates a new instance of the TeamsActivity class from the specified Activity object.
35 /// </summary>
36 /// <param name="json"></param>
37 /// <returns></returns>
38 public static new TeamsActivity FromJsonString(string json)
39 {
40 string? type = null;
41 var jsonBytes = Encoding.UTF8.GetBytes(json);
42 var reader = new Utf8JsonReader(jsonBytes);
43
44 while (reader.Read())
45 {
46 if (reader.TokenType == JsonTokenType.PropertyName &&
47 reader.ValueTextEquals("type"u8))
48 {
49 reader.Read();
50 type = reader.GetString();
51 break;
52 }
53 }
54
55 return type != null && TeamsActivityType.ActivityDeserializerMap.TryGetValue(type, out var factory)
56 ? factory.FromJson(json)
57 : FromJsonString(json, TeamsActivityJsonContext.Default.TeamsActivity);
58 }
59
60 /// <summary>
61 /// Creates a new instance of the specified activity type from JSON string.
62 /// </summary>
63 /// <typeparam name="T">The expected activity type.</typeparam>
64 /// <param name="json">The JSON string to deserialize.</param>
65 /// <param name="typeInfo">The JSON type info for deserialization.</param>
66 /// <returns>An activity of type T.</returns>
67 public static T FromJsonString<T>(string json, JsonTypeInfo<T> typeInfo) where T : TeamsActivity
68 {
69 T activity = JsonSerializer.Deserialize(json, typeInfo)!;
70 activity.Rebase();
71 return activity;
72 }
73
74
75 /// <summary>
76 /// Overrides the ToJson method to serialize the TeamsActivity object to a JSON string.
77 /// </summary>
78 /// <returns></returns>
79 public new string ToJson()
80 => ToJson(TeamsActivityJsonContext.Default.TeamsActivity);
81
82 /// <summary>
83 /// Constructor with type parameter.
84 /// </summary>
85 /// <param name="type"></param>
86 protected TeamsActivity(string type) : this()
87 {
88 Type = type;
89 }
90
91 /// <summary>
92 /// Default constructor.
93 /// </summary>
94 [JsonConstructor]
95 public TeamsActivity()
96 {
97 From = new TeamsConversationAccount();
98 Recipient = new TeamsConversationAccount();
99 Conversation = new TeamsConversation();
100 }
101
102 /// <summary>
103 /// Protected constructor to create TeamsActivity from CoreActivity.
104 /// Allows derived classes to call via base(activity).
105 /// </summary>
106 /// <param name="activity">The CoreActivity to convert.</param>
107 protected TeamsActivity(CoreActivity activity) : base(activity)
108 {
109 ArgumentNullException.ThrowIfNull(activity);
110 // Convert base types to Teams-specific types
111 if (activity.ChannelData is not null)
112 {
113 ChannelData = new TeamsChannelData(activity.ChannelData);
114 }
115 From = new TeamsConversationAccount(activity.From);
116 Recipient = new TeamsConversationAccount(activity.Recipient);
117 Conversation = new TeamsConversation(activity.Conversation);
118 Attachments = TeamsAttachment.FromJArray(activity.Attachments);
119 Entities = EntityList.FromJsonArray(activity.Entities);
120
121 Rebase();
122 }
123
124 /// <summary>
125 /// Resets shadow properties in base class
126 /// </summary>
127 /// <returns></returns>
128 internal TeamsActivity Rebase()
129 {
130 base.Attachments = this.Attachments?.ToJsonArray();
131 base.Entities = this.Entities?.ToJsonArray();
132
133 return this;
134 }
135
136
137 /// <summary>
138 /// Gets or sets the account information for the sender of the Teams conversation.
139 /// </summary>
140 [JsonPropertyName("from")]
141 public new TeamsConversationAccount From
142 {
143 get => (base.From as TeamsConversationAccount) ?? new TeamsConversationAccount(base.From);
144 set => base.From = value;
145 }
146
147 /// <summary>
148 /// Gets or sets the account information for the recipient of the Teams conversation.
149 /// </summary>
150 [JsonPropertyName("recipient")]
151 public new TeamsConversationAccount Recipient
152 {
153 get => (base.Recipient as TeamsConversationAccount) ?? new TeamsConversationAccount(base.Recipient);
154 set => base.Recipient = value;
155 }
156
157 /// <summary>
158 /// Gets or sets the conversation information for the Teams conversation.
159 /// </summary>
160 [JsonPropertyName("conversation")]
161 public new TeamsConversation Conversation
162 {
163 get => (base.Conversation as TeamsConversation) ?? new TeamsConversation(base.Conversation);
164 set => base.Conversation = value;
165 }
166
167 /// <summary>
168 /// Gets or sets the Teams-specific channel data associated with this activity.
169 /// </summary>
170 [JsonPropertyName("channelData")]
171 public new TeamsChannelData? ChannelData
172 {
173 get => base.ChannelData as TeamsChannelData;
174 set => base.ChannelData = value;
175 }
176
177 /// <summary>
178 /// Gets or sets the entities specific to Teams.
179 /// </summary>
180 [JsonPropertyName("entities")] public new EntityList? Entities { get; set; }
181
182 /// <summary>
183 /// Attachments specific to Teams.
184 /// </summary>
185 [JsonPropertyName("attachments")] public new IList<TeamsAttachment>? Attachments { get; set; }
186
187 /// <summary>
188 /// Adds an entity to the activity's Entities collection.
189 /// </summary>
190 /// <param name="entity"></param>
191 /// <returns></returns>
192 public TeamsActivity AddEntity(Entity entity)
193 {
194 // TODO: Pick up nuances about entities.
195 // For eg, there can only be 1 single MessageEntity
196 Entities ??= [];
197 Entities.Add(entity);
198 return this;
199 }
200
201 /// <summary>
202 /// Creates a new TeamsActivityBuilder instance for building a TeamsActivity with a fluent API.
203 /// </summary>
204 /// <returns>A new TeamsActivityBuilder instance.</returns>
205 public static new TeamsActivityBuilder CreateBuilder() => new();
206
207 /// <summary>
208 /// Creates a new TeamsActivityBuilder instance initialized with the specified TeamsActivity.
209 /// </summary>
210 /// <param name="activity"></param>
211 /// <returns></returns>
212 public static TeamsActivityBuilder CreateBuilder(TeamsActivity activity) => new(activity);
213
214}
215