المنشورات
كل نقاط نهاية المنشورات بأمثلة cURL وPython وNode: إعلانات وفعاليات وعروض، جدولة وحملات لكل موقع وجماعية، استعلام دوري عن الحالة وحذف.
المنشور هو تحديث قصير يُنشر على Google Business Profile أو صفحة Facebook الخاصة بموقع: إعلان، أو فعالية محددة التاريخ، أو عرض يتضمن قسيمة. يمكن لحملة واحدة استهداف مواقع متعددة وكلتا المنصتين في آن واحد. النشر غير متزامن، لذا يعيد كل استدعاء إنشاء استجابته فورًا، وتستعلم دوريًا عن النتيجة. تعمل نقاط النهاية الثلاث GET باستخدام مفتاح Read (قراءة)؛ ويتطلب الإنشاء والحذف مفتاح Write (كتابة).
نقاط النهاية في لمحة
القيم التي ستستخدمها في كل موضع
تستخدم جميع نقاط نهاية الإنشاء أنواع التعداد الأربعة أدناه.
نشر إعلان
POST /posts
يتطلب الإعلان رسالة، ويمكن اختياريًا إضافة زر واحد وصورة واحدة لكل منصة. وفّر عنصر postMessage واحدًا لكل منصة مدرجة في postSites. تعيد الاستجابة الحملة الجديدة مع تعيين status إلى INPROGRESS، لأن النشر يجري في الخلفية.
المعاملات
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://jennyhome.example/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. فهو معرّف المنشور بترميز base64 الذي تحتاج إليه كل نقطة نهاية أخرى هنا. تأخذ كلتا الدالتين المساعدتين في SDK سلسلة نصية واحدة message وتحوّلانها إلى عنصر واحد لكل منصة، لذا لا تحتاج إلى إنشاء مصفوفة postMessage يدويًا إلا في cURL.
نشر فعالية
POST /posts
تُعرض الفعالية كبطاقة محددة التاريخ. يوجد الجدول الزمني للفعالية نفسها في postContextInfo. يتحكم الكائن المنفصل postScheduledDates في موعد ظهور المنشور نفسه وانتهاء صلاحيته، وتكون هذه الفترة عادةً هي الفترة التي تسبق الفعالية. ترفض Google أي فعالية بلا عنوان، وتُصدر كلتا حزمتَي SDK خطأ تحقق قبل الإرسال إذا كان title مفقودًا.
المعاملات
ينطبق أيضًا كل ما ورد في جدول الإعلان.
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 and up to 40 percent off in store." } ] }}'{ "data": { "createSocialPost": { "success": true, "socialPost": { "id": "U29jaWFsUG9zdDo0NDEyMw==", "status": "INPROGRESS", "type": "EVENT", "scheduledStartDate": "2026-07-15", "scheduledEndDate": "2026-07-15", "contextInfo": { "title": "Summer Sale Kickoff", "startDay": "2026-07-15", "startTime": "10:00am", "endDay": "2026-07-15", "endTime": "06:00pm" } } } }}تمثل قيمة contextInfo المُعادة الفترة الزمنية للفعالية. يصف scheduledStartDate وscheduledEndDate الجدول الزمني للمنشور نفسه، الذي يطابق تواريخ الفعالية هنا لأن postScheduledDates لم يُرسل.
نشر عرض
POST /posts
العرض بطاقة ترويجية تتضمن رمز قسيمة وخصمًا ورابطًا للاستفادة من العرض وشروطًا. توضع كل هذه التفاصيل في postContextInfo، ويحدد startDay مع endDay فترة صلاحية العرض لا المنشور.
المعاملات
curl -X POST https://listingsapi.com/api/v4/posts \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "postName": "Festive 25 Percent Off", "locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="], "postType": "OFFER", "postSites": ["GOOGLE"], "postContextInfo": { "title": "25% off storewide", "couponCode": "FESTIVE25", "discount": "25%", "redeemUrl": "https://jennyhome.example/festive", "termsConditions": "Valid in-store only through July 6.", "startDay": "2026-06-22", "endDay": "2026-07-06" }, "postMessage": [ { "site": "GOOGLE", "message": "Celebrate with us, 25 percent off everything in store this week." } ], "postCta": [ { "site": "GOOGLE", "type": "GET_OFFER", "url": "https://jennyhome.example/festive" } ] }}'{ "data": { "createSocialPost": { "success": true, "socialPost": { "id": "U29jaWFsUG9zdDo0NDEyNA==", "status": "INPROGRESS", "type": "OFFER", "contextInfo": { "title": "25% off storewide", "couponCode": "FESTIVE25", "discount": "25%", "startDay": "2026-06-22", "endDay": "2026-07-06" } } } }}يستخدم Google القيمة ORDER ويستخدم Facebook القيمة GET_OFFER لأزرار العروض. إذا انتهى عرض ترويجي مبكرًا، فاحذف الحملة بدلًا من تعديلها.
قراءة منشور واحد وحالته
GET /posts/{postId}
يعيد نتيجة النشر لحملة مقبولة. تتضمن الاستجابة، ضمن data.socialPostView، محتوى الحملة ومدخلًا في publishDetails لكل موقع وعدادات التفاعل وروابط المنشور على المنصات بعد نجاح النشر.
المعاملات
curl https://listingsapi.com/api/v4/posts/U29jaWFsUG9zdDo0NDEyMg== \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "socialPostView": { "socialPostId": "U29jaWFsUG9zdDo0NDEyMg==", "socialPostInfo": { "status": "SUCCESS", "type": "ANNOUNCEMENT", "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" } ] }, "publishedLocationsCount": 1, "socialPostAnalyticsBySite": [ { "site": "GOOGLE", "views": 128, "clicks": 14, "reactions": 3, "shares": 0, "comments": 1 } ] } }}هناك حقلان مهمان للحالة، ويجيب كل منهما عن سؤال مختلف.
قد تكون حالة الحملة SUCCESS بينما تكون حالة أحد المواقع ضمنها ERROR، لذا تحقق دائمًا من publishDetails بدلًا من الاكتفاء بالحالة على المستوى الأعلى.
عرض قائمة المنشورات الخاصة بموقع
GET /locations/{locationId}/posts
سجل مقسّم إلى صفحات باستخدام الإزاحة لكل حملة تشمل موقعًا واحدًا، ضمن data.postsByLocation. استخدمه لتدقيق ما هو منشور بالفعل قبل جدولة محتوى جديد.
المعاملات
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/posts?page=1&perPage=10" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "postsByLocation": { "records": [ { "id": "U29jaWFsUG9zdDo0NDEyMg==", "name": "Summer Hours Update", "status": "SUCCESS", "type": "ANNOUNCEMENT", "createdAt": "2026-06-28", "views": 128, "clicks": 14, "sites": ["GOOGLE"] } ], "pageInfo": { "totalPages": 1, "hasNextPage": false, "totalRecords": 1 } } }}لا يدعم هذا المسار التصفية على جانب الخادم. يقبل فقط page وperPage، ويتجاهل أي شيء آخر، لذا اقرأ type وstatus في كل سجل ونفّذ التصفية في التعليمات البرمجية الخاصة بك. وللفرز والتصفية على جانب الخادم، استخدم بدلًا من ذلك نقطة نهاية عرض القائمة المجمّعة أدناه.
حذف منشور
DELETE /posts/{postId}
الحذف دائم، ويلغي نشر المنشور من كل موقع وصل إليه. لا يمكن التراجع عن الحذف ولا توجد نقطة نهاية للتعديل، لذا فإن تصحيح منشور متاح يعني حذفه ونشر بديل له.
المعاملات
curl -X DELETE https://listingsapi.com/api/v4/posts/U29jaWFsUG9zdDo0NDEyMg== \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "clientMutationId": "delete-44122-req-1" }'{ "data": { "deleteSocialPost": { "success": true, "socialPostId": "U29jaWFsUG9zdDo0NDEyMg==" } }}تؤدي محاولة حذف منشور غير معروف أو محذوف بالفعل إلى إرجاع استجابة خطأ تكون فيها قيمة data مضبوطة على null بدلًا من success: false.
نشر حملة واحدة عبر مواقع متعددة
POST /bulk-posts
يستخدم مواصفات POST /posts نفسها، وهو مصمم لمجموعات المواقع: أدرج كل موقع في locationIds لتشملها جميعًا حملة واحدة. توضع الاستجابة تحت المفتاح createSocialPost، كما في POST /posts.
المعاملات
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" } }}'{ "data": { "createSocialPost": { "success": true, "errors": null, "socialPost": { "id": "U29jaWFsUG9zdDo5OTIwMQ==", "name": "July Reopening Announcement", "status": "SCHEDULED", "type": "ANNOUNCEMENT", "scheduledStartDate": "2026-07-10", "scheduledEndDate": "2026-07-24", "sites": ["GOOGLE", "FACEBOOK"], "locationIds": [1800289, 1800290] } } }}تضبط الدالتان المساعدتان في حزمتَي SDK القيمة الافتراضية لـ sites على Google وFacebook، وتوسّعان لك خريطة الرسائل المخصصة لكل موقع، وترمّزان معرّفات المواقع الرقمية، لذا يكون النشر المجمّع عادةً أقصر استدعاء في أيٍّ من حزمتَي SDK.
قراءة حملة جماعية واحدة
GET /bulk-posts/{postId}
النظير الجماعي لـ GET /posts/{postId}. يُرجع البنية نفسها، مع قيمة publishedLocationsCount أكبر من 1 وتفصيل للتحليلات حسب المتجر في socialPostAnalyticsByLocationId.
المعاملات
curl https://listingsapi.com/api/v4/bulk-posts/U29jaWFsUG9zdDo1MTA4OA== \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "socialPostView": { "socialPostId": "U29jaWFsUG9zdDo1MTA4OA==", "socialPostInfo": { "name": "Festive Offer - All Stores", "status": "SUCCESS", "type": "OFFER", "views": 4210, "clicks": 318, "sites": ["GOOGLE", "FACEBOOK"] }, "socialPostAnalyticsByLocationId": [ { "locationId": 1800289, "siteStats": [ { "site": "GOOGLE", "status": "PUBLISHED", "views": 1040, "clicks": 80 }, { "site": "FACEBOOK", "status": "PUBLISHED", "views": 360, "clicks": 26 } ] } ] } }}يجمع socialPostAnalyticsBySite إجماليات الحملة عبر جميع المتاجر، بينما يفصّل socialPostAnalyticsByLocationId الأرقام نفسها حسب المتجر. افحص قيم status لكل متجر للعثور على أي متجر فشل النشر له على إحدى المنصات.
سرد الحملات الجماعية في موقع
GET /locations/{locationId}/bulk-posts
تُقسَّم النتائج إلى صفحات باستخدام الإزاحة ضمن data.rollupSocialPosts. بخلاف القائمة الخاصة بكل موقع، يقبل هذا المسار عوامل التصفية والفرز، مما يجعله نقطة النهاية المناسبة للوحة التحكم بالحملات.
المعاملات
الحقول التي يمكن الفرز حسبها هي name وtype وstatus وcreated_at وschedule_start_date وschedule_end_date وclient_name وclicks وviews وshares.
curl -G https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/bulk-posts \-H "Authorization: API $LISTINGSAPI_KEY" \--data-urlencode 'page=1' \--data-urlencode 'perPage=10' \--data-urlencode 'sortFields={"field":"created_at","order":"Descending"}'{ "data": { "rollupSocialPosts": { "records": [ { "id": "U29jaWFsUG9zdDo1MTA4OA==", "name": "Festive Offer - All Stores", "status": "SUCCESS", "type": "OFFER", "createdAt": "2026-06-20", "views": 4210, "clicks": 318 } ], "pageInfo": { "totalPages": 1, "hasNextPage": false, "totalRecords": 1 } } }}تتولى كلتا حزمتَي SDK ترميز الكائنين filters وsortFields بصيغة JSON نيابةً عنك، لذا مرّرهما كقواميس أو كائنات أصلية في لغة البرمجة.
الأخطاء التي ستواجهها
القائمة الكاملة في رموز الأخطاء.
الخطوات التالية
- نشر المنشورات: النسخة الموجّهة لتنفيذ المهمة من هذه الصفحة، مع شرح حملة مجدولة من البداية إلى النهاية.
- التحقق من حالة إدراج النشاط التجاري والروابط المنشورة: تأكد من أن الموقع منشور على Google قبل نشر منشور له.
- ربط Google واستيراد المواقع: يحتاج الموقع إلى حساب متصل قبل أن يقبل أي موقع إلكتروني منشورًا.
- الاستجابة للأحداث باستخدام webhooks: تحل أحداث
local_postمحل الاستعلام الدوري عن نتائج النشر. - مرجع المنشورات للاطلاع على القائمة الكاملة للحقول في كل نقطة نهاية مذكورة أعلاه.