facebookbotframeworkfacebook-messengerunauthorizedproactive

Microsoft Bot Framework v4: Facebook messenger proactive message unauthorized after bot restart


I've written a bot using the microsoft framework v4 SDK in C#. The bot is deployed in Azure and connected to web chat, direct line and Facebook Messenger channels. The bot works fine for all.

Users can subscribe to receive updates proactively. For this I use a stored ConversationReference which is then used to send the proactive messages. Again this all works fine except for if the bot wepApp is restarted which causes:-

Exception caught : Microsoft.Bot.Schema.ErrorResponseException: Operation returned an invalid status code 'Unauthorized' for the facebook channel.

If I send another message to the bot from facebook messenger then the proactive messages begin working again even for older stored ConversationReferences.

Originally I was using MemoryStorage as per the samples, but I changed it to use Azure Blob Storage for the conversationState and userState. This makes no difference. It's as if it must be storing a facebook auth token in memory, so if the app restarts the token is lost until the user sends another message from messenger.

Is there any way I can fix this as it makes subscribed proactive updates pointless if it can't handle a bot webApp restart?

Many thanks


Solution

  • This sounds a lot like a Trust Service URL Issue.

    You can fix it by adding facebook to the list of trusted URLs:

    var serviceUrl = "https://facebook.botframework.com/";
    
    var connector = new ConnectorClient(new Uri(serviceUrl), new MicrosoftAppCredentials("YourAPPID", "YourAppPassword"));
    
    MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
    

    Here's a link to the library, if that helps. Otherwise, browsing the issues I linked should help.

    Note to others:

    This "Trust Service URL Issue" doesn't apply to just Facebook. This happens for lots of other URLs when trying to use Proactive messaging. Just replace serviceUrl with whatever is appropriate for your use case. And yes, if you're using multiple channels, you can add multiple URLs when using MicrosoftAppCredentials.TrustServiceUrl() by calling it multiple times.

    Here's the method definition. Note: you can add expiration for this, as well.

    As requested, I've submitted a PR for this