將貼文發布至 Google 和 Facebook
發布公告、活動和優惠,排程將一則貼文發布至多個地點,確認貼文已在各網站上線,管理地點的貼文,並處理貼文 webhook。
貼文是顯示在地點的 Google Business Profile 或 Facebook 粉絲專頁上的附日期卡片,類型包括公告、活動或優惠。第一次呼叫會建立貼文,發布作業會在背景執行,第二次呼叫則會告知您各網站是否已接受貼文。
這三種貼文類型皆使用 POST /posts,並將主體包在 input 中。未包裝的主體會遭到拒絕,並傳回 400。SDK 會建立包裝結構,並在傳送前驗證承載資料。
1. 發布公告
公告包含訊息,以及選用的按鈕和圖片。
curl -X POST https://listingsapi.com/api/v4/posts \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "postName": "Grand Opening Announcement", "locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="], "postType": "ANNOUNCEMENT", "postSites": ["GOOGLE"], "postMessage": [ { "site": "GOOGLE", "message": "We are now open! Visit us this week for our grand opening." } ], "postCta": [ { "site": "GOOGLE", "type": "LEARN_MORE", "url": "https://acmekitchen.example.com/opening" } ], "postMediaUrl": [ { "site": "GOOGLE", "url": "https://cdn.example.com/opening.jpg", "type": "IMAGE" } ] }}'{ "data": { "createSocialPost": { "success": true, "errors": [], "socialPost": { "id": "U29jaWFsUG9zdDo0NDEyMg==", "name": "Grand Opening Announcement", "status": "INPROGRESS", "type": "ANNOUNCEMENT", "sites": ["GOOGLE"], "publishDetails": [ { "site": "GOOGLE", "status": "PUBLISHING", "createdDate": "2026-06-28", "submissionError": null } ], "postLinks": [], "locationIds": [1800289] } } }}請保留 socialPost.id。status 的初始值為 INPROGRESS,而 postLinks 在有網站接受貼文之前會維持空白;步驟 5 會讀取這兩者。
2. 發布活動
活動會加入 postContextInfo,其中包含 title、startDay、endDay,以及選用的顯示時間。Google 會拒絕沒有標題的活動,而 SDK 會在缺少標題時,於傳送前拋出 ValidationError。
curl -X POST https://listingsapi.com/api/v4/posts \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "postName": "Summer Sale Kickoff Event", "locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="], "postType": "EVENT", "postSites": ["GOOGLE"], "postContextInfo": { "title": "Summer Sale Kickoff", "startDay": "2026-07-15", "startTime": "10:00am", "endDay": "2026-07-15", "endTime": "06:00pm" }, "postMessage": [ { "site": "GOOGLE", "message": "Join us for the Summer Sale kickoff: refreshments, giveaways, and up to 40% off in store." } ] }}'回應的結構與步驟 1 相同,並在 socialPost.contextInfo 下傳回 type: "EVENT" 和日期。postContextInfo 儲存活動本身的日期;postScheduledDates(步驟 4)則控制貼文本身的發布和下架時間。
3. 發布優惠
優惠的 postContextInfo 包含 title、couponCode、discount、redeemUrl、termsConditions,以及有效期間 startDay 和 endDay。在 Facebook 上請搭配 GET_OFFER 按鈕,在 Google 上則搭配 ORDER 按鈕;沒有 REDEEM 類型。
curl -X POST https://listingsapi.com/api/v4/posts \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "postName": "Summer 25% Off", "locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="], "postType": "OFFER", "postSites": ["GOOGLE"], "postContextInfo": { "title": "25% off storewide", "couponCode": "SUMMER25", "discount": "25%", "redeemUrl": "https://acmekitchen.example.com/summer", "termsConditions": "Valid in store only through July 6. Cannot be combined with other offers.", "startDay": "2026-06-22", "endDay": "2026-07-06" }, "postMessage": [ { "site": "GOOGLE", "message": "Celebrate with us: 25% off everything in store this week." } ] }}'回應會在 socialPost.contextInfo 下傳回優惠欄位,並根據有效期間設定 scheduledStartDate 和 scheduledEndDate。
4. 排程將一則貼文傳送至多個地點
POST /bulk-posts 接受相同的 input,並將一個行銷活動傳送至 locationIds 中的每個 id。加入 postScheduledDates,並提供 ISO-8601 格式的 startDatetime 和 endDatetime,即可延後發布並自動下架;此時貼文會以 SCHEDULED 狀態建立。若各網站需要不同語氣,請分別提供訊息。
curl -X POST https://listingsapi.com/api/v4/bulk-posts \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "postName": "July Reopening Announcement", "locationIds": ["TG9jYXRpb246MTgwMDI4OQ==", "TG9jYXRpb246MTgwMDI5MA=="], "postType": "ANNOUNCEMENT", "postSites": ["GOOGLE", "FACEBOOK"], "postMessage": [ { "site": "GOOGLE", "message": "We are back! Visit us this week for our summer menu." }, { "site": "FACEBOOK", "message": "We are back! Swing by for the new summer menu." } ], "postScheduledDates": { "startDatetime": "2026-07-10T09:00:00Z", "endDatetime": "2026-07-24T23:59:00Z" } }}'大量貼文端點傳回的結構與 POST /posts 相同,因此回應也以 createSocialPost 為鍵,包含 status: "SCHEDULED",並在 locationIds 中包含兩個 id。若有驗證問題,會傳回 200,其中包含 success: false 和已有內容的 errors 陣列;SDK 會為此拋出 ValidationError。使用 GET /bulk-posts/{postId} 讀取大量行銷活動,回應會額外提供各地點的狀態。
5. 檢查發布狀態並收集貼文連結
GET /posts/{postId} 會在 socialPostView 下傳回行銷活動。建立後,請輪詢此端點,直到 socialPostInfo.status 不再是 INPROGRESS,再讀取 publishDetails[] 以取得各網站的結果,並讀取 postLinks[] 以取得已上線貼文的 URL。每次輪詢請間隔數十秒;429 會附帶 Retry-After。
curl https://listingsapi.com/api/v4/posts/U29jaWFsUG9zdDo0NDEyMg== \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "socialPostView": { "socialPostInfo": { "id": "U29jaWFsUG9zdDo0NDEyMg==", "status": "SUCCESS", "views": 128, "clicks": 14, "publishDetails": [ { "site": "GOOGLE", "status": "PUBLISHED", "publishedDate": "2026-06-28", "submissionError": null } ], "postLinks": [ { "site": "GOOGLE", "link": "https://www.google.com/maps/place/?post=44122" } ] }, "socialPostAnalyticsBySite": [ { "site": "GOOGLE", "views": 128, "clicks": 14, "reactions": 3, "shares": 0, "comments": 1 } ] } }}views、clicks、reactions、shares 和 comments 會累計在同一筆記錄中,並在 socialPostAnalyticsBySite 中依網站分列。SDK 會直接傳回 socialPostInfo,因此範例會讀取 post.status。
6. 列出地點的貼文並刪除其中一則
GET /locations/{locationId}/posts 是以位移量分頁的結果(page、perPage 上限為 50),包含所有涵蓋該地點的行銷活動,位於 postsByLocation 下,並附有 records[] 和 pageInfo.totalRecords。請原樣傳入 base64 id;請勿將其 URL 編碼。由於沒有類型篩選條件,請在您自己的程式碼中從 type 挑出優惠或活動。步驟 4 的多地點行銷活動由 GET /locations/{locationId}/bulk-posts 另行列出。
DELETE /posts/{postId} 會移除此處的行銷活動,並將其從所有已發布的網站下架。此操作無法復原,因此請先從清單中確認 id。
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/posts?page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY" curl -X DELETE https://listingsapi.com/api/v4/posts/U29jaWFsUG9zdDo0NDEyMg== \-H "Authorization: API $LISTINGSAPI_KEY"刪除操作會回傳 data.deleteSocialPost,並附上 success: true 和已移除的 socialPostId。若刪除的 id 已不存在,則會改為回傳附有 data: null 的 errors 回應,因此很容易偵測到重複刪除。
7. 回應貼文 webhook
在 /dashboard/webhooks 設定 webhook URL 後,四種事件會涵蓋貼文的生命週期,且皆使用標準承載資料。這些事件會按地點觸發,而非按行銷活動觸發:向 20 個地點大量發布貼文,會產生 20 個 post_item_id 值,並共用一個 post_id。
function handle(payload: { event: string; location_id: string; data: Record<string, unknown> }) {if (!payload.event.startsWith('local_post.')) return; const key = String(payload.data.post_item_id); // one row per locationswitch (payload.event) { case 'local_post.published': markLive(key, payload.location_id, payload.data.post_external_id); break; case 'local_post.rejected': markRejected(key, payload.location_id, payload.data.rejection_reason); break; case 'local_post.deleted': markDeleted(key); break;}}published_url 通常不存在,因此若您需要可點擊的連結,請持續依照步驟 5 輪詢以取得 postLinks。請在 5 秒內回傳 200;系統不會重試。接收端與簽章驗證請參閱使用 webhook 回應事件。
後續步驟
- 連結 Google 並匯入地點和連結 Facebook 粉絲專頁:各網站的先決條件。
- 擷取商家檔案分析資料:商家檔案層級的瀏覽次數與互動資料,可搭配此處每則貼文的計數資料使用。
- 使用 webhook 回應事件:接收這些事件的接收端。
- 參考資料:建立公告貼文、建立活動貼文、建立優惠貼文、建立大量貼文、取得貼文、擷取地點的貼文、刪除貼文。