/// <inheritdoc/> public override async Task <DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { if (options is CancellationToken) { throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } if (Disabled != null && Disabled.GetValue(dc.State)) { return(await dc.EndDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false)); } if (dc.Context.Activity.ChannelId != Channels.Msteams) { throw new InvalidOperationException($"{Kind} works only on the Teams channel."); } IActivity activity = null; if (Activity != null) { activity = await Activity.BindAsync(dc, dc.State).ConfigureAwait(false); } string teamsChannelId = TeamsChannelId.GetValueOrNull(dc.State); if (string.IsNullOrEmpty(teamsChannelId)) { teamsChannelId = dc.Context.Activity.TeamsGetChannelId(); } if (!(dc.Context.Adapter is BotFrameworkAdapter)) { throw new InvalidOperationException($"{Kind} is not supported by the current adapter."); } // TODO: this will NOT work with certificate app credentials // TeamsInfo.SendMessageToTeamsChannelAsync requires AppCredentials var credentials = dc.Context.TurnState.Get <IConnectorClient>()?.Credentials as MicrosoftAppCredentials; if (credentials == null) { throw new InvalidOperationException($"Missing credentials as {nameof(MicrosoftAppCredentials)} in {nameof(IConnectorClient)} from TurnState"); } // The result comes back as a tuple, which is used to set the two properties (if present). var result = await TeamsInfo.SendMessageToTeamsChannelAsync(dc.Context, activity, teamsChannelId, credentials, cancellationToken : cancellationToken).ConfigureAwait(false); if (ConversationReferenceProperty != null) { dc.State.SetValue(ConversationReferenceProperty.GetValue(dc.State), result.Item1); } if (ActivityIdProperty != null) { dc.State.SetValue(ActivityIdProperty.GetValue(dc.State), result.Item2); } return(await dc.EndDialogAsync(result, cancellationToken : cancellationToken).ConfigureAwait(false)); }
/// <inheritdoc/> public override async Task <DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { if (options is CancellationToken) { throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } if (Disabled != null && Disabled.GetValue(dc.State)) { return(await dc.EndDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false)); } if (dc.Context.Activity.ChannelId != Channels.Msteams) { throw new InvalidOperationException($"{Kind} works only on the Teams channel."); } IActivity activity = null; if (Activity != null) { activity = await Activity.BindAsync(dc, dc.State).ConfigureAwait(false); } string teamsChannelId = TeamsChannelId.GetValueOrNull(dc.State); if (string.IsNullOrEmpty(teamsChannelId)) { teamsChannelId = dc.Context.Activity.TeamsGetChannelId(); } Tuple <ConversationReference, string> result; // Check for legacy adapter if (dc.Context.Adapter is BotFrameworkAdapter) { // TeamsInfo.SendMessageToTeamsChannelAsync requires AppCredentials var credentials = dc.Context.TurnState.Get <IConnectorClient>()?.Credentials as MicrosoftAppCredentials; if (credentials == null) { throw new InvalidOperationException($"Missing credentials as {nameof(MicrosoftAppCredentials)} in {nameof(IConnectorClient)} from TurnState"); } // The result comes back as a tuple, which is used to set the two properties (if present). result = await TeamsInfo.SendMessageToTeamsChannelAsync(dc.Context, activity, teamsChannelId, credentials, cancellationToken : cancellationToken).ConfigureAwait(false); } else if (dc.Context.Adapter is CloudAdapterBase) { // Retrieve the bot appid from TurnState's ClaimsIdentity string appId; if (dc.Context.TurnState.Get <ClaimsIdentity>(BotAdapter.BotIdentityKey) is ClaimsIdentity botIdentity) { // Apparently 'version' is sometimes empty, which will result in no id returned from GetAppIdFromClaims appId = JwtTokenValidation.GetAppIdFromClaims(botIdentity.Claims); if (string.IsNullOrEmpty(appId)) { appId = botIdentity.Claims.FirstOrDefault(claim => claim.Type == AuthenticationConstants.AudienceClaim)?.Value; } if (string.IsNullOrEmpty(appId)) { throw new InvalidOperationException($"Missing AppIdClaim in ClaimsIdentity."); } } else { throw new InvalidOperationException($"Missing {BotAdapter.BotIdentityKey} in {nameof(ITurnContext)} TurnState."); } // The result comes back as a tuple, which is used to set the two properties (if present). result = await TeamsInfo.SendMessageToTeamsChannelAsync(dc.Context, activity, teamsChannelId, appId, cancellationToken : cancellationToken).ConfigureAwait(false); } else { throw new InvalidOperationException($"The adapter does not support {nameof(SendMessageToTeamsChannel)}."); } if (ConversationReferenceProperty != null) { dc.State.SetValue(ConversationReferenceProperty.GetValue(dc.State), result.Item1); } if (ActivityIdProperty != null) { dc.State.SetValue(ActivityIdProperty.GetValue(dc.State), result.Item2); } return(await dc.EndDialogAsync(result, cancellationToken : cancellationToken).ConfigureAwait(false)); }