Search code examples
c#botframework

Create a valid ConversationReference from scratch to send proactive messages


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?


Solution

  • 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