简体   繁体   中英

Sending a Proactive Message as a result of a dialog prompt choice

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.

Fixing Your Problem

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)


How Proactive Bot Works

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.

  1. The bot establishes listeners on api/messages (all bots do this) and api/notify (only this bot does this).
  2. When a user messages the bot, it goes through api/messages and is processed through the ActivityHandler .
  3. On any message, the bot saves the conversation reference
  4. When somebody visits <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 references

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM