Skip to content

Commit e4060ec

Browse files
authored
Merge branch 'main' into copilot/update-samples-to-minimal-apis
2 parents b87ed68 + b026f9b commit e4060ec

File tree

13 files changed

+549
-21
lines changed

13 files changed

+549
-21
lines changed

Libraries/Microsoft.Teams.Api/Activities/Events/MeetingEndActivity.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,35 @@ public class MeetingEndActivityValue
3131
/// <summary>
3232
/// The meeting's Id, encoded as a BASE64 string.
3333
/// </summary>
34-
[JsonPropertyName("id")]
34+
[JsonPropertyName("Id")]
3535
[JsonPropertyOrder(0)]
3636
public required string Id { get; set; }
3737

3838
/// <summary>
3939
/// The meeting's type.
4040
/// </summary>
41-
[JsonPropertyName("meetingType")]
41+
[JsonPropertyName("MeetingType")]
4242
[JsonPropertyOrder(1)]
4343
public required string MeetingType { get; set; }
4444

4545
/// <summary>
4646
/// The URL used to join the meeting.
4747
/// </summary>
48-
[JsonPropertyName("joinUrl")]
48+
[JsonPropertyName("JoinUrl")]
4949
[JsonPropertyOrder(2)]
5050
public required string JoinUrl { get; set; }
5151

5252
/// <summary>
5353
/// The title of the meeting.
5454
/// </summary>
55-
[JsonPropertyName("title")]
55+
[JsonPropertyName("Title")]
5656
[JsonPropertyOrder(3)]
5757
public required string Title { get; set; }
5858

5959
/// <summary>
6060
/// Timestamp for meeting end, in UTC.
6161
/// </summary>
62-
[JsonPropertyName("endTime")]
62+
[JsonPropertyName("EndTime")]
6363
[JsonPropertyOrder(4)]
6464
public required DateTime EndTime { get; set; }
6565
}

Libraries/Microsoft.Teams.Api/Activities/Events/MeetingParticipantLeaveActivity.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,6 @@ public class Meeting
6363

6464
[JsonPropertyName("role")]
6565
[JsonPropertyOrder(1)]
66-
public required Role Role { get; set; }
66+
public Role? Role { get; set; }
6767
}
6868
}

Libraries/Microsoft.Teams.Api/Activities/Events/MeetingStartActivity.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,35 @@ public class MeetingStartActivityValue
3131
/// <summary>
3232
/// The meeting's Id, encoded as a BASE64 string.
3333
/// </summary>
34-
[JsonPropertyName("id")]
34+
[JsonPropertyName("Id")]
3535
[JsonPropertyOrder(0)]
3636
public required string Id { get; set; }
3737

3838
/// <summary>
3939
/// The meeting's type.
4040
/// </summary>
41-
[JsonPropertyName("meetingType")]
41+
[JsonPropertyName("MeetingType")]
4242
[JsonPropertyOrder(1)]
4343
public required string MeetingType { get; set; }
4444

4545
/// <summary>
4646
/// The URL used to join the meeting.
4747
/// </summary>
48-
[JsonPropertyName("joinUrl")]
48+
[JsonPropertyName("JoinUrl")]
4949
[JsonPropertyOrder(2)]
5050
public required string JoinUrl { get; set; }
5151

5252
/// <summary>
5353
/// The title of the meeting.
5454
/// </summary>
55-
[JsonPropertyName("title")]
55+
[JsonPropertyName("Title")]
5656
[JsonPropertyOrder(3)]
5757
public required string Title { get; set; }
5858

5959
/// <summary>
6060
/// Timestamp for meeting start, in UTC.
6161
/// </summary>
62-
[JsonPropertyName("startTime")]
62+
[JsonPropertyName("StartTime")]
6363
[JsonPropertyOrder(4)]
6464
public required DateTime StartTime { get; set; }
6565
}

