public async Task TestSendMessageToTeamsChannel2Async() { // Arrange var expectedTeamsChannelId = "teams-channel-id"; var expectedAppId = "app-id"; var expectedServiceUrl = "service-url"; var expectedActivityId = "activity-id"; var expectedConversationId = "conversation-id"; var requestActivity = new Activity { ServiceUrl = expectedServiceUrl }; var adapter = new TestCreateConversationAdapter(expectedActivityId, expectedConversationId); var turnContextMock = new Mock <ITurnContext>(); turnContextMock.Setup(tc => tc.Activity).Returns(requestActivity); turnContextMock.Setup(tc => tc.Adapter).Returns(adapter); var activity = new Activity { Type = "message", Text = "Test-SendMessageToTeamsChannelAsync", ChannelId = Channels.Msteams, ChannelData = new TeamsChannelData { Team = new TeamInfo { Id = "team-id", }, }, }; // Act var r = await TeamsInfo.SendMessageToTeamsChannelAsync(turnContextMock.Object, activity, expectedTeamsChannelId, expectedAppId, CancellationToken.None); // Assert Assert.Equal(expectedConversationId, r.Item1.Conversation.Id); Assert.Equal(expectedActivityId, r.Item2); Assert.Equal(expectedAppId, adapter.AppId); Assert.Equal(Channels.Msteams, adapter.ChannelId); Assert.Equal(expectedServiceUrl, adapter.ServiceUrl); Assert.Null(adapter.Audience); var channelData = adapter.ConversationParameters.ChannelData; var channel = channelData.GetType().GetProperty("channel").GetValue(channelData, null); var id = channel.GetType().GetProperty("id").GetValue(channel, null); Assert.Equal(expectedTeamsChannelId, id); Assert.Equal(adapter.ConversationParameters.Activity, activity); }
private async Task SendMessageToTeamsChannel(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken) { if (await TeamScopeCheck(turnContext, cancellationToken).ConfigureAwait(false)) { var activity = MessageFactory.Text("This is the start of a new thread in a channel"); var channelId = turnContext.Activity.TeamsGetTeamInfo().Id; var creds = new MicrosoftAppCredentials(_config["MicrosoftAppId"], _config["MicrosoftAppPassword"]); await TeamsInfo.SendMessageToTeamsChannelAsync(turnContext, activity, channelId, creds, cancellationToken).ConfigureAwait(false); } }
private async Task CallSendMessageToTeamsChannelAsync(ITurnContext turnContext) { var message = MessageFactory.Text("hi"); var channelId = "channelId123"; var creds = new MicrosoftAppCredentials("big-guid-here", "appPasswordHere"); var cancelToken = new CancellationToken(); var reference = await TeamsInfo.SendMessageToTeamsChannelAsync(turnContext, message, channelId, creds, cancelToken); Assert.AreEqual(reference.Item1.ActivityId, "activityId123"); Assert.AreEqual(reference.Item1.ChannelId, "channelId123"); Assert.AreEqual(reference.Item1.ServiceUrl, "https://test.coffee"); Assert.AreEqual(reference.Item2, "activityId123"); }
private async Task CallSendMessageToTeamsChannelAsync(ITurnContext turnContext) { var message = MessageFactory.Text("hi"); var channelId = "channelId123"; var creds = new MicrosoftAppCredentials(string.Empty, string.Empty); var cancelToken = new CancellationToken(); var reference = await TeamsInfo.SendMessageToTeamsChannelAsync(turnContext, message, channelId, creds, cancelToken); Assert.Equal("activityId123", reference.Item1.ActivityId); Assert.Equal(channelId, reference.Item1.ChannelId); Assert.Equal(turnContext.Activity.ServiceUrl, reference.Item1.ServiceUrl); Assert.Equal("activityId123", reference.Item2); }
protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken) { var teamsChannelId = turnContext.Activity.TeamsGetChannelId(); var message = MessageFactory.Text("good morning"); var creds = new MicrosoftAppCredentials(this._appId, this._appPassword); Tuple <ConversationReference, string> tuple = await TeamsInfo.SendMessageToTeamsChannelAsync(turnContext, message, teamsChannelId, creds); //// (2) starting a one on one chat //var accounts = (await TeamsInfo.GetMembersAsync(turnContext)).ToArray(); //var account = accounts.First(); //var conversationParameters = new ConversationParameters //{ // IsGroup = false, // Bot = turnContext.Activity.Recipient, // Members = new ChannelAccount[] { account }, // TenantId = turnContext.Activity.Conversation.TenantId, //}; //ConversationReference conversationReference = null; //await ((BotFrameworkAdapter)turnContext.Adapter).CreateConversationAsync( // teamsChannelId, // serviceUrl, // credentials, // conversationParameters, // (t, ct) => // { // conversationReference = t.Activity.GetConversationReference(); // return Task.CompletedTask; // }, // cancellationToken); await((BotFrameworkAdapter)turnContext.Adapter).ContinueConversationAsync( this._appId, tuple.Item1, async(t, ct) => { await t.SendActivityAsync(MessageFactory.Text($"this will be the first reply. The Activity.Id of the top level message is {tuple.Item2}"), ct); }, cancellationToken); }
/// <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)); }