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

Commit

Permalink
Merge pull request #826 from microsoft/trboehre/teamsmeeting
Browse files Browse the repository at this point in the history
Teams Meeting API
  • Loading branch information
tracyboehrer authored Oct 21, 2020
2 parents 5a406bf + c657733 commit c9dcdce
Show file tree
Hide file tree
Showing 8 changed files with 376 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.microsoft.bot.schema.teams.TeamsChannelAccount;
import com.microsoft.bot.schema.teams.TeamsChannelData;
import com.microsoft.bot.schema.teams.TeamsPagedMembersResult;
import com.microsoft.bot.schema.teams.TeamsMeetingParticipant;
import org.apache.commons.lang3.StringUtils;

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

/**
* Gets the details for the given meeting participant. This only works in teams meeting scoped conversations.
* @param turnContext The TurnContext that the meeting, participant, and tenant ids are pulled from.
* @return TeamsParticipantChannelAccount
*/
public static CompletableFuture<TeamsMeetingParticipant> getMeetingParticipant(
TurnContext turnContext
) {
return getMeetingParticipant(turnContext, null, null, null);
}

/**
* Gets the details for the given meeting participant. This only works in teams meeting scoped conversations.
* @param turnContext Turn context.
* @param meetingId The meeting id, or null to get from Activities TeamsChannelData
* @param participantId The participant id, or null to get from Activities TeamsChannelData
* @param tenantId The tenant id, or null to get from Activities TeamsChannelData
* @return Team participant channel account.
*/
public static CompletableFuture<TeamsMeetingParticipant> getMeetingParticipant(
TurnContext turnContext,
String meetingId,
String participantId,
String tenantId
) {
if (StringUtils.isEmpty(meetingId)) {
meetingId = turnContext.getActivity().teamsGetMeetingInfo() != null
? turnContext.getActivity().teamsGetMeetingInfo().getId()
: null;
}
if (StringUtils.isEmpty(meetingId)) {
return illegalArgument("TeamsInfo.getMeetingParticipant: method requires a meetingId");
}

if (StringUtils.isEmpty(participantId)) {
participantId = turnContext.getActivity().getFrom() != null
? turnContext.getActivity().getFrom().getAadObjectId()
: null;
}
if (StringUtils.isEmpty(participantId)) {
return illegalArgument("TeamsInfo.getMeetingParticipant: method requires a participantId");
}

if (StringUtils.isEmpty(tenantId)) {
tenantId = turnContext.getActivity().teamsGetChannelData() != null
? turnContext.getActivity().teamsGetChannelData().getTenant().getId()
: null;
}
if (StringUtils.isEmpty(tenantId)) {
return illegalArgument("TeamsInfo.getMeetingParticipant: method requires a tenantId");
}

return getTeamsConnectorClient(turnContext).getTeams().fetchParticipant(
meetingId,
participantId,
tenantId
);
}

