الصور
أرفق شعارًا وصورة غلاف وصور معرض بموقع، وميّز الصورة الرئيسية بنجمة، واحذف الملفات القديمة باستخدام SDK الخاص بـ listingsapi-js.
تُرفق الصور بموقع عبر عنوان URL متاح للعامة: تستضيف أنت الصورة، وتجلبها المنصة وتخزنها، ثم تحصل عليها منصات النشر من هناك. يحتفظ الموقع بشعار واحد وصورة غلاف واحدة وأي عدد من الصور الإضافية، ويمكن تمييز 4 منها بنجمة كحد أقصى. تتوفر جميع دوال الصور في مثيل العميل ListingsAPI، ويقتصر نطاقها على معرّف موقع. تُرمَّز معرّفات المواقع الرقمية تلقائيًا، لذا يمكن استخدام 1800289 و'TG9jYXRpb246MTgwMDI4OQ==' بالتبادل.
لعمليات الرفع شكلان من النجاح. تُخزَّن الدفعة الصغيرة مباشرةً وتُعاد الوسائط بعد اكتمال معالجتها؛ أما الدفعة الكبيرة فتُضاف إلى قائمة الانتظار، وتحصل على معرّف طلب للاستعلام عن حالته دوريًا. حدّد مسار التنفيذ بناءً على وجود request.requestId بدلًا من حساب عدد صورك.
fetchLocationPhotos
اسرد جميع ملفات الوسائط المرفقة بموقع: الشعار وصورة الغلاف والصور الإضافية. استدعِ هذه الدالة قبل الرفع لمعرفة ما ينقص، ولجمع معرّفات الصور التي تقبلها دالتا التمييز بنجمة والإزالة.
const photos = await client.fetchLocationPhotos(1800289); for (const p of photos) {console.log(p.id, p.categoryName, p.starred, p.url);}المعاملات
تُرجع عند اكتمالها المصفوفة mediaFilesOfLocation، وتكون مصفوفة فارغة افتراضيًا. يحتوي كل ملف على id وurl وthumbnailUrl وcategoryName (Logo أو Cover أو Additional) وcategoryId وfileType وstarred وviewsCount. إذا لم يكن للموقع أي وسائط، تُرجع الدالة مصفوفة فارغة، وهذه هي الاستجابة المعتادة لموقع أُنشئ حديثًا وليست خطأً.
addLocationPhotos
أرفق صورة واحدة أو أكثر بموقع. يحتاج كل عنصر إلى عنوان URL لصورة JPEG أو PNG يمكن الوصول إليه علنًا في photo، بالإضافة إلى الموضع المخصص للصورة في type.
const result = await client.addLocationPhotos(1800289, [{ photo: 'https://cdn.example.com/brightsmile/logo.png', type: 'LOGO' },{ photo: 'https://cdn.example.com/brightsmile/storefront.jpg', type: 'ADDITIONAL' },]); if (result.request?.requestId) {// Queued: poll fetchPhotoUploadStatus with this idconsole.log('queued', result.request.requestId);} else {for (const p of result.photos ?? []) { console.log('stored', p.id, p.type);}}خيارات الصور
المعاملات
تُرجع عند اكتمالها محتوى addLocationPhotos: success وphotos وrequest وerrors وclientMutationId. عند معالجة الرفع مباشرةً، يحتوي photos على الوسائط الجديدة مع id وdatabaseId وurl وthumbnailUrl وtype وstarred لكل منها، ويكون request كائنًا فارغًا. عند إضافة الرفع إلى قائمة الانتظار، يكون photos فارغًا وتُعيَّن قيمة request.requestId. كلتا الحالتين تعنيان النجاح.
يجب أن تكون الصور بصيغة JPEG أو PNG، وتُطبَّق قواعد الحجم الخاصة بمنصة النشر على كل موضع. يحتفظ الموقع بشعار واحد وصورة غلاف واحدة، لذا فإن إعادة رفع أي منهما تستبدل الصورة الموجودة. حدّد type بعناية: ADDITIONAL هو الموضع المخصص لصور المعرض.
fetchPhotoUploadStatus
استعلم دوريًا عن حالة عملية الرفع المضافة إلى قائمة الانتظار حتى تصل إلى حالة نهائية. استخدم request.requestId الذي أعاده addLocationPhotos.
let job = await client.fetchPhotoUploadStatus('e6c2d9d9-9a18-4015-88cf-9a4e19a6f49a'); while (job.status === 'PROCESSING') {await new Promise((resolve) => setTimeout(resolve, 5000));job = await client.fetchPhotoUploadStatus('e6c2d9d9-9a18-4015-88cf-9a4e19a6f49a');} for (const p of job.photos ?? []) {if (p.status === 'ERROR') { console.log('rejected:', p.errorMessage);}}المعاملات
يحتوي المحتوى المُعاد على requestId، وعلى status للمهمة بقيمة PROCESSING أو SUCCESS أو ERROR، وعلى مصفوفة photos يحتوي كل عنصر فيها على mediaId وlocationId وstatus الخاص به وerrorMessage.
يشير status للمهمة إلى انتهاء المعالجة، ولا يعني أن كل الصور قد خُزِّنت. قد تظل المهمة ذات القيمة SUCCESS تحتوي على صور مرفوضة، لذا بمجرد خروجها من PROCESSING، مرّ على photos واقرأ كل عنصر. انتظر بضع ثوانٍ بين الاستعلامات: فالاستعلام المتكرر دون انتظار يؤدي سريعًا إلى تقييد معدل الطلبات. استعلم فقط عن معرّفات ناتجة عن عملية رفع حديثة، لأن المعرّف المنتهي الصلاحية لا يصل أبدًا إلى حالة نهائية.
starLocationPhotos
ميّز الصور الإضافية بنجمة لمنحها أولوية الظهور على منصات النشر التي تدعم الصور المميزة، أو أزل النجمة عنها بتمرير false.
// Feature a photoconst result = await client.starLocationPhotos(1800289,['TWVkaWFGaWxlOjU4Nzg5MzI='],true,); console.log(result.success, result.photos[0].starred); // Reverse itawait client.starLocationPhotos(1800289, ['TWVkaWFGaWxlOjU4Nzg5MzI='], false);المعاملات
تُرجع عند اكتمالها محتوى starUnstarLocationPhotos: success وphotos وكائن error واحد بدلًا من مصفوفة errors. تحتوي كل صورة مُعادة على id وdatabaseId وurl وthumbnailUrl وtype وقيمة starred الجديدة الخاصة بها.
يمكن تمييز الصور من نوع ADDITIONAL فقط بنجمة؛ فالشعار وصورة الغلاف صورتان أساسيتان بالفعل. يمكن أن يحتوي الموقع على 4 صور مميزة بنجمة كحد أقصى، ويشمل التحقق الصور المميزة بنجمة بالفعل بالإضافة إلى الصور المحددة في استدعائك، لذا فإن تجاوز 4 صور يؤدي إلى فشل الطلب بأكمله.
removeLocationPhotos
أزل ارتباط الصور بموقع باستخدام معرّفاتها. استخدم هذه الدالة لإزالة صور المعرض القديمة أو للتراجع عن عملية استيراد غير صحيحة.
const result = await client.removeLocationPhotos(1800289, ['TWVkaWFGaWxlOjU4Nzg5MzI=',]); console.log(result.removedCount); // 1المعاملات
تُرجع عند اكتمالها محتوى removeLocationPhotos: removedCount وerrors وclientMutationId. إذا كانت قيمة removedCount تساوي 0 وكانت قيمة errors هي null، فهذا يعني أن أيًا من المعرّفات التي أرسلتها لم يكن مرتبطًا بذلك الموقع، وبهذه الطريقة يمكنك اكتشاف المعرّفات التي أُزيلت سابقًا.
يمكن هنا إزالة الصور من نوع ADDITIONAL فقط. لاستبدال شعار أو صورة غلاف، ارفع صورة جديدة بدلًا منها. تؤدي إزالة الوسائط إلى إزالة ارتباطها بالموقع؛ ولا تؤدي بالضرورة إلى حذف الملف نهائيًا من مكتبة وسائط الحساب.
تحديث معتاد لمعرض الصور
import { ListingsAPI } from 'listingsapi-js'; const client = new ListingsAPI(); // reads LISTINGSAPI_KEY from envconst LOCATION_ID = 1800289; // Brightsmile Dental // 1. See what is already attachedconst existing = await client.fetchLocationPhotos(LOCATION_ID);const hasLogo = existing.some((p) => p.categoryName === 'Logo'); // 2. Upload only what is missing, plus the new hero shotconst uploaded = await client.addLocationPhotos(LOCATION_ID, [...(hasLogo ? [] : [{ photo: 'https://cdn.example.com/brightsmile/logo.png', type: 'LOGO' as const }]),{ photo: 'https://cdn.example.com/brightsmile/hero-2026.jpg', type: 'ADDITIONAL' as const },]); // 3. Feature the new hero shotconst hero = (uploaded.photos ?? []).find((p) => p.type === 'ADDITIONAL');if (hero) {await client.starLocationPhotos(LOCATION_ID, [hero.id], true);} // 4. Retire last season's imagesconst stale = existing.filter((p) => p.categoryName === 'Additional' && !p.starred).map((p) => p.id);if (stale.length > 0) {const removed = await client.removeLocationPhotos(LOCATION_ID, stale);console.log('removed ' + removed.removedCount + ' stale photos');}موارد ذات صلة
- المواقع، البحث عن معرّفات المواقع
- معالجة الأخطاء، أخطاء ذات أنواع محددة تطرحها كل دالة
- تحميل شعار وصورة غلاف وصور، الشرح الكامل خطوة بخطوة
- مرجع REST: جلب الصور، تحميل الصور، حالة التحميل الجماعي، تمييز الصور بنجمة، إزالة الصور