Reputation: 3
I'm pretty new to Microsoft Bot Framework. I have a bot that receives messages from one user and can be viewed by another. I want to add a feature where the viewer can then reply to the sender. I figured the best way to do this is to send a proactive message to the original sender. However, I'm having trouble understanding the documentation Microsoft provides and other sources are pretty dated.
Right now this is what I have.
MessageDetails.RelatesTo contains the ConversationReference:
private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var messageDetails = (MessageDetails)stepContext.Options;
var replyText = (string)stepContext.Result;
var messageactivity = messageDetails.RelatesTo.GetContinuationActivity();
await stepContext.Context.SendActivityAsync($"{messageDetails.RelatesTo}");
var client = new ConnectorClient(new Uri(messageactivity.ServiceUrl));
if (messageDetails.IsTrustedServiceUrl)
{
MicrosoftAppCredentials.TrustServiceUrl(messageactivity.ServiceUrl);
}
var triggerReply = messageactivity.CreateReply();
triggerReply.Text = $"NoReply from {stepContext.Context.Activity.Name}: {replyText}";
await client.Conversations.ReplyToActivityAsync(triggerReply);
await stepContext.Context.SendActivityAsync($"Your reply has been sent to {messageDetails.RelatesTo.User.Name}.");
return await stepContext.EndDialogAsync(messageDetails, cancellationToken);
}
This code doesn't work and I'm not entirely sure why. (I would also appreciate any advice on how I might troubleshoot the problem). I realize that this doesn't make use of the controller shown in the sample code provided by Microsoft. Honestly, I don't understand how the notify controller works. So if a solution involves that, it would be great to get an explanation on some of the details.
Upvotes: 0
Views: 369
Reputation: 7241
My guess is that you're getting this error:
System.ArgumentNullException: 'Value cannot be null. Parameter name: clientId'
This is because you're not specifying the appId
in new ConnectorClient
. You can disregard that, as you're better off doing something more like:
await stepContext.Context.Adapter.ContinueConversationAsync("<yourAppId>", messageDetails.RelatesTo, async (ITurnContext turnContext, CancellationToken cancel) =>
{
await turnContext.SendActivityAsync(triggerReply);
}, cancellationToken);
The key is making sure you have a ConversationReference
for the user that you need to send the proactive message to. If you don't have one, you should be able to CreateConversation
to establish one
Note that you also have:
if (messageDetails.IsTrustedServiceUrl)
{
MicrosoftAppCredentials.TrustServiceUrl(messageactivity.ServiceUrl);
}
This is basically saying, "if we already trust the serviceUrl, trust it again". Instead, you need: if (!messageDetails.IsTrustedServiceUrl)
Here's a brief explanation of how the proactive sample works. I recommend downloading it and playing around with it to get a better understanding.
api/messages
(all bots do this) and api/notify
(only this bot does this).api/messages
and is processed through the ActivityHandler
.<theBotUrl>/api/notify
, it loops through each saved conversation reference, calls ContinueConversation, and sends the message to all of the users in the saved conversation referencesUpvotes: 1