نقدّم لكم حزم SDK الخاصة بـ SupDesk
كل منتج جاد يصل في نهاية المطاف إلى كتابة طبقة تكامل — سكربت يقرأ من صندوق الوارد، أو وظيفة cron تزامن لوحة عمل، أو نقطة نهاية ترصد الملاحظات القادمة من واجهتك الخاصة.
وحدة تحكّم SupDesk ممتازة عندما تكون أمام لوحة المفاتيح، لكن ما إن تريد أتمتة الأمر حتى تحتاج إلى API، ولا تكون API أفضل من العملاء المتاحين للحديث إليها.
واليوم نُطلق أربعة منها.
تعرّف على حزم SDK
- JavaScript / TypeScript — حزمة
supdeskعلى npm. تعمل دون أي تعديل على Node 18+ وDeno وBun وCloudflare Workers، ودون أي تبعيات في وقت التشغيل. - Python — حزمة
supdeskعلى PyPI. عميل متزامن واحدSupDeskوعميل غير متزامن واحدAsyncSupDeskيتشاركان نواة httpx واحدة. - Go — حزمة
github.com/rabinapps/supdesk-go. المكتبة القياسية فقط، لذلك تُبنى في أي مكان يعمل فيه Go 1.23+ — بما في ذلك Cloudflare Workers عبرGOOS=wasip1. - Dart — حزمة
supdeskعلى pub.dev. مبنية على dio، لذلك تعمل الاعتراضات وCancelTokenومحوّلات الوكلاء (proxy adapters) بالطريقة التي تتوقعها أصلًا.
التثبيت
npm install supdeskpip install supdeskgo get github.com/rabinapps/supdesk-godependencies:
supdesk: ^0.1.0API واحدة، أربع لغات
الحزم ليست أربع طبقات تغليف منفصلة؛ بل هي نفس API بنفس الدلالات في كل لغة. إذا تمكنت من قراءة الإرساليات بلغة واحدة، فستقرؤها باللغات الأربع جميعًا.
الترقيم التلقائي. يُرجع list() صفحة هي أيضًا متكرِّر غير متزامن (async iterable) — تجوّل عبر كل الصفحات باستخدام for await، أو اسحب الصفحة الأولى فقط عندما يكون هذا كل ما تحتاجه.
الموارد الموجّهة بالأنواع. الإرساليات والملاحظات ومدخلات سجل التغييرات والرسائل والتسجيلات في قائمة الانتظار وبرامج الاختبار التجريبي والمختبرين ومقالات مركز المساعدة وتصنيفاته — كلٌّ منها بالطرق والمعاملات الموجّهة بالأنواع التي تتوقعها، بحيث تفشل الأخطاء المطبعية وقت الترجمة بدلًا من بيئة الإنتاج.
الأخطاء الموجّهة بالأنواع. ينحدر كل فشل من أساس واحد — SupDeskError في JS وPython، وAPIError في Go، وSupDeskException في Dart — فيكفي catch واحد للتعامل معها جميعًا بينما يظل instanceof أو errors.As يحدد الحالة الخاصة بدقة.
Webhooks. تتحقق constructEventFromRequest وconstruct_event_from_headers وConstructEvent وconstructEventFromHeaders من توقيع SupDesk في وقت ثابت، حتى تطمئن إلى ما يتصرف بناءً عليه المتلقي لديك.
مرونة مدمجة. يعيد كل عميل المحاولة مع تأجيل أُسّي وتشتيت (jitter)، ويحترم Retry-After، ولا يعيد أبدًا محاولة طلب POST مُقاس ربما يكون قد قبله بالفعل — فلا تستطيع شبكة متقلبة أن تُكرّر إرسال تذكرة المستخدم.
صُممت من جهة الخادم
تصادق مفاتيح SupDesk للـ API على هوية مشروعك بالكامل، لذلك ترفض الحزم العمل في المتصفح — ترمي مُنشئات JS وDart استثناءً إذا رصدت وجود DOM أو بناءً مخصصًا للعميل، وتكون ملفات README صريحة في توضيح السبب. أبقِ المفتاح في متغير بيئة من جهة الخادم، خلف نقطة نهاية تتحكم فيها.
أمران آخران جديران بالمعرفة: تعمل القراءات على كل الخطط، بينما تتطلب الكتابات (POST/PATCH/DELETE) خطة مدفوعة؛ والمفاتيح مقيّدة بالمشروع، لذلك امنح كل بيئة مفتاحها الخاص وستتمكن من إبطال واحد منها دون المساس بالباقي.
أين يتناسب SupDesk
تُشكّل الحزم النصف الخلفي من دليل دمج SupDesk لمنتجات SaaS — دعم متعدد المستأجرين، ووصول عبر API، وwebhooks للمنتجات التي تريد دعمًا مدمجًا في أنظمتها الخاصة. والمرجع الكامل موجود في توثيق API.
ابدأ الآن
احصل على مفتاح API من إعدادات مساحة العمل ← مفاتيح API، وثبّت العميل المناسب لتقنيتك، ونفّذ دليل البدء السريع في هذه الصفحة. ثم استنسخ المستودع واقرأ ملف README.
أدوات SDK من جانب الخادم لتكامل الواجهة الخلفية
أمثلة برمجية مباشرة مأخوذة من مستودع GitHub لكل SDK.
import { SupDesk } from "supdesk";
const supdesk = new SupDesk({ apiKey: process.env.SUPDESK_API_KEY! });
// Auto-pages: iterating walks every page for you.
for await (const submission of await supdesk.submissions.list({
status: "open",
})) {
console.log(submission.title);
}
await supdesk.submissions.create({
type: "bug",
title: "Export button does nothing",
email: "user@example.com",
body: "Clicking Export on the reports page has no effect.",
});from supdesk import SupDesk
supdesk = SupDesk() # api_key=... or $SUPDESK_API_KEY
# Auto-pages: iterating walks every page for you.
for submission in supdesk.submissions.list(status="open"):
print(submission.title)
supdesk.submissions.create(
type="bug",
title="Export button does nothing",
email="user@example.com",
body="Clicking Export on the reports page has no effect.",
)import "github.com/rabinapps/supdesk-go/supdesk"
client, err := supdesk.New(os.Getenv("SUPDESK_API_KEY"))
if err != nil {
log.Fatal(err)
}
page, err := client.Submissions.List(ctx, supdesk.SubmissionsListParams{
Status: ptr("open"),
})
if err != nil {
return err
}
// Auto-pages: All walks every page for you.
for sub, err := range page.All(ctx) {
if err != nil {
return err
}
fmt.Println(sub.Title)
}
_, err = client.Submissions.Create(ctx, supdesk.SubmissionsCreateParams{
Type: supdesk.SubmissionTypeBug,
Title: "Export button does nothing",
Email: "user@example.com",
Body: "Clicking Export on the reports page has no effect.",
})import 'dart:io';
import 'package:supdesk/supdesk.dart';
final supdesk = SupDesk(apiKey: Platform.environment['SUPDESK_API_KEY']!);
// Auto-pages: the stream walks every page for you.
final page = await supdesk.submissions.list(status: PostStatus.open);
await for (final submission in page.autoPaging()) {
print(submission.title);
}
await supdesk.submissions.create(
type: SubmissionType.bug,
title: 'Export button does nothing',
email: 'user@example.com',
body: 'Clicking Export on the reports page has no effect.',
);