连接 Facebook 公共主页

创建 Facebook 连接链接,将所有者的公共主页与您的地点匹配,确认或手动选择关联,并在客户离开时断开账号连接。

连接 Facebook 账号后,即可为地点启用 Facebook 发布和报告功能。关联公共主页后,帖子可以在 postSites 中以 FACEBOOK 为目标,Facebook 分析端点会返回公共主页指标,而不再返回 null,该公共主页会被添加为评价来源,其评价将与其他评价一起接收,并且该地点的高级商家信息中的 Facebook 行也不再处于 REQUIRING_ACTION 状态。

流程与 Google 相同:创建链接,让所有者授权,进行匹配,然后确认。Facebook 使用的值如有不同,会另行说明。

Facebook 公共主页必须已在 Facebook 上设置营业时间。如果公共主页没有营业时间,Facebook 会拒绝 ListingsAPI 对该公共主页的更新,即使地点已有 businessHours 也是如此。此时,Facebook 商家信息会保持 IN_PROGRESS 状态,并带有一条说明缺少营业时间的 syncIssue。要解决此问题,请在 Facebook 上为该公共主页添加营业时间,然后发送地点更新。

请求体仅包含您的 2 个重定向 URL。该链接只对密钥所属的账户有效,有效期为 24 小时。

Connect link
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connect-facebook \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "successUrl": "https://app.example.com/connect/facebook/success",    "errorUrl": "https://app.example.com/connect/facebook/error"  }}'
JSON
{  "data": {    "bulkConnectLinkForFacebook": {      "success": true,      "url": "https://connect.example.com/oauth?token=8f3c1d92-...",      "errors": null    }  }}

上面的 url 是占位符。请将所有者引导至您自己的响应中返回的 url。

将所有者重定向至 url。所有者接受 Facebook 的条款、授予公共主页权限后,会进入您的 successUrl。

2. OAuth 返回后列出已连接的账号

按 publisher=FacebookAccount 筛选。这是采用偏移量分页的结果:包含 records[] 和 pageInfo.totalRecords,使用 page 和 perPage 分页。

List accounts
curl "https://listingsapi.com/api/v4/connected-accounts?publisher=FacebookAccount&page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "connectedAccountsInfo": {      "pageInfo": { "hasNextPage": false, "totalRecords": 1 },      "records": [        {          "connectedAccountId": "d2397854-52c2-41d7-95f1-b90cba16498d",          "connectedAccountType": "FacebookAccount",          "status": "CONNECTED",          "requestMatchesStatus": "MATCH_COMPLETED",          "connectedLocationsCount": 0        }      ]    }  }}

保留 connectedAccountId。status 的值为 CONNECTED、MATCH_IN_PROGRESS 或 CONNECTIVITY_ISSUE;只要不是 CONNECTED,所有者就必须重新授权,后续步骤才能正常执行。

3. 触发匹配并等待完成

匹配过程会获取该账号可访问的公共主页,并将每个公共主页与您的一个地点配对。该过程在后台运行,因此请轮询账号详情,直到 requestMatchesStatus 为 MATCH_COMPLETED。在此之前读取建议会返回空的 records 数组,看起来像是“没有匹配项”。

Trigger and poll
curl -X POST https://listingsapi.com/api/v4/connected-accounts/trigger-matches \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "connectedAccountIds": ["d2397854-52c2-41d7-95f1-b90cba16498d"] } }' # then, every 15 seconds until requestMatchesStatus is MATCH_COMPLETEDcurl https://listingsapi.com/api/v4/connected-accounts/d2397854-52c2-41d7-95f1-b90cba16498d/details \-H "Authorization: API $LISTINGSAPI_KEY"

详情记录在 data.connectedAccountDetails.details 处返回。MATCH_COMPLETED 表示匹配程序已完成;在您确认之前,不会建立任何关联,因此 connectedLocationsCount 暂时仍为 0。

4. 查看并确认建议

每条记录将您的地点(locationInfo、locationId)与一个公共主页(suggestedLocationInfo)配对。对于 Facebook 账号,accountType 为 FB,而非 GMB,因此您发送用于确认的 id 也会有所不同。

