Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.

Commit c657733

Browse files
committed
Teams Meeting API
1 parent 5a406bf commit c657733

File tree

8 files changed

+376
-10
lines changed

8 files changed

+376
-10
lines changed

libraries/bot-builder/src/main/java/com/microsoft/bot/builder/teams/TeamsInfo.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.microsoft.bot.schema.teams.TeamsChannelAccount;
2222
import com.microsoft.bot.schema.teams.TeamsChannelData;
2323
import com.microsoft.bot.schema.teams.TeamsPagedMembersResult;
24+
import com.microsoft.bot.schema.teams.TeamsMeetingParticipant;
2425
import org.apache.commons.lang3.StringUtils;
2526

2627
import java.util.ArrayList;
@@ -209,6 +210,65 @@ public static CompletableFuture<TeamsPagedMembersResult> getPagedMembers(
209210
return getPagedMembers(getConnectorClient(turnContext), conversationId, continuationToken);
210211
}
211212

213+
/**
214+
* Gets the details for the given meeting participant. This only works in teams meeting scoped conversations.
215+
* @param turnContext The TurnContext that the meeting, participant, and tenant ids are pulled from.
216+
* @return TeamsParticipantChannelAccount
217+
*/
218+
public static CompletableFuture<TeamsMeetingParticipant> getMeetingParticipant(
219+
TurnContext turnContext
220+
) {
221+
return getMeetingParticipant(turnContext, null, null, null);
222+
}
223+
224+
/**
225+
* Gets the details for the given meeting participant. This only works in teams meeting scoped conversations.
226+
* @param turnContext Turn context.
227+
* @param meetingId The meeting id, or null to get from Activities TeamsChannelData
228+
* @param participantId The participant id, or null to get from Activities TeamsChannelData
229+
* @param tenantId The tenant id, or null to get from Activities TeamsChannelData
230+
* @return Team participant channel account.
231+
*/
232+
public static CompletableFuture<TeamsMeetingParticipant> getMeetingParticipant(
233+
TurnContext turnContext,
234+
String meetingId,
235+
String participantId,
236+
String tenantId
237+
) {
238+
if (StringUtils.isEmpty(meetingId)) {
239+
meetingId = turnContext.getActivity().teamsGetMeetingInfo() != null
240+
? turnContext.getActivity().teamsGetMeetingInfo().getId()
241+
: null;
242+
}
243+
if (StringUtils.isEmpty(meetingId)) {
244+
return illegalArgument("TeamsInfo.getMeetingParticipant: method requires a meetingId");
245+
}
246+
247+
if (StringUtils.isEmpty(participantId)) {
248+
participantId = turnContext.getActivity().getFrom() != null
249+
? turnContext.getActivity().getFrom().getAadObjectId()
250+
: null;
251+
}
252+
if (StringUtils.isEmpty(participantId)) {
253+
return illegalArgument("TeamsInfo.getMeetingParticipant: method requires a participantId");
254+
}
255+
256+
if (StringUtils.isEmpty(tenantId)) {
257+
tenantId = turnContext.getActivity().teamsGetChannelData() != null
258+
? turnContext.getActivity().teamsGetChannelData().getTenant().getId()
259+
: null;
260+
}
261+
if (StringUtils.isEmpty(tenantId)) {
262+
return illegalArgument("TeamsInfo.getMeetingParticipant: method requires a tenantId");
263+
}
264+
265+
return getTeamsConnectorClient(turnContext).getTeams().fetchParticipant(
266+
meetingId,
267+
participantId,
268+
tenantId
269+
);
270+
}
271+
212272
private static CompletableFuture<List<TeamsChannelAccount>> getMembers(
213273
ConnectorClient connectorClient,
214274
String conversationId

libraries/bot-connector/src/main/java/com/microsoft/bot/connector/rest/RestTeamsOperations.java

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
import com.microsoft.bot.rest.ServiceResponse;
1212
import com.microsoft.bot.schema.teams.ConversationList;
1313
import com.microsoft.bot.schema.teams.TeamDetails;
14+
import com.microsoft.bot.schema.teams.TeamsMeetingParticipant;
1415
import okhttp3.ResponseBody;
1516
import retrofit2.Response;
1617
import retrofit2.Retrofit;
18+
import retrofit2.http.GET;
1719
import retrofit2.http.Header;
1820
import retrofit2.http.Headers;
1921
import retrofit2.http.POST;
@@ -22,6 +24,7 @@
2224
import java.io.IOException;
2325
import java.net.HttpURLConnection;
2426
import java.util.concurrent.CompletableFuture;
27+
import retrofit2.http.Query;
2528

2629
/**
2730
* msrest impl of TeamsOperations.
@@ -117,6 +120,44 @@ private ServiceResponse<TeamDetails> fetchTeamDetailsDelegate(
117120
.build(response);
118121
}
119122

123+
/**
124+
* Fetches Teams meeting participant details.
125+
* @param meetingId Teams meeting id
126+
* @param participantId Teams meeting participant id
127+
* @param tenantId Teams meeting tenant id
128+
* @return TeamsParticipantChannelAccount
129+
*/
130+
public CompletableFuture<TeamsMeetingParticipant> fetchParticipant(
131+
String meetingId,
132+
String participantId,
133+
String tenantId
134+
) {
135+
return service.fetchParticipant(
136+
meetingId, participantId, tenantId, client.getAcceptLanguage(), client.getUserAgent()
137+
)
138+
.thenApply(responseBodyResponse -> {
139+
try {
140+
return fetchParticipantDelegate(responseBodyResponse).body();
141+
} catch (ErrorResponseException e) {
142+
throw e;
143+
} catch (Throwable t) {
144+
throw new ErrorResponseException("fetchParticipant", responseBodyResponse);
145+
}
146+
});
147+
}
148+
149+
private ServiceResponse<TeamsMeetingParticipant> fetchParticipantDelegate(
150+
Response<ResponseBody> response
151+
) throws ErrorResponseException, IOException, IllegalArgumentException {
152+
return client.restClient()
153+
.responseBuilderFactory()
154+
.<TeamsMeetingParticipant, ErrorResponseException>newInstance(client.serializerAdapter())
155+
.register(HttpURLConnection.HTTP_OK, new TypeToken<TeamsMeetingParticipant>() {
156+
}.getType())
157+
.registerError(ErrorResponseException.class)
158+
.build(response);
159+
}
160+
120161
/**
121162
* The interface defining all the services for TeamsOperations to be used by
122163
* Retrofit to perform actually REST calls.
@@ -140,6 +181,16 @@ CompletableFuture<Response<ResponseBody>> fetchTeamDetails(
140181
@Header("accept-language") String acceptLanguage,
141182
@Header("User-Agent") String userAgent
142183
);
143-
}
144184

185+
@Headers({ "Content-Type: application/json; charset=utf-8",
186+
"x-ms-logging-context: com.microsoft.bot.schema.Teams fetchParticipant" })
187+
@GET("v1/meetings/{meetingId}/participants/{participantId}")
188+
CompletableFuture<Response<ResponseBody>> fetchParticipant(
189+
@Path("meetingId") String meetingId,
190+
@Path("participantId") String participantId,
191+
@Query("tenantId") String tenantId,
192+
@Header("accept-language") String acceptLanguage,
193+
@Header("User-Agent") String userAgent
194+
);
195+
}
145196
}

libraries/bot-connector/src/main/java/com/microsoft/bot/connector/teams/TeamsOperations.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.microsoft.bot.schema.teams.ConversationList;
1414
import com.microsoft.bot.schema.teams.TeamDetails;
1515

16+
import com.microsoft.bot.schema.teams.TeamsMeetingParticipant;
1617
import java.util.concurrent.CompletableFuture;
1718

1819
/**
@@ -34,4 +35,17 @@ public interface TeamsOperations {
3435
* @return The TeamDetails
3536
*/
3637
CompletableFuture<TeamDetails> fetchTeamDetails(String teamId);
38+
39+
/**
40+
* Fetches Teams meeting participant details.
41+
* @param meetingId Teams meeting id
42+
* @param participantId Teams meeting participant id
43+
* @param tenantId Teams meeting tenant id
44+
* @return TeamsMeetingParticipant
45+
*/
46+
CompletableFuture<TeamsMeetingParticipant> fetchParticipant(
47+
String meetingId,
48+
String participantId,
49+
String tenantId
50+
);
3751
}

