我正在使用Microsoft.Bot.Builder框架(4.2.2)开发一个Facebook。 Bot可以在模拟器和Azure上运行,并且具有“ Web聊天测试”功能。但是在Facebook频道上,我收到“将此消息发送到您的机器人时出错:HTTP状态代码InternalServerError”
我的日志流说:
019-04-12 13:23:22.154 +00:00 [Information]
Microsoft.AspNetCore.Hosting.Internal.WebHost: Request starting
HTTP/1.1 POST
http://thomasreigltestbot1995.azurewebsites.net/api/messages
application/json; charset=utf-8 688
2019-04-12 13:23:22.155 +00:00 [Information]
Microsoft.Bot.Builder.Integration.IAdapterIntegration: Received an
incoming activity. ActivityId: Vg2USjaJGCZ1Ib_-
LTftnL9F6qg_DCJaV3XbIqGzSpisuO10eYLezkjHJxSVcYAAUWQvynDJbUyfvyBgN30B3w
2019-04-12 13:23:22.155 +00:00 [Information]
Microsoft.Bot.Builder.Integration.IAdapterIntegration: Sending
activity. ReplyToId: Vg2USjaJGCZ1Ib_-
LTftnL9F6qg_DCJaV3XbIqGzSpisuO10eYLezkjHJxSVcYAAUWQvynDJbUyfvyBgN30B3w
2019-04-12 13:23:22.388 +00:00 [Error]
Facebook_Events_Bot.FacebookEventsBot: Exception caught :
Microsoft.Bot.Schema.ErrorResponseException: Operation returned an
invalid status code 'Unauthorized'at
Microsoft.Bot.Connector.Conversations.
这是我这个仓库中的简单Bot:
public class FacebookEventsBot : IBot
{
private const string DialogId = "question";
/// </summary>
private readonly DialogSet _dialogs;
private Tuple<int, string> tuple;
public FacebookEventsBot(BotAccessors accessors)
{
if (accessors == null)
{
throw new ArgumentNullException(nameof(accessors));
}
_dialogs = new DialogSet(accessors.ConversationDialogState);
_dialogs.Add(new AttachmentPrompt(DialogId));
}
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
const string facebookPageNameOption = "Facebook Page Name";
const string quickRepliesOption = "Quick Replies";
const string postBackOption = "PostBack";
if (turnContext == null)
{
throw new ArgumentNullException(nameof(turnContext));
}
// Check if we are on the Facebook channel.
if (turnContext.Activity.ChannelId == Channel.Channels.Facebook)
{
// Analyze Facebook payload from channel data.
ProcessFacebookPayload(turnContext.Activity.ChannelData);
// Initially the bot offers to showcase 3 Facebook features: Quick replies, PostBack and getting the Facebook Page Name.
// Below we also show how to get the messaging_optin payload separately as well.
switch (turnContext.Activity.Text)
{
// Here we showcase how to obtain the Facebook page name.
// This can be useful for the Facebook multi-page support provided by the Bot Framework.
// The Facebook page name from which the message comes from is in turnContext.Activity.Recipient.Name.
case facebookPageNameOption:
{
var reply = turnContext.Activity.CreateReply($"This message comes from the following Facebook Page: {turnContext.Activity.Recipient.Name}");
await turnContext.SendActivityAsync(reply);
break;
}
// Here we send a HeroCard with 2 options that will trigger a Facebook PostBack.
case postBackOption:
{
var dialogContext = await _dialogs.CreateContextAsync(turnContext, cancellationToken);
var results = await dialogContext.ContinueDialogAsync(cancellationToken);
var card = new HeroCard
{
Text = "Is 42 the answer to the ultimate question of Life, the Universe, and Everything?",
Buttons = new List<CardAction>
{
new CardAction() { Title = "Yes", Type = ActionTypes.PostBack, Value = "Yes" },
new CardAction() { Title = "No", Type = ActionTypes.PostBack, Value = "No" },
},
};
var reply = turnContext.Activity.CreateReply();
reply.Attachments = new List<Attachment> { card.ToAttachment() };
await turnContext.SendActivityAsync(reply);
break;
}
// By default we offer the users different actions that the bot supports, through quick replies.
case quickRepliesOption:
default:
{
var reply = turnContext.Activity.CreateReply("What Facebook feature would you like to try? Here are some quick replies to choose from!");
reply.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction() { Title = quickRepliesOption, Type = ActionTypes.PostBack, Value = quickRepliesOption },
new CardAction() { Title = facebookPageNameOption, Type = ActionTypes.PostBack, Value = facebookPageNameOption },
new CardAction() { Title = postBackOption, Type = ActionTypes.PostBack, Value = postBackOption },
},
};
await turnContext.SendActivityAsync(reply);
break;
}
}
}
else
{
// Check if we are on the Facebook channel.
if (turnContext.Activity.ChannelId == Channel.Channels.Facebook)
{
// Here we can check for messaging_optin webhook event.
// Facebook Documentation for Message optin:
// https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messaging_optins/
}
await turnContext.SendActivityAsync($"Received activity of type {turnContext.Activity.Type}.");
}
}
private void ProcessFacebookPayload(object channelData)
{
// At this point we know we are on Facebook channel, and can consume the Facebook custom payload
// present in channelData.
var facebookPayload = (channelData as JObject)?.ToObject<FacebookPayload>();
if (facebookPayload != null)
{
// PostBack
if (facebookPayload.PostBack != null)
{
OnFacebookPostBack(facebookPayload.PostBack);
}
// Optin
else if (facebookPayload.Optin != null)
{
OnFacebookOptin(facebookPayload.Optin);
}
// Quick reply
else if (facebookPayload.Message?.QuickReply != null)
{
OnFacebookQuickReply(facebookPayload.Message.QuickReply);
}
// TODO: Handle other events that you're interested in...
}
}
private void OnFacebookOptin(FacebookOptin optin)
{
// TODO: Your optin event handling logic here...
}
private void OnFacebookPostBack(FacebookPostback postBack)
{
// TODO: Your PostBack handling logic here...
}
private void OnFacebookQuickReply(FacebookQuickReply quickReply)
{
// TODO: Your quick reply event handling logic here...
}
}
}