الحسابات المتصلة
اربط حسابات Google وFacebook وApple Business Connect، وطابق إدراجات أنشطتها التجارية مع المواقع، وافصلها باستخدام SDK listingsapi-js.
الحساب المتصل هو تفويض OAuth يمنحه مالك حساب Google Business Profile أو صفحات Facebook أو Apple Business Connect. بمجرد وجود التفويض، يمكن للمنصة قراءة إدراجات الأنشطة التجارية التي يملكها ذلك الحساب وربط كل منها بموقع. جميع دوال الحسابات المتصلة متاحة على كائن العميل ListingsAPI.
الترتيب المعتاد هو: إنشاء رابط اتصال، وانتظار منح المالك التفويض، وسرد الحسابات للحصول على connectedAccountId، وبدء المطابقة، ومراجعة الاقتراحات، ثم تأكيدها أو ربط إدراج نشاط تجاري يدويًا. تُرجع كل دالة عند اكتمالها البيانات الموجودة ضمن مفتاح الاستجابة الخاص بها، والمذكور في القسم المقابل أدناه.
connectGoogleAccount
أنشئ رابط OAuth على مستوى الحساب بالكامل لـ Google Business Profile. وجّه المالك إلى url المُرجع؛ وسيعود إلى successUrl أو errorUrl لديك عند إغلاق شاشة الموافقة.
const link = await client.connectGoogleAccount('https://app.example.com/onboarding/google/done','https://app.example.com/onboarding/google/failed',); console.log(link.url);المعاملات
تُرجع بيانات bulkConnectLinkForGoogle: url وsuccess وerrors. تحقّق من url ولا تكتفِ بـ success، لأن إعادة التوجيه غير القابلة للاستخدام قد تُرجع نتيجة نجاح مع قيمة null في url. مدة صلاحية الرابط قصيرة، لذا أنشئ رابطًا جديدًا لكل محاولة.
connectFacebookAccount
الدالة المقابلة لـ connectGoogleAccount في صفحات Facebook، وتقبل وسيطَي إعادة التوجيه نفسيهما.
const link = await client.connectFacebookAccount('https://app.example.com/onboarding/facebook/done','https://app.example.com/onboarding/facebook/failed',); console.log(link.url);المعاملات
تُرجع بيانات bulkConnectLinkForFacebook: url وsuccess وerrors.
getOauthConnectUrl
أنشئ رابط OAuth يقتصر نطاقه على موقع واحد بدلًا من حساب كامل. استخدمه عندما تعرف مسبقًا الموقع الذي يربطه المالك وتريد إعادته إلى شاشة ذلك الموقع في منتجك.
const link = await client.getOauthConnectUrl(1800289,'GOOGLE','https://app.example.com/locations/1800289/connected','https://app.example.com/locations/1800289/connect-failed',); console.log(link.url);المعاملات
تُرجع بيانات createConnectUrl: url وsuccess وerrors. عنوانا إعادة التوجيه مطلوبان ويجب أن يكونا مطلقين. الرابط صالح للاستخدام مرة واحدة ومرتبط بالموقع الذي حددته.
fetchConnectedAccounts
اسرد حسابات Google وFacebook المفوَّضة ضمن حسابك، مع حالة سلامة الاتصال وأعداد المواقع المرتبطة. من هنا تحصل على connectedAccountId الذي تحتاج إليه كل دالة لاحقة.
const page1 = await client.fetchConnectedAccounts({publisher: 'GoogleAccount',status: 'Connected',page: 1,perPage: 20,}); for (const record of page1.records ?? []) {console.log(record.email, record.connectedAccountId, record.status);}الخيارات
تُرجع بيانات connectedAccountsInfo: مصفوفة records بالإضافة إلى pageInfo الذي يتضمن hasNextPage وhasPreviousPage وtotalPages وtotalRecords. يحتوي كل سجل على connectedAccountId وemail وconnectedAccountType وconnectedLocationsCount وconnectivityIssue وstatus وrequestMatchesStatus.
لا يستخدم عامل التصفية والحقل مجموعة القيم نفسها. يقبل الخيار status القيم 'Connected' أو 'NotConnected' أو 'ConnectionIssue'، بينما تكون قيمة status في السجل نفسه هي CONNECTED أو MATCH_IN_PROGRESS أو CONNECTIVITY_ISSUE. يُرفض تمرير قيمة السجل بوصفها قيمة عامل التصفية.
fetchConnectedAccountDetails
اقرأ حسابًا واحدًا باستخدام معرّفه. هذه الدالة أقل تكلفة من تصفّح جميع صفحات القائمة عندما يكون المعرّف متاحًا لديك بالفعل، وهي الدالة التي تُستدعى دوريًا أثناء تشغيل المطابقة.
const details = await client.fetchConnectedAccountDetails('4f712c17-4f95-42dd-90f4-97171a2e67b5',); console.log(details.details.requestMatchesStatus); // MATCH_IN_PROGRESS, then MATCH_COMPLETEDالمعاملات
تُرجع بيانات connectedAccountDetails، التي تتضمن السجل ضمن details بالحقول نفسها التي تُرجعها القائمة. راقب requestMatchesStatus لمعرفة متى تصبح الاقتراحات جاهزة، واقرأ status وconnectivityIssue لتحديد ما إذا كان ينبغي طلب إعادة التفويض.
fetchConnectedAccountFolders
اسرد مجموعات حساب Google (المجلدات) التي يمكن للحساب المتصل الوصول إليها. استدعِ هذه الدالة قبل createGmbListing عندما يريد المالك وضع إدراج النشاط التجاري الجديد في مجموعة محددة.
const folders = await client.fetchConnectedAccountFolders('4f712c17-4f95-42dd-90f4-97171a2e67b5',); for (const folder of folders) {console.log(folder.folderId, folder.folderName, folder.locationCount);} // Narrow by nameconst matching = await client.fetchConnectedAccountFolders('4f712c17-4f95-42dd-90f4-97171a2e67b5',{ folderName: 'West Region' },);الخيارات
تُرجع مصفوفة getFoldersUnderGoogleAccount، وتكون مصفوفة فارغة افتراضيًا. يحتوي كل مجلد على folderId (سلسلة نصية بصيغة accounts/<id> تمرّرها دون تغيير) وfolderName وlocationCount، الذي قد تكون قيمته null عندما لا يُبلغ Google عن عدد. هذا المسار صالح فقط للحسابات من نوع Google.
fetchConnectedAccountListings
اسرد إدراجات الأنشطة التجارية لدى منصات النشر التي يمكن للحساب المتصل الوصول إليها. قيمة id في كل سجل هي بالضبط قيمة connectedAccountListingId التي تقبلها connectListing، وبذلك يمكنك إنشاء واجهة لاختيار إدراج نشاط تجاري.
const listings = await client.fetchConnectedAccountListings('4f712c17-4f95-42dd-90f4-97171a2e67b5',{ locationInfo: 'William St', page: 1, perPage: 50 },); for (const record of listings.records ?? []) {console.log(record.id, record.locationName, record.address);}الخيارات
تُرجع بيانات connectedAccountListings: records بالإضافة إلى pageInfo. يحتوي كل سجل على id وlocationName وaddress وphone وliveLink وaccountTypeName. رغم أن الطلب الأساسي يتخذ صيغة طلب كتابة، فهذه عملية قراءة: تضع SDK معرّف الحساب ومعاملات تقسيم النتائج إلى صفحات في جسم الطلب تلقائيًا، وفقًا لما تتطلبه نقطة النهاية.
triggerConnectedAccountMatches
أضف إلى قائمة الانتظار المهمة التي تجلب كل ملف تعريفي يمكن للحسابات المحددة الوصول إليه وتطابق هذه الملفات مع مواقعك. استدعِ هذه الدالة فور انتهاء المالك من شاشة الموافقة، ومرة أخرى بعد إنشاء المواقع دفعة واحدة.
const result = await client.triggerConnectedAccountMatches(['4f712c17-4f95-42dd-90f4-97171a2e67b5',]); console.log(result.success, result.failedIds);المعاملات
تُرجع بيانات connectedAccountsTriggerMatches: success وfailedIds. تعني قيمة true في success أن المهمة أُضيفت إلى قائمة الانتظار، ولا تعني أن المطابقة اكتملت. استدعِ fetchConnectedAccountDetails دوريًا حتى تصبح قيمة requestMatchesStatus هي MATCH_COMPLETED، ثم اقرأ الاقتراحات.
fetchConnectionSuggestions
اقرأ أزواج المطابقة الناتجة، ليتمكن المشغّل من مقارنة كل موقع بإدراج النشاط التجاري لدى منصة النشر قبل إجراء أي ربط.
const suggestions = await client.fetchConnectionSuggestions('4f712c17-4f95-42dd-90f4-97171a2e67b5',{ page: 1, perPage: 50 },); for (const record of suggestions.records ?? []) {console.log(record.accountType, record.matchedDataDatabaseId, record.locationInfo.name);}الخيارات
تُرجع بيانات connectionSuggestionsForAccount: records بالإضافة إلى pageInfo. لا يحتوي سجل الاقتراح على حقل id. معرّفه هو matchedDataDatabaseId، ويحدد accountType (GMB أو FB أو APPLE) نوع سجل المطابقة. احتفظ بالقيمتين معًا، لأن confirmConnectedAccountMatches يحتاج إليهما لإنشاء المعرّف الذي يقبله. يُرجع الحساب الذي لا توجد له مطابقات بعد مصفوفة records فارغة.
confirmConnectedAccountMatches
اقبل أزواج المطابقة التي تمت مراجعتها. يربط التأكيد كل موقع بإدراج نشاطه التجاري لدى منصة النشر، بحيث تُطبَّق عليه تحديثات الموقع اللاحقة.
أنشئ كل معرّف من سجل اقتراح: صِل اسم نوع سجل المطابقة بقيمة matchedDataDatabaseId في السجل باستخدام نقطتين رأسيتين، ثم رمّز الناتج باستخدام base64. يقابل GMB النوع GmbLocationMatchedData، ويقابل FB النوع FbLocationMatchedData، ويقابل APPLE النوع AppleLocationMatchedData.
const TYPES: Record<string, string> = {GMB: 'GmbLocationMatchedData',FB: 'FbLocationMatchedData',APPLE: 'AppleLocationMatchedData',}; const matchRecordId = (record: any) =>Buffer.from(TYPES[record.accountType] + ':' + record.matchedDataDatabaseId).toString('base64'); const approved = (suggestions.records ?? []).map(matchRecordId);const result = await client.confirmConnectedAccountMatches(approved); console.log(result.success, result.failedIds);المعاملات
تُرجع بيانات confirmConnectMatches: success وfailedIds. تحقّق من success في كل استدعاء: إذا لم ينتج عن فك ترميز المعرّف أحد الأنواع الثلاثة، تُرجع الدالة استجابة بصيغة استجابة نجاح، بقيمة false في success ودون failedIds. عند فشل بعض المعرّفات، يحتوي failedIds على معرّفات قاعدة البيانات بعد فك ترميزها، وليس على القيم المرمَّزة التي أرسلتها، لذا طابقها مع matchedDataDatabaseId.
ربط إدراج نشاط تجاري واحد بموقع واحد
تُكمل 3 طرق الربط بين إدراج نشاط تجاري واحد تمت مطابقته وموقع واحد، وهي موثّقة مع بقية نقاط نهاية إدراجات الأنشطة التجارية لتجنب تكرار توثيقها:
- connectListing تربط إدراج نشاط تجاري تمت مطابقته بموقع.
- disconnectListing تفك هذا الربط.
- createGmbListing تنشئ ملفًا جديدًا على Google Business Profile لموقع ليس لديه ملف، داخل مجلد من fetchConnectedAccountFolders.
استخدم هذه الطرق بعد أن تعالج confirmConnectedAccountMatches معظم عناصر الحساب، إذا ظل هناك متجر واحد يحتاج إلى ربط يدوي.
oauthDisconnect
هذه هي عملية قطع الاتصال نفسها لموقع واحد، ويمكن الوصول إليها عبر مسار OAuth الخاص بكل موقع. تقبل الوسائط نفسها وتُرجع الحمولة نفسها، لذا اختر الاسم الأنسب في شيفرتك.
await client.oauthDisconnect(1800289, 'GOOGLE');المعلمات
تُرجع حمولة disconnectConnectedAccountsLocations، بالمفتاح نفسه الذي تُرجعه disconnectListing.
disconnectGoogleAccount
تقطع اتصال حساب Google بالكامل: يتوقف كل موقع مرتبط من خلاله عن تلقي التحديثات. استخدمها عندما يتوقف عميل عن استخدام الخدمة أو ينقل الملكية.
await client.disconnectGoogleAccount('4f712c17-4f95-42dd-90f4-97171a2e67b5');المعلمات
تُرجع حمولة gmbBulkDisconnect، التي تتضمن success. تشمل هذه العملية الحساب بالكامل ولا يمكن تطبيقها جزئيًا: لفك ربط موقع واحد مع الاحتفاظ بالحساب، استخدم disconnectListing. تُرجع success بقيمة true حتى إذا كان المعرّف غير معروف، لذا اقرأ fetchConnectedAccounts بعد ذلك إذا كنت بحاجة إلى التأكد.
disconnectFacebookAccount
الطريقة المقابلة لـ Facebook، وتقبل الوسيط نفسه وتنطبق على الحساب بالكامل بالطريقة نفسها دون إمكانية تطبيقها جزئيًا.
await client.disconnectFacebookAccount('9d2b5a41-0c7e-4f83-bb16-2ac43e70d915');المعلمات
تُرجع حمولة fbBulkDisconnect، التي تتضمن success. ينطبق التحفظ نفسه: تُفيد العملية بالنجاح حتى إذا كان المعرّف غير معروف، لذا تحقّق باستخدام fetchConnectedAccounts.
سير عمل الإعداد الأولي المعتاد
import { ListingsAPI } from 'listingsapi-js'; const client = new ListingsAPI(); // reads LISTINGSAPI_KEY from env // 1. Send the owner through the consent screenconst link = await client.connectGoogleAccount('https://app.example.com/onboarding/google/done','https://app.example.com/onboarding/google/failed',);console.log('open:', link.url); // 2. After they return, pick up the account IDconst accounts = await client.fetchConnectedAccounts({ publisher: 'GoogleAccount' });const accountId = accounts.records[0].connectedAccountId; // 3. Match its listings against your locationsawait client.triggerConnectedAccountMatches([accountId]); // 4. Poll until matching finisheslet details = await client.fetchConnectedAccountDetails(accountId);while (details.details.requestMatchesStatus !== 'MATCH_COMPLETED') {await new Promise((resolve) => setTimeout(resolve, 5000));details = await client.fetchConnectedAccountDetails(accountId);} // 5. Read the suggestions and confirm the approved onesconst suggestions = await client.fetchConnectionSuggestions(accountId, { perPage: 100 });console.log('found ' + (suggestions.records ?? []).length + ' suggested matches');موارد ذات صلة
- إدراجات الأنشطة التجارية، طرق الربط وفك الربط نفسها في سياق إدراجات الأنشطة التجارية
- المواقع، البحث عن معرّفات المواقع
- معالجة الأخطاء، الأخطاء ذات الأنواع المحددة التي تطرحها كل طريقة
- نقاط نهاية الحسابات المتصلة، شرح خطوات REST التي تستند إليها هذه الطرق
- ربط Google واستيراد المواقع، دليل الإعداد الأولي الكامل
- ربط صفحات Facebook، النسخة الخاصة بـ Facebook
- إنشاء ملف على Google Business Profile، دليل
createGmbListing - مرجع REST: سرد الحسابات، تفاصيل الحساب، المجلدات، إدراجات الأنشطة التجارية في الحساب، بدء عمليات المطابقة، اقتراحات الربط، تأكيد المطابقات، ربط إدراج نشاط تجاري، فك ربط إدراج نشاط تجاري