Nodejs: Messenger показывает ошибку неверных данных при отправке запроса на широковещательное сообщение

В настоящее время я пытаюсь автоматизировать процесс отправки широковещательного сообщения в Facebook, чтобы я мог запускать его с помощью вызова API.

Запрос Http к моему API получен и обработан, но когда процесс начинает отправлять сообщение в конечную точку message_creatives, он возвращает следующую ошибку:

{ Error: Request failed with status code 400
2018-08-10T00:12:25.705782+00:00 app[web.1]: at createError (/app/node_modules/axios/lib/core/createError.js:16:15)
2018-08-10T00:12:25.705784+00:00 app[web.1]: at settle (/app/node_modules/axios/lib/core/settle.js:18:12)
2018-08-10T00:12:25.705787+00:00 app[web.1]: at IncomingMessage.handleStreamEnd (/app/node_modules/axios/lib/adapters/http.js:191:11)
2018-08-10T00:12:25.705789+00:00 app[web.1]: at IncomingMessage.emit (events.js:164:20)
2018-08-10T00:12:25.705792+00:00 app[web.1]: at endReadableNT (_stream_readable.js:1062:12)
2018-08-10T00:12:25.705794+00:00 app[web.1]: at process._tickCallback (internal/process/next_tick.js:152:19)
2018-08-10T00:12:25.705796+00:00 app[web.1]: config:
2018-08-10T00:12:25.705798+00:00 app[web.1]: { adapter: [Function: httpAdapter],
2018-08-10T00:12:25.705800+00:00 app[web.1]: transformRequest: { '0': [Function: transformRequest] },
2018-08-10T00:12:25.705801+00:00 app[web.1]: transformResponse: { '0': [Function: transformResponse] },
2018-08-10T00:12:25.705804+00:00 app[web.1]: timeout: 0,
2018-08-10T00:12:25.705806+00:00 app[web.1]: xsrfCookieName: 'XSRF-TOKEN',
2018-08-10T00:12:25.705807+00:00 app[web.1]: xsrfHeaderName: 'X-XSRF-TOKEN',
2018-08-10T00:12:25.705809+00:00 app[web.1]: maxContentLength: -1,
2018-08-10T00:12:25.705810+00:00 app[web.1]: validateStatus: [Function: validateStatus],
2018-08-10T00:12:25.705812+00:00 app[web.1]: headers:
2018-08-10T00:12:25.705814+00:00 app[web.1]: { Accept: 'application/json, text/plain, */*',
2018-08-10T00:12:25.705815+00:00 app[web.1]: 'Content-Type': 'application/json',
2018-08-10T00:12:25.705817+00:00 app[web.1]: 'User-Agent': 'axios/0.16.2',
2018-08-10T00:12:25.705819+00:00 app[web.1]: 'Content-Length': 54 },
2018-08-10T00:12:25.705820+00:00 app[web.1]: method: 'post',
2018-08-10T00:12:25.705829+00:00 app[web.1]: url: 'https://graph.facebook.com/v2.11/me/message_creatives?access_token=<ACCESS_TOKEN>',
2018-08-10T00:12:25.705831+00:00 app[web.1]: data: '{"message":[{"text":"Today\'s information is HERE!"}]}' },
2018-08-10T00:12:25.705832+00:00 app[web.1]: request:
2018-08-10T00:12:25.705834+00:00 app[web.1]: ClientRequest {
2018-08-10T00:12:25.705835+00:00 app[web.1]: domain: null,
2018-08-10T00:12:25.705837+00:00 app[web.1]: _events:
2018-08-10T00:12:25.705839+00:00 app[web.1]: { socket: [Function],
2018-08-10T00:12:25.705840+00:00 app[web.1]: abort: [Function],
2018-08-10T00:12:25.705842+00:00 app[web.1]: aborted: [Function],
2018-08-10T00:12:25.705844+00:00 app[web.1]: error: [Function],
2018-08-10T00:12:25.705845+00:00 app[web.1]: timeout: [Function],
2018-08-10T00:12:25.705847+00:00 app[web.1]: prefinish: [Function: requestOnPrefinish] },
2018-08-10T00:12:25.705848+00:00 app[web.1]: _eventsCount: 6,
2018-08-10T00:12:25.705850+00:00 app[web.1]: _maxListeners: undefined,
2018-08-10T00:12:25.705852+00:00 app[web.1]: output: [],
2018-08-10T00:12:25.705853+00:00 app[web.1]: outputEncodings: [],
2018-08-10T00:12:25.705855+00:00 app[web.1]: outputCallbacks: [],
2018-08-10T00:12:25.705856+00:00 app[web.1]: outputSize: 0,
2018-08-10T00:12:25.705858+00:00 app[web.1]: writable: true,
2018-08-10T00:12:25.705860+00:00 app[web.1]: _last: true,
2018-08-10T00:12:25.705861+00:00 app[web.1]: upgrading: false,
2018-08-10T00:12:25.705863+00:00 app[web.1]: chunkedEncoding: false,
2018-08-10T00:12:25.705865+00:00 app[web.1]: shouldKeepAlive: false,
2018-08-10T00:12:25.705867+00:00 app[web.1]: useChunkedEncodingByDefault: true,
2018-08-10T00:12:25.705868+00:00 app[web.1]: sendDate: false,
2018-08-10T00:12:25.705870+00:00 app[web.1]: _removedConnection: false,
2018-08-10T00:12:25.705871+00:00 app[web.1]: _removedContLen: false,
2018-08-10T00:12:25.705873+00:00 app[web.1]: _removedTE: false,
2018-08-10T00:12:25.705875+00:00 app[web.1]: _contentLength: null,
2018-08-10T00:12:25.705876+00:00 app[web.1]: _hasBody: true,
2018-08-10T00:12:25.705878+00:00 app[web.1]: _trailer: '',
2018-08-10T00:12:25.705880+00:00 app[web.1]: finished: true,
2018-08-10T00:12:25.705881+00:00 app[web.1]: _headerSent: true,
2018-08-10T00:12:25.705883+00:00 app[web.1]: socket:
2018-08-10T00:12:25.705885+00:00 app[web.1]: TLSSocket {
2018-08-10T00:12:25.705887+00:00 app[web.1]: _tlsOptions: [Object],
2018-08-10T00:12:25.705889+00:00 app[web.1]: _secureEstablished: true,
2018-08-10T00:12:25.705890+00:00 app[web.1]: _securePending: false,
2018-08-10T00:12:25.705892+00:00 app[web.1]: _newSessionPending: false,
2018-08-10T00:12:25.705894+00:00 app[web.1]: _controlReleased: true,
2018-08-10T00:12:25.705895+00:00 app[web.1]: _SNICallback: null,
2018-08-10T00:12:25.705897+00:00 app[web.1]: servername: null,
2018-08-10T00:12:25.705899+00:00 app[web.1]: npnProtocol: undefined,
2018-08-10T00:12:25.705900+00:00 app[web.1]: alpnProtocol: false,
2018-08-10T00:12:25.705902+00:00 app[web.1]: authorized: true,
2018-08-10T00:12:25.705904+00:00 app[web.1]: authorizationError: null,
2018-08-10T00:12:25.705906+00:00 app[web.1]: encrypted: true,
2018-08-10T00:12:25.705907+00:00 app[web.1]: _events: [Object],
2018-08-10T00:12:25.705908+00:00 app[web.1]: _eventsCount: 9,
2018-08-10T00:12:25.705910+00:00 app[web.1]: connecting: false,
2018-08-10T00:12:25.705911+00:00 app[web.1]: _hadError: false,
2018-08-10T00:12:25.705913+00:00 app[web.1]: _handle: null,
2018-08-10T00:12:25.705914+00:00 app[web.1]: _parent: null,
2018-08-10T00:12:25.705916+00:00 app[web.1]: _host: 'graph.facebook.com',
2018-08-10T00:12:25.705917+00:00 app[web.1]: _readableState: [ReadableState],
2018-08-10T00:12:25.705919+00:00 app[web.1]: readable: false,
2018-08-10T00:12:25.705921+00:00 app[web.1]: domain: null,
2018-08-10T00:12:25.705922+00:00 app[web.1]: _maxListeners: undefined,
2018-08-10T00:12:25.705924+00:00 app[web.1]: _writableState: [WritableState],
2018-08-10T00:12:25.705926+00:00 app[web.1]: writable: false,
2018-08-10T00:12:25.705927+00:00 app[web.1]: allowHalfOpen: false,
2018-08-10T00:12:25.705929+00:00 app[web.1]: _bytesDispatched: 456,
2018-08-10T00:12:25.705931+00:00 app[web.1]: _sockname: null,
2018-08-10T00:12:25.705932+00:00 app[web.1]: _pendingData: null,
2018-08-10T00:12:25.705934+00:00 app[web.1]: _pendingEncoding: '',
2018-08-10T00:12:25.705936+00:00 app[web.1]: server: undefined,
2018-08-10T00:12:25.705937+00:00 app[web.1]: _server: null,
2018-08-10T00:12:25.705939+00:00 app[web.1]: ssl: null,
2018-08-10T00:12:25.705940+00:00 app[web.1]: _requestCert: true,
2018-08-10T00:12:25.705942+00:00 app[web.1]: _rejectUnauthorized: true,
2018-08-10T00:12:25.705944+00:00 app[web.1]: parser: null,
2018-08-10T00:12:25.705946+00:00 app[web.1]: _httpMessage: [Circular],
2018-08-10T00:12:25.705947+00:00 app[web.1]: read: [Function],
2018-08-10T00:12:25.705949+00:00 app[web.1]: _consuming: true,
2018-08-10T00:12:25.705950+00:00 app[web.1]: _idleNext: null,
2018-08-10T00:12:25.705952+00:00 app[web.1]: _idlePrev: null,
2018-08-10T00:12:25.705953+00:00 app[web.1]: _idleTimeout: -1,
2018-08-10T00:12:25.705955+00:00 app[web.1]: [Symbol(res)]: [TLSWrap],
2018-08-10T00:12:25.705957+00:00 app[web.1]: [Symbol(asyncId)]: 11622,
2018-08-10T00:12:25.705958+00:00 app[web.1]: [Symbol(bytesRead)]: 842,
2018-08-10T00:12:25.705960+00:00 app[web.1]: [Symbol(connect-options)]: [Object] },
2018-08-10T00:12:25.705961+00:00 app[web.1]: connection:
2018-08-10T00:12:25.705963+00:00 app[web.1]: TLSSocket {
2018-08-10T00:12:25.705964+00:00 app[web.1]: _tlsOptions: [Object],
2018-08-10T00:12:25.705966+00:00 app[web.1]: _secureEstablished: true,
2018-08-10T00:12:25.705968+00:00 app[web.1]: _securePending: false,
2018-08-10T00:12:25.705970+00:00 app[web.1]: _newSessionPending: false,
2018-08-10T00:12:25.705971+00:00 app[web.1]: _controlReleased: true,
2018-08-10T00:12:25.705973+00:00 app[web.1]: _SNICallback: null,
2018-08-10T00:12:25.705974+00:00 app[web.1]: servername: null,
2018-08-10T00:12:25.705976+00:00 app[web.1]: npnProtocol: undefined,
2018-08-10T00:12:25.705977+00:00 app[web.1]: alpnProtocol: false,
2018-08-10T00:12:25.705979+00:00 app[web.1]: authorized: true,
2018-08-10T00:12:25.705982+00:00 app[web.1]: authorizationError: null,
2018-08-10T00:12:25.705984+00:00 app[web.1]: encrypted: true,
2018-08-10T00:12:25.705985+00:00 app[web.1]: _events: [Object],
2018-08-10T00:12:25.705987+00:00 app[web.1]: _eventsCount: 9,
2018-08-10T00:12:25.705988+00:00 app[web.1]: connecting: false,
2018-08-10T00:12:25.705990+00:00 app[web.1]: _hadError: false,
2018-08-10T00:12:25.705992+00:00 app[web.1]: _handle: null,
2018-08-10T00:12:25.705993+00:00 app[web.1]: _parent: null,
2018-08-10T00:12:25.705995+00:00 app[web.1]: _host: 'graph.facebook.com',
2018-08-10T00:12:25.706004+00:00 app[web.1]: _readableState: [ReadableState],
2018-08-10T00:12:25.706006+00:00 app[web.1]: readable: false,
2018-08-10T00:12:25.706007+00:00 app[web.1]: domain: null,
2018-08-10T00:12:25.706009+00:00 app[web.1]: _maxListeners: undefined,
2018-08-10T00:12:25.706010+00:00 app[web.1]: _writableState: [WritableState],
2018-08-10T00:12:25.706012+00:00 app[web.1]: writable: false,
2018-08-10T00:12:25.706013+00:00 app[web.1]: allowHalfOpen: false,
2018-08-10T00:12:25.706015+00:00 app[web.1]: _bytesDispatched: 456,
2018-08-10T00:12:25.706017+00:00 app[web.1]: _sockname: null,
2018-08-10T00:12:25.706019+00:00 app[web.1]: _pendingData: null,
2018-08-10T00:12:25.706020+00:00 app[web.1]: _pendingEncoding: '',
2018-08-10T00:12:25.706022+00:00 app[web.1]: server: undefined,
2018-08-10T00:12:25.706023+00:00 app[web.1]: _server: null,
2018-08-10T00:12:25.706025+00:00 app[web.1]: ssl: null,
2018-08-10T00:12:25.706027+00:00 app[web.1]: _requestCert: true,
2018-08-10T00:12:25.706028+00:00 app[web.1]: _rejectUnauthorized: true,
2018-08-10T00:12:25.706030+00:00 app[web.1]: parser: null,
2018-08-10T00:12:25.706032+00:00 app[web.1]: _httpMessage: [Circular],
2018-08-10T00:12:25.706033+00:00 app[web.1]: read: [Function],
2018-08-10T00:12:25.706035+00:00 app[web.1]: _consuming: true,
2018-08-10T00:12:25.706036+00:00 app[web.1]: _idleNext: null,
2018-08-10T00:12:25.706038+00:00 app[web.1]: _idlePrev: null,
2018-08-10T00:12:25.706040+00:00 app[web.1]: _idleTimeout: -1,
2018-08-10T00:12:25.706041+00:00 app[web.1]: [Symbol(res)]: [TLSWrap],
2018-08-10T00:12:25.706043+00:00 app[web.1]: [Symbol(asyncId)]: 11622,
2018-08-10T00:12:25.706045+00:00 app[web.1]: [Symbol(bytesRead)]: 842,
2018-08-10T00:12:25.706047+00:00 app[web.1]: [Symbol(connect-options)]: [Object] },
2018-08-10T00:12:25.706050+00:00 app[web.1]: _header: 'POST /v2.11/me/message_creatives?access_token=<ACCESS_TOKEN> HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: application/json\r\nUser-Agent: axios/0.16.2\r\nContent-Length: 54\r\nHost: graph.facebook.com\r\nConnection: close\r\n\r\n',
2018-08-10T00:12:25.706052+00:00 app[web.1]: _onPendingData: [Function: noopPendingOutput],
2018-08-10T00:12:25.706054+00:00 app[web.1]: agent:
2018-08-10T00:12:25.706056+00:00 app[web.1]: Agent {
2018-08-10T00:12:25.706057+00:00 app[web.1]: domain: null,
2018-08-10T00:12:25.706059+00:00 app[web.1]: _events: [Object],
2018-08-10T00:12:25.706061+00:00 app[web.1]: _eventsCount: 1,
2018-08-10T00:12:25.706062+00:00 app[web.1]: _maxListeners: undefined,
2018-08-10T00:12:25.706064+00:00 app[web.1]: defaultPort: 443,
2018-08-10T00:12:25.706066+00:00 app[web.1]: protocol: 'https:',
2018-08-10T00:12:25.706068+00:00 app[web.1]: options: [Object],
2018-08-10T00:12:25.706069+00:00 app[web.1]: requests: {},
2018-08-10T00:12:25.706071+00:00 app[web.1]: sockets: [Object],
2018-08-10T00:12:25.706072+00:00 app[web.1]: freeSockets: {},
2018-08-10T00:12:25.706074+00:00 app[web.1]: keepAliveMsecs: 1000,
2018-08-10T00:12:25.706076+00:00 app[web.1]: keepAlive: false,
2018-08-10T00:12:25.706077+00:00 app[web.1]: maxSockets: Infinity,
2018-08-10T00:12:25.706079+00:00 app[web.1]: maxFreeSockets: 256,
2018-08-10T00:12:25.706081+00:00 app[web.1]: maxCachedSessions: 100,
2018-08-10T00:12:25.706083+00:00 app[web.1]: _sessionCache: [Object] },
2018-08-10T00:12:25.706085+00:00 app[web.1]: socketPath: undefined,
2018-08-10T00:12:25.706086+00:00 app[web.1]: timeout: undefined,
2018-08-10T00:12:25.706088+00:00 app[web.1]: method: 'POST',
2018-08-10T00:12:25.706093+00:00 app[web.1]: path: '/v2.11/me/message_creatives?access_token=<ACCESS_TOKEN>

Примечание: места, где написано ACCESS_TOKEN, были намеренно отредактированы мной перед публикацией из соображений безопасности, так что эта часть работает нормально.

МОЙ код, который выполняет эту работу, таков:

const templates = require('./templates')
const dialogsContent = require('../dialogs-content').dialogsContent
const axios = require('axios')

class broadcastSender {

  static formatMessage (message) {
    return templates.format(message)
  }

  static async getCreativeId (message) {
    // -- The format of the message from the dialog is in a generic format
    // -- We need to format it to the Facebook format
    const formattedMessage = this.formatMessage(message)
    // -- Execute the first step to send a single Broadcast Message
    // -- Get that message's ID from Facebook
    await axios.request({
      headers: { 'Content-Type': 'application/json' },
      url: `${process.env.FB_BASE_URL}/${process.env.FB_VERSION}/me/message_creatives?access_token=${process.env.FB_ACCESS_TOKEN}`,
      method: 'post',
      data: formattedMessage,
    })
      .then(data => {
        return data.message_creative_id
      })
      .catch(error => {
        console.info(error)
      })
  }

  static async prepareCreativeIdsArray (dialogName) {
    // -- The Dialog is an array of messages
    // -- We get the Dialog and assign it to a messages array
    const messagesArray = dialogsContent.messages[dialogName]
    const IdsArray = []
    // -- Fill the array with the Ids of the BroadCast Messages
    for (const message of messagesArray) {
      const messageIdFromFacebook = await this.getCreativeId(message)
      if (!isNaN(parseInt(messageIdFromFacebook, 10))) {
        IdsArray.push(messageIdFromFacebook)
      }
    }
    return IdsArray
  }

  static async getCustomLabelId (label) {
    const labelsIdsArray = (await axios.get(`${process.env.FB_BASE_URL}/${process.env.FB_VERSION}/me/custom_labels?fields=name&access_token=${process.env.FB_ACCESS_TOKEN}`)).data.data
    for (const labelData of labelsIdsArray) {
      if (labelData.name === label) {
        return labelData.id
      }
    }
  }

  static async sendBroadcastMessage (dialogName, labelToExclude) {
    const IdsArray = await this.prepareCreativeIdsArray(dialogName)
    const customLabelId = await this.getCustomLabelId(labelToExclude)
    console.info('IDS ARRAY %s\n labelid %s', IdsArray, customLabelId)
    for (const broadcastId of IdsArray) {

      const creativeData = Object.assign({},
        {
          message_creative_id: broadcastId,
          notification_type: 'REGULAR',
          targeting: { labels: { operator: 'NOT', values: [{ customLabelId }] } },
        })
      // -- Send the message to facebook
      await axios.request({
        headers: { 'Content-Type': 'application/json' },
        url: `${process.env.FB_BASE_URL}/${process.env.FB_VERSION}/me/broadcast_messages?access_token=${process.env.FB_ACCESS_TOKEN}`,
        method: 'post',
        data: JSON.stringify(creativeData),
      })
        .then(data => {
          return data.broadcast_id
        })
        .catch(error => {
          throw error
        })
    }
  }

}

module.exports = broadcastSender

Код для функции templates.format:

  module.exports = class templates {
  static format (genericMessage) {

    let type = genericMessage.type
    const payload = genericMessage.content
    let fallback_text = ''

    const isPersonalized = /{{first_name}}/i

    if (isPersonalized.test(JSON.stringify(payload))) {
      type = 'dynamic_text'
      fallback_text = payload.replace(isPersonalized, 'buddy')
    }
    let preparedMessage

    if (type === 'carousel') {

      const carousel = []
      // NOTE: content_type supported by FB are text, location, phone number and email
      for (const cards of payload) {
        if (cards.buttons && cards.subtitle) {

          const buttonsOfCard = []
          for (const buttonTemplate of cards.buttons) {

            if (buttonTemplate.type === 'postback') {
              buttonsOfCard.push({
                type: buttonTemplate.type,
                title: buttonTemplate.title,
                payload: buttonTemplate.value,
              })
            } else if (buttonTemplate.type === 'web_url') {
              buttonsOfCard.push({
                type: buttonTemplate.type,
                title: buttonTemplate.title,
                url: buttonTemplate.url,
              })
            } else if (buttonTemplate.type === 'element_share') {
              buttonsOfCard.push({
                type: buttonTemplate.type,
              })
            }

          }
          carousel.push({
            title: cards.title,
            image_url: cards.imageUrl,
            subtitle: cards.subtitle,
            buttons: buttonsOfCard,
          })

        } else if (cards.buttons) {

          const buttonsOfCard = []
          for (const buttonTemplate of cards.buttons) {

            if (buttonTemplate.type === 'postback') {
              buttonsOfCard.push({
                type: buttonTemplate.type,
                title: buttonTemplate.title,
                payload: buttonTemplate.value,
              })

            } else if (buttonTemplate.type === 'web_url') {
              buttonsOfCard.push({
                type: buttonTemplate.type,
                title: buttonTemplate.title,
                url: buttonTemplate.url,
              })

            } else if (buttonTemplate.type === 'element_share') {
              buttonsOfCard.push({
                type: buttonTemplate.type,
              })
            }

          }
          carousel.push({
            title: cards.title,
            image_url: cards.imageUrl,
            buttons: buttonsOfCard,
          })

        } else if (cards.subtitle) {

          carousel.push({
            title: cards.title,
            image_url: cards.imageUrl,
            subtitle: cards.subtitle,
          })

        } else {

          carousel.push({
            title: cards.title,
            image_url: cards.imageUrl,
          })

        }
      }

      // Set the prepared message
      preparedMessage = JSON.stringify({
        message: [{
          attachment: {
            type: 'template',
            payload: {
              template_type: 'generic',
              elements: carousel,
            },
          },
        }],
      })

    }

    if (type === 'card') {
      const elements = payload[0]
      if (elements.buttons && elements.subtitle) {

        const buttonsOfCard = []
        for (const buttonTemplate of elements.buttons) {

          if (buttonTemplate.type === 'postback') {
            buttonsOfCard.push({
              type: buttonTemplate.type,
              title: buttonTemplate.title,
              payload: buttonTemplate.value,
            })
          } else if (buttonTemplate.type === 'web_url') {
            buttonsOfCard.push({
              type: buttonTemplate.type,
              title: buttonTemplate.title,
              url: buttonTemplate.url,
            })
          } else if (buttonTemplate.type === 'element_share') {
            buttonsOfCard.push({
              type: buttonTemplate.type,
            })
          }

        }
        payload[0] = ({
          title: elements.title,
          image_url: elements.imageUrl,
          subtitle: elements.subtitle,
          buttons: buttonsOfCard,
        })

      } else if (elements.buttons) {

        const buttonsOfCard = []
        for (const buttonTemplate of elements.buttons) {

          if (buttonTemplate.type === 'postback') {
            buttonsOfCard.push({
              type: buttonTemplate.type,
              title: buttonTemplate.title,
              payload: buttonTemplate.value,
            })

          } else if (buttonTemplate.type === 'web_url') {
            buttonsOfCard.push({
              type: buttonTemplate.type,
              title: buttonTemplate.title,
              url: buttonTemplate.url,
            })

          } else if (buttonTemplate.type === 'element_share') {
            buttonsOfCard.push({
              type: buttonTemplate.type,
            })
          }

        }
        payload[0] = ({
          title: elements.title,
          image_url: elements.imageUrl,
          buttons: buttonsOfCard,
        })

      } else if (elements.subtitle) {

        payload[0] = ({
          title: elements.title,
          image_url: elements.imageUrl,
          subtitle: elements.subtitle,
        })

      } else {

        payload[0] = ({
          title: elements.title,
          image_url: elements.imageUrl,
        })

      }

      // Set the prepared message
      preparedMessage = JSON.stringify({
        message: [{
          attachment: {
            type: 'template',
            payload: {
              template_type: 'generic',
              elements: payload,
            },
          },
        }],
      })
    }

    if (type === 'button') {

      const buttonsArray = []
      for (const buttons of payload.buttons) {

        if (buttons.type === 'postback') {
          buttonsArray.push({
            type: buttons.type,
            title: buttons.title,
            payload: buttons.value,
          })
        } else if (buttons.type === 'web_url') {
          buttonsArray.push({
            type: buttons.type,
            title: buttons.title,
            url: buttons.url,
          })
        } else if (buttons.type === 'element_share') {
          buttonsArray.push({
            type: buttons.type,
          })
        }

      }

      // Set the prepared message
      preparedMessage = JSON.stringify({
        message: [{
          attachment: {
            type: 'template',
            payload: {
              template_type: type,
              text: payload.title,
              buttons: buttonsArray,
            },
          },
        }],
      })

    } else if (type === 'quickReplies') {
      const quickRepliesArray = []
      // NOTE: content_type supported by FB are text, location, phone number 
and email
      for (const buttons of payload.buttons) {
        if (buttons.image_url) {
          quickRepliesArray.push({
            content_type: 'text',
            title: buttons.title,
            payload: buttons.value,
            image_url: buttons.image_url,
          })
        } else {
          quickRepliesArray.push({
            content_type: 'text',
            title: buttons.title,
            payload: buttons.value,
          })
        }
      }

      // Set the prepared Message
      preparedMessage = JSON.stringify({
        message: [{
          text: payload.title,
          quick_replies: quickRepliesArray,
        }],
      })
    } else if (type === 'text') {
      preparedMessage = JSON.stringify({
        message: [{ text: payload }],
      })
    } else if (type === 'dynamic_text') {
      preparedMessage = JSON.stringify({
        messages: [{
          dynamic_text: {
            text: payload,
            fallback_text,
          },
        }],
      })
    } else if (type === 'audio') {
      preparedMessage = JSON.stringify({
        message: [{
          attachment: {
            type,
            payload: {
              url: payload,
              is_reusable: true,
            },
          },
        }],
      })
    } else if (type === 'video') {
      preparedMessage = JSON.stringify({
        message: [{
          attachment: {
            type,
            payload: {
              url: payload,
              is_reusable: true,
            },
          },
        }],
      })
    } else if (type === 'image') {
      preparedMessage = JSON.stringify({
        message: [{
          attachment: {
            type,
            payload: {
              url: payload,
              is_reusable: true,
            },
          },
        }],
      })
    } else if (type === 'file') {
      preparedMessage = JSON.stringify({
        message: [{
          attachment: {
            type,
            payload: {
              url: payload,
              is_reusable: true,
            },
          },
        }],
      })
    }
    return preparedMessage
  }

}

Требуемое поведение Этот первый шаг процесса отправки широковещательного сообщения в мессенджер должен возвращать объект со свойством message_creative_id.

«Места, где написано ACCESS_TOKEN, были специально отредактированы мной перед публикацией в целях безопасности» - вы пропустили один, что означает, что вы должны в первую очередь аннулировать этот токен сейчас (например, изменив пароль учетной записи пользователя, который его предоставил)
CBroe 10.08.2018 12:04

@Cbroe, спасибо, я только что заметил. Я уже аннулировал этот токен.

Andrés Hevia 11.08.2018 19:03
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
58
1

Ответы 1

Я обнаружил ошибку, это была пропущенная буква «s» в конце «сообщения». Facebook имеет похожий формат отправки ответов пользователям, поэтому проблема возникла при использовании этого формата для широковещательных сообщений, которые вместо «message» имеют свойство, называемое «messages».

Другие вопросы по теме