facebook - Microsoft Bot Framework 如何设置 Facebook 消息标签

标签 facebook tags botframework message proactive

我的用例是能够使用消息标签在 Facebook 的 24 + 1 政策之外发送消息,如 Facebook Dev Docs 中所述。 。它指出我需要设置messaging_type 和有效标签。我已经设置了 messages_type,但就是无法让标签正常工作。

目前我从 Facebook 收到此错误:

{
  "error": {
    "message": "(#100) Tag is required for MESSAGE_TAG messaging type.",
    "type": "OAuthException",
    "code": 100,
    "error_subcode": 2018199,
    "fbtrace_id": "GvmKwSrcqVb"
  }
}

对我来说,这表明我已成功设置 messages_type 但未设置标签。我尝试添加其他建议中的标签 GitHub #2924在 Activity.Properties 中,如下所示,但它不起作用,所以我也在 ChannelData 中尝试过它,它也不起作用。

activity.Properties = new Newtonsoft.Json.Linq.JObject();
activity.Properties.Add("tag", "CONFIRMED_EVENT_REMINDER");

activity.ChannelData = JObject.FromObject(new
{
    messaging_type = "MESSAGE_TAG",
    tag = "CONFIRMED_EVENT_REMINDER"
});

任何帮助将不胜感激,因为这看起来非常接近工作,但同时确实限制了我的机器人的能力。

我已将其交叉发布到 GitHub here .

谢谢

编辑 - 下面添加的代码示例

这是我的代码,它在所有普通情况下都能正常工作,但我无法使用消息标签在 Facebook 24 + 1 规则之外发送消息。其他一些信息是我已将我的机器人迁移到机器人框架门户上,并且它已在 Facebook Messenger 上运行,我已在其中批准了pages_messaging,但尚未申请pages_messaging_subscriptions。

[RoutePrefix("api/outboundtest")]
public class SendBotMessageTestController : ApiController
{
    [HttpPost]
    [Route("SendSimpleMessage")]
    public async Task<HttpResponseMessage> SendSimpleMessage([FromBody] BotToCustomerMessageTestDTO dto)
    {
        try
        {
            var conversationRef = JsonConvert.DeserializeObject<ConversationReference>(dto.BotConversationJson);

            // We need to ensure the URL is trusted as we lose this from the in-memory cache of trusted URLs if/when the app pool recycles: https://github.com/Microsoft/BotBuilder/issues/1645
            MicrosoftAppCredentials.TrustServiceUrl(conversationRef.ServiceUrl);

            var activity = conversationRef.GetPostToBotMessage();

            var userAccount = new ChannelAccount(conversationRef.User.Id, conversationRef.User.Name);
            var botAccount = new ChannelAccount(conversationRef.Bot.Id, conversationRef.Bot.Name);

            activity.ChannelId = conversationRef.ChannelId;
            activity.From = botAccount;
            activity.Recipient = userAccount;
            activity.Conversation = new ConversationAccount(id: conversationRef.Conversation.Id);
            activity.Locale = "en-Gb";

            var connector = new ConnectorClient(new Uri(conversationRef.ServiceUrl), this.GetCredentials());

            if (activity.ChannelId == "facebook")
            {
                // Add TAG indicate we can send this message outside the allowed window as suggested here: https://github.com/Microsoft/BotBuilder/issues/2924
                activity.Properties = new Newtonsoft.Json.Linq.JObject();
                activity.Properties.Add("tag", "CONFIRMED_EVENT_REMINDER");

                // Set messaging_type as suggested here: https://github.com/Microsoft/BotBuilder/issues/4154 and https://developers.facebook.com/docs/messenger-platform/reference/send-api/
                activity.ChannelData = JObject.FromObject(new
                {
                    notification_type = "REGULAR",
                    messaging_type = "MESSAGE_TAG"
                });
            }

            // Send the message:
            activity.Text = dto.Message;
            await connector.Conversations.SendToConversationAsync((Activity)activity).ConfigureAwait(false);

            var resp = new HttpResponseMessage(HttpStatusCode.OK);
            resp.Content = new StringContent($"Message sent", System.Text.Encoding.UTF8, @"text/plain");
            return resp;

        }
        catch (Exception ex)
        {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
        }
    }

    private MicrosoftAppCredentials GetCredentials()
    {
        return new MicrosoftAppCredentials("ABC", "XYZ");
    }
}

public class BotToCustomerMessageTestDTO
{
    public string BotConversationJson; // Stored from previous reply using activity.ToConversationReference()
    public string Message;      // This is the message to send.
}

最佳答案

这段代码对我有用。

var starter = new ConversationStarter(conversationReference);
starter.Resume(msg)

public class ConversationStarter
{
    ConversationReference conversationReference;

    public ConversationStarter(ConversationReference cr)
        => conversationReference = cr;

    public async Task Resume(string text)
    {
        IMessageActivity message = Activity.CreateMessageActivity();
        message.Text = text;
        message.Locale = "en-Us";
        await Resume(message);
    }

    public async Task Resume(IMessageActivity message)
    {
        var connector = new ConnectorClient(new Uri(conversationReference.ServiceUrl));

        //unathorized workaround
        //https://github.com/Microsoft/BotBuilder/issues/2575
        //https://github.com/Microsoft/BotBuilder/issues/2155#issuecomment-276964664
        MicrosoftAppCredentials.TrustServiceUrl(conversationReference.ServiceUrl); 

        message.ChannelId = conversationReference.ChannelId ??
            (await connector.Conversations.CreateDirectConversationAsync(conversationReference.Bot, conversationReference.User)).Id;
        message.From = conversationReference.Bot;
        message.Recipient = conversationReference.User;
        message.Conversation = new ConversationAccount(id: conversationReference.Conversation.Id);
        var activity = (Activity)message;
        activity.Properties = new Newtonsoft.Json.Linq.JObject();
        activity.Properties.Add("tag", "APPLICATION_UPDATE");
        await connector.Conversations.SendToConversationAsync(activity);
    }

    public async Task ResumeAsDialog<T>(IDialog<T> dialog)
    {
        var message = conversationReference.GetPostToBotMessage();
        var client = new ConnectorClient(new Uri(message.ServiceUrl));

        using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
        {
            var botData = scope.Resolve<IBotData>();
            await botData.LoadAsync(CancellationToken.None);

            //This is our dialog stack
            var task = scope.Resolve<IDialogTask>();

            //interrupt the stack. This means that we're stopping whatever conversation that is currently happening with the user
            //Then adding this stack to run and once it's finished, we will be back to the original conversation
            task.Call(dialog.Void<T, IMessageActivity>(), null);

            await task.PollAsync(CancellationToken.None);
            //flush dialog stack
            await botData.FlushAsync(CancellationToken.None);
        }
    }
}

关于facebook - Microsoft Bot Framework 如何设置 Facebook 消息标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49082513/

相关文章:

php - 未捕获的 OAuthException : An unknown error has occurred with Facebook PHP API

html - 为什么 Firefox 关闭空 html 标签?

c# - 丰富的卡片属性 Markdown 格式化

botframework - 如何在确认提示(Microsoft Bot Framework)中添加对不同语言的支持?

android - 为什么我的 facebook android sdk 登录被调用了两次?

android - 在 Android 应用程序中显示带有其图像的 Facebook 页面帖子

php - Ajax Post 500 服务器错误

git - 如何在没有本地仓库的情况下远程运行 git 命令

html - 在 CSS 中给 <html> 一个背景图片可以吗?

c# - 什么是 PromptOptions.Validations