كيفية رفع الكتالوج الخاص بك إلى SiteChat
إذا كنت تستخدم SiteChat على موقعك الإلكتروني الخاص (وليس متجر Shopify)، فيمكنك إرسال سجلات منتجات منظَّمة إلى Shoply حتى يتمكن المتسوقون من العثور عليها في دردشة SiteChat وبحث المنتجات.
تستخدم نقاط النهاية هذه نفس Settings → Store owner API secret مثل بقية Shoply Merchant API، ويمكن لصفحة Product Catalog في لوحة إدارة SiteChat استدعاءها باستخدام رمز وصول المسؤول الخاص بك عند تسجيل الدخول. تستمر متاجر Shopify في مزامنة بيانات الكتالوج عبر Shopify؛ ومسارات الرفع هذه متاحة فقط لحسابات SiteChat التي لا تقوم بالفعل بمزامنة كتالوج Magento.
في لوحة إدارة SiteChat، تفتح Product Catalog مساحة بأسلوب Shopify تضم Products وCollections وInventory. يمكنك إضافة المنتجات أو تعديلها، واستيراد CSV/Excel، وتجميع المنتجات في مجموعات يدوية، وضبط كميات المخزون.
ما واجهات برمجة التطبيقات المتاحة؟
| API | Method | ما الذي تفعله |
|---|---|---|
/merchant/products/batch | POST | إنشاء ما يصل إلى 50 منتجًا أو استبدالها بالكامل في طلب واحد |
/merchant/products | POST | إنشاء منتج واحد أو استبداله بالكامل |
/merchant/products | GET | قراءة منتج واحد تم استيراده باستخدام source وexternal_id |
/merchant/products | PATCH | تحديث جزئي لمنتج واحد؛ ويتطلب استبدال المتغيرات أو metafields الإصدار القادم من GET |
/merchant/products | DELETE | أرشفة المنتج أرشفةً مؤقتة (status=archived) |
/merchant/products/list | GET | التنقّل بين صفحات المنتجات المستوردة في جداول الإدارة |
/merchant/products/images | POST | رفع صورة منتج واستلام عنوان URL عام عبر HTTPS |
/merchant/collections | GET / POST | عرض المجموعات اليدوية أو إنشاؤها |
/merchant/collections/{id} | GET / PUT / DELETE | قراءة مجموعة واحدة أو استبدالها أو أرشفتها |
/merchant/inventory | GET | عرض صفوف المخزون (كميات المنتجات والمتغيرات) |
/merchant/inventory/adjust | POST | تعيين الكمية المتتبعة لمنتج أو متغير |
تطلب عمليات حفظ المنتجات الناجحة من Shoply إعادة بناء فهرس المتجر. وحتى يكتمل ذلك، تُظهر الاستجابات index_status: "pending". وبعد ذلك تظهر المنتجات المنشورة في كلٍّ من فهرس المنتجات والمعرفة المستخدمة بواسطة دردشة SiteChat.
من يمكنه استخدام واجهات برمجة التطبيقات هذه؟
- يجب أن يكون متجرك حساب SiteChat (
app_platformهو SiteChat). - يتم رفض مفاتيح متاجر Shopify (بما في ذلك أي نطاق
*.myshopify.com). - يجب أن تستخدم المصادقة إما سرًّا صالحًا لواجهة برمجة تطبيقات مالك المتجر أو رمز وصول مسؤول SiteChat لنفس
store_keyالموجود في الطلب. - لا يمكن لرموز Shopify Admin API استدعاء هذه المسارات.
أنشئ سرّ المالك أو قم بتدويره بالطريقة نفسها المستخدمة مع تكاملات Merchant API الأخرى: How to Use the Shoply Merchant API. وفي وحدة تحكم إدارة SiteChat، افتح Product Catalog لإدارة المنتجات والمجموعات والمخزون — أو لاستيراد ملف CSV أو Excel — دون الحاجة إلى إدارة السرّ بنفسك.
كيف تعمل المصادقة؟
من موصل خادم
استدعِ واجهة برمجة التطبيقات من خلفية موثوقة عبر HTTPS. ضع سلسلة JSON في ترويسة Authorization:
{
"store_key": "YOUR_SITECHAT_STORE_KEY",
"store_owner_api_secrete": "YOUR_STORE_OWNER_API_SECRET"
}store_owner_api_secrete هو اسم الحقل العام، بما في ذلك التهجئة التاريخية. كما أن store_owner_api_secret مقبول أيضًا. هذا ليس رمز Bearer.
من لوحة إدارة SiteChat
ترسل صفحة Product Catalog جلسة المسؤول المسجَّل دخولُه بدلًا من ذلك:
{
"store_key": "YOUR_SITECHAT_STORE_KEY",
"admin_auth_token": "YOUR_SITECHAT_ACCESS_TOKEN"
}يُقبل access_token كاسم بديل لـ admin_auth_token.
يجب أن تتطابق قيمة معلَمة الاستعلام store_key مع الترويسة. احتفظ بأسرار المالك في متغيرات بيئة على جانب الخادم فقط — ولا تضعها أبدًا في نص برمجي للواجهة، أو في عنوان URL، أو في مستودع عام.
export SHOPLY_STORE_KEY="your-sitechat-store-key"
export SHOPLY_STORE_OWNER_API_SECRETE="shoply_owner_key_example123.secret-value"كيف أرفع المنتجات؟
POST https://api.shoplyai.ai/merchant/products/batch?store_key=YOUR_SITECHAT_STORE_KEY
{
"source": "woocommerce-main",
"products": [
{
"external_id": "123",
"title": "Trail shoes",
"description": "Water-resistant hiking shoes.",
"url": "https://example.com/products/trail-shoes",
"currency": "USD",
"price": "49.95",
"original_price": "59.95",
"available": true,
"status": "published",
"images": ["https://example.com/images/trail-shoes.jpg"],
"categories": ["Footwear"],
"metafields": {"material": "Leather"},
"variants": [
{
"external_id": "124",
"title": "Brown / 42",
"sku": "TRAIL-BR-42",
"price": "49.95",
"available": true,
"metafields": {"color": "Brown", "size": "42"}
}
]
}
]
}الحقول المطلوبة والقواعد
- حقول المنتج المطلوبة:
external_idوtitleوurlوcurrencyوpriceوavailable. تكون القيمة الافتراضية لـstatusهيpublished. - المخزون اختياري: اضبط
tracks_inventoryعلىtrueوحددquantityغير سالبة على المنتج أو المتغير. عندها يستنتج Shoply التوفر من المخزون (quantity > 0) ويخزنtotal_inventoryلقوائم الإدارة. - يحدّد
sourceاتصال الكتالوج (وليس بالضرورة منصة). استخدم اسمًا ثابتًا مثلwoocommerce-main. الأحرف المسموح بها: حروف صغيرة وأرقام وشرطات سفلية وشرطات عادية، حتى 64 حرفًا. المنتجات التي تُنشأ من النماذج في لوحة الإدارة يكون مصدرها الافتراضيadmin. - هوية المنتج هي مزيج من المتجر والمصدر والمعرّف الخارجي. عمليتا batch و
POSTالفردي من نوع upsert هما استبدال كامل وليستا patch: يتم مسح الحقول الاختيارية المحذوفة. استخدمPATCHللتحديثات الجزئية. - تحتوي الدُفعات على 1–50 منتجًا وبحد أقصى 2,000,000 بايت للطلب. يقتصر JSON المتحقق منه لكل منتج على 128,000 بايت، وبحد أقصى 250 متغيرًا.
- يُفضَّل استخدام سلاسل عشرية للأسعار. ويجب أن تكون العملة رمزًا مكوّنًا من ثلاثة أحرف كبيرة.
- يجب أن تكون عناوين URL للمنتجات والصور من نوع HTTP(S). لا تقوم عملية الاستيراد بجلب تلك العناوين نيابةً عنك.
- استخدم
metafieldsالعامة لمواصفات المنتجات القابلة للبحث (وهي المقابل في SiteChat لحقول Shopify product metafields). يجب أن تكون القيم سلاسل نصية عادية. كما يُقبلattributesالقديم كاسم بديل. لم يعدmetadataالخاص بالمنتج مدعومًا. - تُستبعَد منتجات
draftوarchivedمن الفهرس المنشور التالي. أما المنتجات المنشورة النافدة من المخزون فتبقى مفهرسة مع إرفاق حالة التوفر. - تخزّن المجموعات اليدوية عنوانًا ووصفًا وحالةً وقائمة بعضوية المنتجات (
source+external_id). لا يتم دعم المجموعات الذكية/القائمة على القواعد في هذا الإصدار.
مثال على استجابة نجاح
{
"results": [
{
"external_id": "123",
"product_id": "sitechat_product::woocommerce-main::<sha256-of-external-id>",
"status": "stored"
}
],
"index_status": "pending",
"index_revision": 1
}يتحقق Shoply من الطلب بالكامل قبل الكتابة. ويمكن أن تتضمن استجابة HTTP 200 مع ذلك بعض النتائج failed مع error: "storage_error". افحص كل نتيجة وأعد محاولة المنتجات الفاشلة. وإذا كانت index_status هي request_failed، فهذا يعني أن التخزين نجح لكن لم تتم جدولة الفهرسة — لذا أعد محاولة المنتجات المخزنة أيضًا.
مثال Python
import json
import os
import requests
store_key = os.environ["SHOPLY_STORE_KEY"]
headers = {
"Authorization": json.dumps({
"store_key": store_key,
"store_owner_api_secrete": os.environ["SHOPLY_STORE_OWNER_API_SECRETE"],
})
}
response = requests.post(
"https://api.shoplyai.ai/merchant/products/batch",
params={"store_key": store_key},
headers=headers,
json={
"source": "custom",
"products": [{
"external_id": "123",
"title": "Trail shoes",
"url": "https://example.com/products/trail-shoes",
"currency": "USD",
"price": "49.95",
"available": True,
}],
},
timeout=60,
)
response.raise_for_status()
result = response.json()
failed = [item["external_id"] for item in result["results"] if item["status"] != "stored"]
if failed:
raise RuntimeError(f"Products need retry: {failed}")
if result["index_status"] == "request_failed":
raise RuntimeError("Products saved, but retry the batch to request indexing")كيف أتحقق من منتج مستورد؟
GET https://api.shoplyai.ai/merchant/products?store_key=YOUR_SITECHAT_STORE_KEY&source=woocommerce-main&external_id=123
استخدم ترويسة Authorization نفسها. تتضمن الاستجابة schema_version وupdated_at وindex_status وproduct بعد التسوية. وتُرجع السجلات غير الموجودة HTTP 404.
بعد أن ينشر المفهرِس في الخلفية إعادة البناء، تصبح حالة القراءة الراجعة لكل منتج indexed أو excluded (للمنتجات من نوع draft أو archived) أو limit_exceeded. استخدم GET /merchant/products/list لسرد المنتجات في لوحة الإدارة. ونفّذ أرشفة مؤقتة باستخدام DELETE /merchant/products (أو عيّن status إلى archived / draft) لإبقاء المنتج خارج الفهرس المنشور التالي؛ ولا يوجد حذف نهائي في هذا الإصدار.
record = requests.get(
"https://api.shoplyai.ai/merchant/products",
params={
"store_key": store_key,
"source": "woocommerce-main",
"external_id": "123",
},
headers=headers,
timeout=30,
)
record.raise_for_status()
print(record.json()["index_status"], record.json()["product"]["title"])كيف أحدّث المتغيرات أو Metafields بأمان؟
بالنسبة إلى طلب PATCH يحتوي على variants أو metafields أو الحقل القديم attributes، اقرأ المنتج أولًا باستخدام GET. أنشئ التعديل انطلاقًا من تلك الاستجابة، وأدرج قيمة updated_at ذات المستوى الأعلى كـ expected_updated_at في جسم PATCH. وينطبق ذلك أيضًا عند مسح المتغيرات أو metafields.
current_response = requests.get(
"https://api.shoplyai.ai/merchant/products",
params={"store_key": store_key, "source": "woocommerce-main", "external_id": "123"},
headers=headers,
timeout=30,
)
current_response.raise_for_status()
current = current_response.json()
updated_metafields = {**current["product"].get("metafields", {}), "material": "Leather"}
response = requests.patch(
"https://api.shoplyai.ai/merchant/products",
params={"store_key": store_key},
headers=headers,
json={
"source": "woocommerce-main",
"external_id": "123",
"expected_updated_at": current["updated_at"],
"metafields": updated_metafields,
},
timeout=30,
)
response.raise_for_status()يعني HTTP 409 أن الإصدار كان مفقودًا أو أن تحديثًا آخر غيّر المنتج. اقرأ أحدث نسخة من المنتج وادمج التغييرات المقصودة مرة أخرى قبل إعادة المحاولة. لا تُرفق إصدارًا جديدًا بقائمة متغيرات قديمة: فقد يؤدي ذلك إلى الكتابة فوق قيم مخزون أحدث.
يجب تحديث التكاملات الحالية التي تُجري PATCH لهذه الحقول دون إصدار. أما طلبات PATCH التي تقتصر على القيم scalar فقط، وتعديلات المخزون المخصصة، والاستبدالات الكاملة عبر POST أو الاستيراد على دفعات، فلا تتطلب هذا الحقل. ومع ذلك، تظل الاستبدالات الكاملة تستبدل المنتج بأكمله.
هل يمكنني رفع صور المنتجات؟
نعم. إذا كانت الصورة متاحة بالفعل على عنوان URL عام دائم عبر HTTPS، فضع ذلك العنوان في قائمة images الخاصة بالمنتج أو في الحقل image الخاص بمتغير. تعمل عناوين S3 العامة عبر HTTPS. أما المسارات الخام s3:// وعناوين URL الموقعة قصيرة العمر فلا تعمل.
لكي يستضيف Shoply الملف، ارفع بايتات الصورة الخام من الخلفية لديك:
POST https://api.shoplyai.ai/merchant/products/images?store_key=YOUR_SITECHAT_STORE_KEY
Content-Type: image/pngأرسل بايتات الملف الخام، وليس JSON أو base64 أو multipart form data. يتم قبول JPEG وPNG وWebP، حتى 10 MiB و20 million pixels. الصور المتحركة غير مدعومة. يحوّل Shoply الصورة إلى WebP ويزيل البيانات الوصفية المضمّنة.
with open("trail-shoes.png", "rb") as image_file:
response = requests.post(
"https://api.shoplyai.ai/merchant/products/images",
params={"store_key": store_key},
headers={**headers, "Content-Type": "image/png"},
data=image_file,
timeout=60,
)
response.raise_for_status()
image_url = response.json()["url"]تعيد HTTP 201 القيم url وcontent_type وsize_bytes وwidth وheight. لا يؤدي رفع صورة وحدها إلى إرفاقها بمنتج أو طلب الفهرسة. أدرج عنوان URL المُعاد في منتج كامل ثم أرسله مرة أخرى عبر /merchant/products/batch.
إذا رُفعت الصورة نفسها مرة أخرى للحساب نفسه، فسيُعاد استخدام عنوان URL الخاص بها. أما إذا تغيّرت الصورة فستحصل على عنوان URL جديد. ولا توجد نقطة نهاية لحذف الصور في هذا الإصدار.
متى تظهر المنتجات في الدردشة والبحث؟
بعد نجاح حفظ الدفعة، يطلب Shoply إعادة بناء الفهرس في الخلفية. تعرض الاستجابات index_status: "pending" حتى ينشر العامل الفهرس الجديد. ولا يوجد ضمان ثابت لوقت الإكمال.
- تدخل المنتجات المنشورة في كلٍّ من بحث المنتجات والمعرفة المستخدمة بواسطة دردشة SiteChat.
- تُستبعد المنتجات draft وarchived في إعادة البناء التالية.
- إذا لم تتم جدولة الفهرسة (
index_status: "request_failed")، فأعد محاولة الدفعة للمنتجات التي تم تخزينها بنجاح بالفعل.
ما الأخطاء التي ينبغي أن أتوقعها؟
| HTTP status | المعنى |
|---|---|
403 | سرّ مفقود أو غير صالح أو منتهي الصلاحية أو مُلغى؛ أو متجر خاطئ؛ أو حساب ليس من نوع SiteChat |
404 | المنتج المستورد المطلوب غير موجود |
413 | الطلب أو الصورة يتجاوز حد الحجم |
415 | تم رفع الصورة باستخدام Content-Type غير مدعوم |
422 | حقول غير صالحة، أو معرّفات مكررة، أو صور متحركة أو كبيرة جدًا، أو تجاوز حدود النموذج |
503 | فشل مؤقت في التخزين |
تنتهي صلاحية الأسرار بعد 90 days. أنشئ بديلًا في Settings → Store owner API secret قبل انتهاء الصلاحية، وألغِ أي سرّ لم تعد بحاجة إليه. ويمكن للسرّ نفسه أيضًا استدعاء نقاط نهاية التحليلات والمحادثات والمعرفة الموثقة في Merchant API guide.
للمساعدة في التكامل، تواصل مع Shoply AI.