Suggestions
curl "https://listingsapi.com/api/v4/connected-accounts/d2397854-52c2-41d7-95f1-b90cba16498d/connection-suggestions?page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY"

建议中没有 id。根据 accountType 选择类型,对 <MatchRecordType>:<matchedDataDatabaseId> 做 base64 编码即可得到该 ID。参考文档仅展示了一个 Google 示例,解码后为 GmbLocationMatchedData:...;不同发布平台使用的类型不同。对于 Facebook,类型为 FbLocationMatchedData,因此 FB 与 0d5e306f-0da0-46e3-929f-fd3c67ccd8cc 组合后的编码结果为 RmJMb2NhdGlvbk1hdGNoZWREYXRhOjBkNWUzMDZmLTBkYTAtNDZlMy05MjlmLWZkM2M2N2NjZDhjYw==。

accountType匹配记录类型
GMBGmbLocationMatchedData
FBFbLocationMatchedData
APPLEAppleLocationMatchedData
Confirm matches
# base64 of FbLocationMatchedData:0d5e306f-0da0-46e3-929f-fd3c67ccd8cccurl -X POST https://listingsapi.com/api/v4/connected-accounts/confirm-matches \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "matchRecordIds": ["RmJMb2NhdGlvbk1hdGNoZWREYXRhOjBkNWUzMDZmLTBkYTAtNDZlMy05MjlmLWZkM2M2N2NjZDhjYw=="] } }'

响应为 data.confirmConnectMatches,包含 success 和 failedIds,后者是无法确认的已解码数据库 id。使用错误类型构造的 id 会返回 200,其中包含 success: false,但不包含 failedIds,因此请务必检查 success。

当匹配程序无法确定匹配结果,或公共主页是在匹配运行后创建的,请列出该账号可见的公共主页,并直接关联其中一个。connectedAccountId 应放在商家信息调用的 JSON 请求体中;如果作为查询参数传递,它会被忽略,您将获得第一个已连接账号的商家信息。

Pick and link
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connected-account-listings \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "connectedAccountId": "d2397854-52c2-41d7-95f1-b90cba16498d", "locationInfo": "Lincoln" }' curl -X POST https://listingsapi.com/api/v4/connected-accounts/connect-listing \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "locationId": "TG9jYXRpb246MTgwMDI4OQ==",    "connectedAccountId": "d2397854-52c2-41d7-95f1-b90cba16498d",    "connectedAccountListingId": "<id from the listings response>"  }}'

每条商家信息记录都包含 id、locationName、address 和 liveLink。其中的 id 就是 connect-listing 接受的 connectedAccountListingId;该字段不叫 listingId。关联失败时会返回 success: false,并带有一个 message,例如 Listing record not found。

6. 在客户离开时断开账号连接

断开连接会作用于整个账号:通过该账号关联的所有公共主页都会停止同步,也不再接收 Facebook 互动。要在保留账号连接的同时解除某个地点的关联,请改用 disconnect-listing。

Disconnect
curl -X POST https://listingsapi.com/api/v4/connected-accounts/disconnect-facebook \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "connectedAccountId": "d2397854-52c2-41d7-95f1-b90cba16498d" } }'

响应为 data.fbBulkDisconnect,并包含 success。即使 connectedAccountId 未知,响应也仍为 true,因此它表示“已处理”,而非“已移除有效连接”。如果您需要确认,请再次列出已连接账户。

7. 接下来会发生什么

每个已关联的地点都会触发一个带有 data.platform: "facebook" 的 connection.location_connected 事件,解除关联时则会触发 connection.location_disconnected。如果 Facebook 撤销授权,您会收到 connection.reauth_required:请创建新链接(步骤 1),并请所有者重新同意授予全部权限。关联完成后,地点的高级商家信息中的 Facebook 行会变为 SYNCED,postSites: ["FACEBOOK"] 会成为有效目标,Facebook 分析端点也会开始返回数据。

后续步骤