private static CompletableFuture<List<TeamsChannelAccount>> getMembers(
ConnectorClient connectorClient,
String conversationId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
import com.microsoft.bot.rest.ServiceResponse;
import com.microsoft.bot.schema.teams.ConversationList;
import com.microsoft.bot.schema.teams.TeamDetails;
import com.microsoft.bot.schema.teams.TeamsMeetingParticipant;
import okhttp3.ResponseBody;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
Expand All @@ -22,6 +24,7 @@
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.concurrent.CompletableFuture;
import retrofit2.http.Query;

/**
* msrest impl of TeamsOperations.
Expand Down Expand Up @@ -117,6 +120,44 @@ private ServiceResponse<TeamDetails> fetchTeamDetailsDelegate(
.build(response);
}

/**
* Fetches Teams meeting participant details.
* @param meetingId Teams meeting id
* @param participantId Teams meeting participant id
* @param tenantId Teams meeting tenant id
* @return TeamsParticipantChannelAccount
*/
public CompletableFuture<TeamsMeetingParticipant> fetchParticipant(
String meetingId,
String participantId,
String tenantId
) {
return service.fetchParticipant(
meetingId, participantId, tenantId, client.getAcceptLanguage(), client.getUserAgent()
)
.thenApply(responseBodyResponse -> {
try {
return fetchParticipantDelegate(responseBodyResponse).body();
} catch (ErrorResponseException e) {
throw e;
} catch (Throwable t) {
throw new ErrorResponseException("fetchParticipant", responseBodyResponse);
}
});
}

private ServiceResponse<TeamsMeetingParticipant> fetchParticipantDelegate(
Response<ResponseBody> response
) throws ErrorResponseException, IOException, IllegalArgumentException {
return client.restClient()
.responseBuilderFactory()
.<TeamsMeetingParticipant, ErrorResponseException>newInstance(client.serializerAdapter())
.register(HttpURLConnection.HTTP_OK, new TypeToken<TeamsMeetingParticipant>() {
}.getType())
.registerError(ErrorResponseException.class)
.build(response);
}

/**
* The interface defining all the services for TeamsOperations to be used by
* Retrofit to perform actually REST calls.
Expand All @@ -140,6 +181,16 @@ CompletableFuture<Response<ResponseBody>> fetchTeamDetails(
@Header("accept-language") String acceptLanguage,
@Header("User-Agent") String userAgent
);
}

@Headers({ "Content-Type: application/json; charset=utf-8",
"x-ms-logging-context: com.microsoft.bot.schema.Teams fetchParticipant" })
@GET("v1/meetings/{meetingId}/participants/{participantId}")
CompletableFuture<Response<ResponseBody>> fetchParticipant(
@Path("meetingId") String meetingId,
@Path("participantId") String participantId,
@Query("tenantId") String tenantId,
@Header("accept-language") String acceptLanguage,
@Header("User-Agent") String userAgent
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.microsoft.bot.schema.teams.ConversationList;
import com.microsoft.bot.schema.teams.TeamDetails;

import com.microsoft.bot.schema.teams.TeamsMeetingParticipant;
import java.util.concurrent.CompletableFuture;

/**
Expand All @@ -34,4 +35,17 @@ public interface TeamsOperations {
* @return The TeamDetails
*/
CompletableFuture<TeamDetails> fetchTeamDetails(String teamId);

/**
* Fetches Teams meeting participant details.
* @param meetingId Teams meeting id
* @param participantId Teams meeting participant id
* @param tenantId Teams meeting tenant id
* @return TeamsMeetingParticipant
*/
CompletableFuture<TeamsMeetingParticipant> fetchParticipant(
String meetingId,
String participantId,
String tenantId
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.microsoft.bot.schema.teams.TeamsMeetingInfo;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDateTime;
Expand Down Expand Up @@ -50,9 +51,6 @@ public class Activity {

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

@JsonProperty(value = "localTimezone")
Expand Down Expand Up @@ -1757,6 +1755,22 @@ public String teamsGetChannelId() {
return teamsChannelId;
}

/**
* Gets the TeamsChannelData.
* @return TeamsChannelData
*/
public TeamsChannelData teamsGetChannelData() {
TeamsChannelData teamsChannelData;

try {
teamsChannelData = getChannelData(TeamsChannelData.class);
} catch (JsonProcessingException jpe) {
teamsChannelData = null;
}

return teamsChannelData;
}

/**
* Get unique identifier representing a team.
*
Expand Down Expand Up @@ -1842,6 +1856,22 @@ public void teamsNotifyUser(boolean alertInMeeting, String externalResourceUrl)
teamsChannelData.setNotification(new NotificationInfo(true, externalResourceUrl));
}

/**
* Gets the TeamsMeetingInfo object from the current activity.
* @return The current activity's team's meeting, or null.
*/
public TeamsMeetingInfo teamsGetMeetingInfo() {
TeamsChannelData teamsChannelData;

try {
teamsChannelData = getChannelData(TeamsChannelData.class);
} catch (JsonProcessingException jpe) {
teamsChannelData = null;
}

return teamsChannelData != null ? teamsChannelData.getMeeting() : null;
}

/**
* Returns this activity as a Message Activity; or null, if this is not that type of activity.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.microsoft.bot.schema.teams;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
* Teams meeting participant details.
*/
public class MeetingParticipantInfo {
@JsonProperty(value = "role")
private String role;

@JsonProperty(value = "inMeeting")
private boolean inMeeting;

/**
* Gets the participant's role in the meeting.
* @return The participant's role in the meeting.
*/
public String getRole() {
return role;
}

/**
* Sets the participant's role in the meeting.
* @param withRole The participant's role in the meeting.
*/
public void setRole(String withRole) {
role = withRole;
}

/**
* Gets a value indicating whether the participant is in the meeting or not.
* @return The value indicating if the participant is in the meeting.
*/
public boolean isInMeeting() {
return inMeeting;
}

/**
* Sets a value indicating whether the participant is in the meeting or not.
* @param withInMeeting The value indicating if the participant is in the meeting.
*/
public void setInMeeting(boolean withInMeeting) {
inMeeting = withInMeeting;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@

package com.microsoft.bot.schema.teams;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.HashMap;
import java.util.Map;

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

/// Gets or sets type of event.
@JsonProperty(value = "eventType")
private String eventType;

/// Gets or sets information about the team in which the message was
/// sent
@JsonProperty(value = "team")
private TeamInfo team;

/// Gets or sets notification settings for the message
@JsonProperty(value = "notification")
private NotificationInfo notification;

/// Gets or sets information about the tenant in which the message was
/// sent
@JsonProperty(value = "tenant")
private TenantInfo tenant;

@JsonProperty(value = "meeting")
private TeamsMeetingInfo meeting;

private HashMap<String, JsonNode> properties = new HashMap<>();

/**
* Get unique identifier representing a channel.
*
Expand Down Expand Up @@ -163,6 +167,45 @@ public void setTenant(TenantInfo withTenant) {
this.tenant = withTenant;
}

/**
* Information about the meeting in which the message was sent.
* @return The meeting info
*/
public TeamsMeetingInfo getMeeting() {
return meeting;
}

/**
* Sets information about the meeting in which the message was sent.
* @param withMeeting The meeting info
*/
public void setMeeting(TeamsMeetingInfo withMeeting) {
meeting = withMeeting;
}

/**
* Holds the overflow properties that aren't first class properties in the
* object. This allows extensibility while maintaining the object.
*
* @return Map of additional properties.
*/
@JsonAnyGetter
public Map<String, JsonNode> getProperties() {
return this.properties;
}

/**
* Holds the overflow properties that aren't first class properties in the
* object. This allows extensibility while maintaining the object.
*
* @param key The key of the property to set.
* @param withValue The value for the property.
*/
@JsonAnySetter
public void setProperties(String key, JsonNode withValue) {
this.properties.put(key, withValue);
}

/**
* A new instance of TeamChannelData.
*
Expand Down
Loading

0 comments on commit c9dcdce

Please sign in to comment.