libraries/bot-schema/src/main/java/com/microsoft/bot/schema/Activity.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.fasterxml.jackson.core.JsonProcessingException;
1717
import com.fasterxml.jackson.databind.JsonNode;
1818
import com.fasterxml.jackson.databind.ObjectMapper;
19+
import com.microsoft.bot.schema.teams.TeamsMeetingInfo;
1920
import org.apache.commons.lang3.StringUtils;
2021

2122
import java.time.LocalDateTime;
@@ -50,9 +51,6 @@ public class Activity {
5051

5152
@JsonProperty(value = "localTimestamp")
5253
@JsonInclude(JsonInclude.Include.NON_EMPTY)
53-
// @JsonFormat(shape = JsonFormat.Shape.STRING, pattern =
54-
// "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
55-
// 2019-10-07T09:49:37-05:00
5654
private OffsetDateTime localTimestamp;
5755

5856
@JsonProperty(value = "localTimezone")
@@ -1757,6 +1755,22 @@ public String teamsGetChannelId() {
17571755
return teamsChannelId;
17581756
}
17591757

1758+
/**
1759+
* Gets the TeamsChannelData.
1760+
* @return TeamsChannelData
1761+
*/
1762+
public TeamsChannelData teamsGetChannelData() {
1763+
TeamsChannelData teamsChannelData;
1764+
1765+
try {
1766+
teamsChannelData = getChannelData(TeamsChannelData.class);
1767+
} catch (JsonProcessingException jpe) {
1768+
teamsChannelData = null;
1769+
}
1770+
1771+
return teamsChannelData;
1772+
}
1773+
17601774
/**
17611775
* Get unique identifier representing a team.
17621776
*
@@ -1842,6 +1856,22 @@ public void teamsNotifyUser(boolean alertInMeeting, String externalResourceUrl)
18421856
teamsChannelData.setNotification(new NotificationInfo(true, externalResourceUrl));
18431857
}
18441858

1859+
/**
1860+
* Gets the TeamsMeetingInfo object from the current activity.
1861+
* @return The current activity's team's meeting, or null.
1862+
*/
1863+
public TeamsMeetingInfo teamsGetMeetingInfo() {
1864+
TeamsChannelData teamsChannelData;
1865+
1866+
try {
1867+
teamsChannelData = getChannelData(TeamsChannelData.class);
1868+
} catch (JsonProcessingException jpe) {
1869+
teamsChannelData = null;
1870+
}
1871+
1872+
return teamsChannelData != null ? teamsChannelData.getMeeting() : null;
1873+
}
1874+
18451875
/**
18461876
* Returns this activity as a Message Activity; or null, if this is not that type of activity.
18471877
*
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.microsoft.bot.schema.teams;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
/**
6+
* Teams meeting participant details.
7+
*/
8+
public class MeetingParticipantInfo {
9+
@JsonProperty(value = "role")
10+
private String role;
11+
12+
@JsonProperty(value = "inMeeting")
13+
private boolean inMeeting;
14+
15+
/**
16+
* Gets the participant's role in the meeting.
17+
* @return The participant's role in the meeting.
18+
*/
19+
public String getRole() {
20+
return role;
21+
}
22+
23+
/**
24+
* Sets the participant's role in the meeting.
25+
* @param withRole The participant's role in the meeting.
26+
*/
27+
public void setRole(String withRole) {
28+
role = withRole;
29+
}
30+
31+
/**
32+
* Gets a value indicating whether the participant is in the meeting or not.
33+
* @return The value indicating if the participant is in the meeting.
34+
*/
35+
public boolean isInMeeting() {
36+
return inMeeting;
37+
}
38+
39+
/**
40+
* Sets a value indicating whether the participant is in the meeting or not.
41+
* @param withInMeeting The value indicating if the participant is in the meeting.
42+
*/
43+
public void setInMeeting(boolean withInMeeting) {
44+
inMeeting = withInMeeting;
45+
}
46+
}

libraries/bot-schema/src/main/java/com/microsoft/bot/schema/teams/TeamsChannelData.java

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33

44
package com.microsoft.bot.schema.teams;
55

6+
import com.fasterxml.jackson.annotation.JsonAnyGetter;
7+
import com.fasterxml.jackson.annotation.JsonAnySetter;
68
import com.fasterxml.jackson.annotation.JsonProperty;
9+
import com.fasterxml.jackson.databind.JsonNode;
10+
import java.util.HashMap;
11+
import java.util.Map;
712

813
/**
914
* Channel data specific to messages received in Microsoft Teams.
@@ -18,24 +23,23 @@ public class TeamsChannelData {
1823
@JsonProperty(value = "channel")
1924
private ChannelInfo channel;
2025

21-
/// Gets or sets type of event.
2226
@JsonProperty(value = "eventType")
2327
private String eventType;
2428

25-
/// Gets or sets information about the team in which the message was
26-
/// sent
2729
@JsonProperty(value = "team")
2830
private TeamInfo team;
2931

30-
/// Gets or sets notification settings for the message
3132
@JsonProperty(value = "notification")
3233
private NotificationInfo notification;
3334

34-
/// Gets or sets information about the tenant in which the message was
35-
/// sent
3635
@JsonProperty(value = "tenant")
3736
private TenantInfo tenant;
3837

38+
@JsonProperty(value = "meeting")
39+
private TeamsMeetingInfo meeting;
40+
41+
private HashMap<String, JsonNode> properties = new HashMap<>();
42+
3943
/**
4044
* Get unique identifier representing a channel.
4145
*
@@ -163,6 +167,45 @@ public void setTenant(TenantInfo withTenant) {
163167
this.tenant = withTenant;
164168
}
165169

170+
/**
171+
* Information about the meeting in which the message was sent.
172+
* @return The meeting info
173+
*/
174+
public TeamsMeetingInfo getMeeting() {
175+
return meeting;
176+
}
177+
178+
/**
179+
* Sets information about the meeting in which the message was sent.
180+
* @param withMeeting The meeting info
181+
*/
182+
public void setMeeting(TeamsMeetingInfo withMeeting) {
183+
meeting = withMeeting;
184+
}
185+
186+
/**
187+
* Holds the overflow properties that aren't first class properties in the
188+
* object. This allows extensibility while maintaining the object.
189+
*
190+
* @return Map of additional properties.
191+
*/
192+
@JsonAnyGetter
193+
public Map<String, JsonNode> getProperties() {
194+
return this.properties;
195+
}
196+
197+
/**
198+
* Holds the overflow properties that aren't first class properties in the
199+
* object. This allows extensibility while maintaining the object.
200+
*
201+
* @param key The key of the property to set.
202+
* @param withValue The value for the property.
203+
*/
204+
@JsonAnySetter
205+
public void setProperties(String key, JsonNode withValue) {
206+
this.properties.put(key, withValue);
207+
}
208+
166209
/**
167210
* A new instance of TeamChannelData.
168211
*

0 commit comments

Comments
 (0)