2
votes

I'm able to send proactive messages to a conversation using the way described in the bot builder samples. All samples I found so far, rely on a ConversationReference that is held in-memory.

I was also able to grab a message from the transcript blob store and reply on that message.

But what I really trying to achieve is to create a valid ConversationReference by instantiating it manually. But I was not able to figure out the required properties I have to set to make it work. I know the channelId, serviceUrl and conversationId.

Does someone have a working example how to generate a valid ConversationReference?

1
What channel are using? If you're hoping to do this in Teams, it's pretty difficult as you need a lot of additional info. I'll start working up an answer.mdrichardson
I'm using directline and webchat. Just trying your suggestions, currently struggling with a 403...martinoss
403? You have the TrustServiceUrl part in there? You're using the correct appId and password? If you edit sample 16 like I did, do you still receive the error? If you're not using that sample, I've seen some permission errors pop up if you instantiate the ConnectorClient incorrectly; if you include some code I might be able to help.mdrichardson
It turned out, the 403 was caused by swapped content of "bot" and "user". I was using ApplyConversationReference without the setting "isIncoming" to true.martinoss

1 Answers

4
votes

I believe some channels may have different requirements. I can update this answer if you're looking for how to do this on a particular channel. For DirecLine/Webchat, I edited Sample 16.proactive-messages. In NotifyController.cs, I changed the Get() method to:

public async Task<IActionResult> Get()
{
    foreach (var conversationReference in _conversationReferences.Values)
    {
        // Here, I create my own ConversationReference from a known one for the purpose of testing requirements
        // I found that this is the bare minimum for WebChat/DirectLine
        var newReference = new ConversationReference()
        {
            Bot = new ChannelAccount()
            {
                Id = conversationReference.Bot.Id
            },
            Conversation = new ConversationAccount()
            {
                Id = conversationReference.Conversation.Id
            },
            ServiceUrl = conversationReference.ServiceUrl,
        };

        // You may need this to ensure the message isn't rejected
        MicrosoftAppCredentials.TrustServiceUrl(conversationReference.ServiceUrl);

        // Here, I replaced conversationReference with newReference, to ensure it's using the one I created
        await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, newReference, BotCallback, default(CancellationToken));
    }

    // Let the caller know proactive messages have been sent
    return new ContentResult()
    {
        Content = "<html><body><h1>Proactive messages have been sent.</h1></body></html>",
        ContentType = "text/html",
        StatusCode = (int)HttpStatusCode.OK,
    };
}

So, as you can see, the minimum appears to be:

var newReference = new ConversationReference()
{
    Bot = new ChannelAccount()
    {
        Id = conversationReference.Bot.Id
    },
    Conversation = new ConversationAccount()
    {
        Id = conversationReference.Conversation.Id
    },
    ServiceUrl = conversationReference.ServiceUrl,
};

References