Microsoft.Teams.sln

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Teams.Plugins.Ext
8383
EndProject
8484
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.AI", "Samples\Samples.AI\Samples.AI.csproj", "{BCD1AE81-8D5D-461F-AB63-7C0E5882F89B}"
8585
EndProject
86+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Meetings", "Samples\Samples.Meetings\Samples.Meetings.csproj", "{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}"
87+
EndProject
8688
Global
8789
GlobalSection(SolutionConfigurationPlatforms) = preSolution
8890
Debug|Any CPU = Debug|Any CPU
@@ -501,6 +503,18 @@ Global
501503
{BCD1AE81-8D5D-461F-AB63-7C0E5882F89B}.Release|x64.Build.0 = Release|Any CPU
502504
{BCD1AE81-8D5D-461F-AB63-7C0E5882F89B}.Release|x86.ActiveCfg = Release|Any CPU
503505
{BCD1AE81-8D5D-461F-AB63-7C0E5882F89B}.Release|x86.Build.0 = Release|Any CPU
506+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
507+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Debug|Any CPU.Build.0 = Debug|Any CPU
508+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Debug|x64.ActiveCfg = Debug|Any CPU
509+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Debug|x64.Build.0 = Debug|Any CPU
510+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Debug|x86.ActiveCfg = Debug|Any CPU
511+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Debug|x86.Build.0 = Debug|Any CPU
512+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Release|Any CPU.ActiveCfg = Release|Any CPU
513+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Release|Any CPU.Build.0 = Release|Any CPU
514+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Release|x64.ActiveCfg = Release|Any CPU
515+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Release|x64.Build.0 = Release|Any CPU
516+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Release|x86.ActiveCfg = Release|Any CPU
517+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514}.Release|x86.Build.0 = Release|Any CPU
504518
EndGlobalSection
505519
GlobalSection(SolutionProperties) = preSolution
506520
HideSolutionNode = FALSE
@@ -543,6 +557,7 @@ Global
543557
{C4DDD35D-CCDC-4EBB-94F6-F2E4E4406AA8} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
544558
{783599E3-9841-4377-9590-4A5D9EC0023D} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
545559
{BCD1AE81-8D5D-461F-AB63-7C0E5882F89B} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
560+
{FCEEF7AD-1E78-4615-8BE4-7B46B034A514} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
546561
EndGlobalSection
547562
GlobalSection(ExtensibilityGlobals) = postSolution
548563
SolutionGuid = {378263F2-C2B2-4DB1-83CF-CA228AF03ABF}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
using System.Diagnostics;
2+
3+
using Microsoft.Teams.Api.Activities;
4+
using Microsoft.Teams.Api.Activities.Events;
5+
using Microsoft.Teams.Apps;
6+
using Microsoft.Teams.Apps.Activities;
7+
using Microsoft.Teams.Apps.Activities.Events;
8+
using Microsoft.Teams.Apps.Annotations;
9+
using Microsoft.Teams.Cards;
10+
using Microsoft.Teams.Common.Logging;
11+
using Microsoft.Teams.Plugins.AspNetCore.Extensions;
12+
13+
var builder = WebApplication.CreateBuilder(args);
14+
15+
var appBuilder = App.Builder()
16+
.AddLogger(new ConsoleLogger(level: Microsoft.Teams.Common.Logging.LogLevel.Debug));
17+
18+
builder.AddTeams(appBuilder);
19+
20+
var app = builder.Build();
21+
var teams = app.UseTeams();
22+
23+
teams.Use(async context =>
24+
{
25+
var start = DateTime.UtcNow;
26+
try
27+
{
28+
await context.Next();
29+
}
30+
catch(Exception e)
31+
{
32+
context.Log.Error(e);
33+
context.Log.Error("error occurred during activity processing");
34+
}
35+
context.Log.Debug($"request took {(DateTime.UtcNow - start).TotalMilliseconds}ms");
36+
});
37+
38+
teams.OnMeetingStart(async context =>
39+
{
40+
var activity = context.Activity.Value;
41+
var startTime = activity.StartTime.ToLocalTime();
42+
AdaptiveCard card = new AdaptiveCard
43+
{
44+
Schema = "http://adaptivecards.io/schemas/adaptive-card.json",
45+
Body = new List<CardElement>
46+
{
47+
new TextBlock($"'{activity.Title}' has started at {startTime}.")
48+
{
49+
Wrap = true,
50+
Weight = TextWeight.Bolder
51+
}
52+
},
53+
Actions = new List<Microsoft.Teams.Cards.Action>
54+
{
55+
new OpenUrlAction(activity.JoinUrl)
56+
{
57+
Title = "Join the meeting",
58+
}
59+
}
60+
};
61+
await context.Send(card);
62+
});
63+
64+
teams.OnMeetingEnd(async context =>
65+
{
66+
var activity = context.Activity.Value;
67+
var endTime = activity.EndTime.ToLocalTime();
68+
69+
AdaptiveCard card = new AdaptiveCard
70+
{
71+
Schema = "http://adaptivecards.io/schemas/adaptive-card.json",
72+
Body = new List<CardElement>
73+
{
74+
new TextBlock($"'{activity.Title}' has ended at {endTime}.")
75+
{
76+
Wrap = true,
77+
Weight = TextWeight.Bolder
78+
}
79+
}
80+
};
81+
82+
await context.Send(card);
83+
});
84+
85+
teams.OnMeetingJoin(async context =>
86+
{
87+
var activity = context.Activity.Value;
88+
var member = activity.Members[0].User.Name;
89+
var role = activity.Members[0].Meeting.Role;
90+
91+
AdaptiveCard card = new AdaptiveCard
92+
{
93+
Schema = "http://adaptivecards.io/schemas/adaptive-card.json",
94+
Body = new List<CardElement>
95+
{
96+
new TextBlock($"{member} has joined the meeting as {role}.")
97+
{
98+
Wrap = true,
99+
Weight = TextWeight.Bolder
100+
}
101+
}
102+
};
103+
104+
await context.Send(card);
105+
106+
});
107+
108+
teams.OnMeetingLeave(async context =>
109+
{
110+
var activity = context.Activity.Value;
111+
var member = activity.Members[0].User.Name;
112+
113+
AdaptiveCard card = new AdaptiveCard
114+
{
115+
Schema = "http://adaptivecards.io/schemas/adaptive-card.json",
116+
Body = new List<CardElement>
117+
{
118+
new TextBlock($"{member} has left the meeting.")
119+
{
120+
Wrap = true,
121+
Weight = TextWeight.Bolder
122+
}
123+
}
124+
};
125+
126+
await context.Send(card);
127+
});
128+
129+
teams.OnMessage(async context =>
130+
{
131+
await context.Typing();
132+
await context.Send($"you said '{context.Activity.Text}'");
133+
});
134+
135+
app.Run();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"http": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"launchBrowser": true,
8+
"applicationUrl": "http://localhost:3978",
9+
"environmentVariables": {
10+
"ASPNETCORE_ENVIRONMENT": "Development"
11+
}
12+
}
13+
}
14+
}

Samples/Samples.Meetings/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
## Meetings Sample
2+
3+
This sample demonstrates how to handle real-time updates for meeting events and meeting participant events.
4+
5+
### Manifest Requirements
6+
7+
There are a few requirements in the Teams app manifest (manifest.json) to support these events.
8+
9+
1) The `scopes` section must include `team`, and `groupChat`:
10+
11+
```csharp
12+
"bots": [
13+
{
14+
"botId": "",
15+
"scopes": [
16+
"team",
17+
"personal",
18+
"groupChat"
19+
],
20+
"isNotificationOnly": false
21+
}
22+
]
23+
```
24+
25+
2) In the authorization section, make sure to specify the following resource-specific permissions:
26+
27+
```csharp
28+
"authorization":{
29+
"permissions":{
30+
"resourceSpecific":[
31+
{
32+
"name":"OnlineMeetingParticipant.Read.Chat",
33+
"type":"Application"
34+
},
35+
{
36+
"name":"ChannelMeeting.ReadBasic.Group",
37+
"type":"Application"
38+
},
39+
{
40+
"name":"OnlineMeeting.ReadBasic.Chat",
41+
"type":"Application"
42+
}
43+
]
44+
}
45+
}
46+
```
47+
48+
### Teams Developer Portal: Bot Configuration
49+
50+
For your Bot, make sure the [Meeting Event Subscriptions](https://learn.microsoft.com/en-us/microsoftteams/platform/apps-in-teams-meetings/meeting-apps-apis?branch=pr-en-us-8455&tabs=channel-meeting%2Cguest-user%2Cone-on-one-call%2Cdotnet3%2Cdotnet2%2Cdotnet%2Cparticipant-join-event%2Cparticipant-join-event1#receive-meeting-participant-events) are checked.
51+
This enables you to receive the Meeting Participant events.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<ProjectReference Include="..\..\Libraries\Microsoft.Teams.Plugins\Microsoft.Teams.Plugins.AspNetCore\Microsoft.Teams.Plugins.AspNetCore.csproj" />
11+
</ItemGroup>
12+
13+
</Project>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"Teams": {
9+
"ClientId": "",
10+
"ClientSecret": "",
11+
"TenantId": "",
12+
},
13+
"AllowedHosts": "*"
14+
}

0 commit comments

Comments
 (0)