Afterlog للمطوّرين
أدخِل رحلات Afterlog إلى تطبيقاتك وخدماتك.

أدوات التضمين
ضع منزلق Before↔Current أو بطاقة رحلة في أي موقع. الرحلات العامة فقط — بلا مفتاح API.
معاينة حيّة
وسم السكربت
أضف سكربت الـ SDK وعنصر div مؤقّت؛ تُركَّب الأداة وتُعيد ضبط ارتفاعها تلقائيًا.
<script async src="https://afterlog.me/sdk/afterlog.js"></script>
<div data-afterlog-journey="JOURNEY_ID" data-afterlog-theme="light"></div>iframe مباشر
ضمِّن بدون JavaScript. استخدم theme=light|dark و variant=slider|card.
<iframe
src="https://afterlog.me/embed/journey/JOURNEY_ID?theme=light&variant=slider"
width="480" height="520" style="border:0;max-width:100%"
scrolling="no" loading="lazy" title="Afterlog journey"></iframe>oEmbed
الصق رابط رحلة في Slack و WordPress والأدوات التي تدعم oEmbed.
GET https://afterlog.me/api/oembed?url=https://afterlog.me/journey/JOURNEY_ID&format=jsonواجهة الشركاء (API)
واجهة REST للقراءة فقط للشركاء المعتمدين. اجلب الرحلات العامة والرائجة والبحث والملفات الشخصية إلى منتجك.
المصادقة
أرسل مفتاحك في ترويسة x-api-key. أصدر المفاتيح من وحدة تحكم المطوّر أدناه.
curl https://api.afterlog.me/v1/partner/trending \
-H "x-api-key: ak_live_..."الوصول المبكر
واجهة الشركاء بالدعوة فقط حاليًا. سجّل تطبيقًا، ثم نراجعه قبل تفعيل مفاتيحك.
403— لم يُعتمد التطبيق بعد، أو تم إبطال المفتاح.401— المفتاح x-api-key مفقود أو غير صالح.429— تم تجاوز حد الطلبات — انتظر وفق ترويسة Retry-After ثم أعد المحاولة.
نقاط النهاية
كل المسارات نسبية إلى https://api.afterlog.me/v1 وللقراءة فقط. الرائج والبحث يُرقّمان بالصفحات عبر cursor و nextCursor.
GET /partner/trending?category=&sort=trending|helpful&cursor=&limit=
GET /partner/search?q=&cursor=&limit=
GET /partner/journeys/:id
GET /partner/profiles/:username
GET /partner/profiles/:username/journeys?sort=recent|pinnedشكل الاستجابة
تُعاد الرحلة بعرضها العام — الغلاف والوسوم والإحصاءات والمالك. بلا حقول خاصة بالمشاهد أو حقول خاصة.
{
"items": [
{
"id": "cmr576hhy000n5s6a1b2c3d4",
"userId": "cmr4qx8p0000ab12cd34",
"title": "코 성형 회복 여정",
"category": "BEAUTY",
"categoryCustom": null,
"startDate": "2026-01-15",
"privacy": "PUBLIC",
"status": "PUBLISHED",
"description": "붓기와 회복 과정을 매주 기록합니다.",
"tags": ["recovery", "beauty"],
"coverMediaId": "cmr58a4k0001...",
"coverUrl": "https://disk.afterlog.me/media/.../320.webp",
"captureSlots": [{ "key": "front", "label": "Front" }, { "key": "side", "label": "Side" }],
"heroSlot": "front",
"createdAt": "2026-01-15T09:12:00.000Z",
"updatedAt": "2026-07-14T02:31:00.000Z",
"stats": {
"daysCount": 180, "updatesCount": 12, "viewsCount": 3400,
"savesCount": 210, "followersCount": 95, "helpfulCount": 88,
"completedReadsCount": 40, "forksCount": 3, "helpfulnessScore": 0.82
},
"owner": {
"userId": "cmr4qx8p0000ab12cd34", "username": "riah_kim",
"displayName": "Riah", "avatarMediaId": null,
"avatarUrl": "https://disk.afterlog.me/media/.../320.webp"
},
"trendingScore": 128.4
}
],
"nextCursor": "eyJjIjoiMjAyNi0wNy0xNCJ9"
}جاهز للبناء؟ سجّل تطبيقًا وأصدر مفتاحك الأول.
افتح وحدة تحكم المطوّرOAuth لبيانات المستخدم
دع المستخدمين يربطون حساب Afterlog حتى يتمكن تطبيقك من قراءة رحلاتهم — بما فيها الخاصة — نيابةً عنهم. Authorization Code + PKCE (S256).
التدفّق
- 1. أرسل المستخدم إلى رابط التفويض مع PKCE challenge والنطاقات المطلوبة.
- 2. يراجع المستخدم ويوافق على Afterlog، ثم نعيد التوجيه إلى redirect_uri مع code لمرة واحدة و state الخاص بك.
- 3. بادل الـ code برموز عند نقطة نهاية token، مع إرسال code_verifier الأصلي.
- 4. استدعِ واجهة الشركاء بـ Authorization: Bearer <access_token>. رمز الوصول يدوم ساعة؛ استخدم refresh للتدوير.
النطاقات
journeys.read | قراءة رحلات المستخدم المرتبط وسجلاته، بما فيها الخاصة. |
profile.read | قراءة الملف العام للمستخدم المرتبط. |
رابط التفويض
أعد توجيه المتصفح إلى هنا. يجب أن يطابق redirect_uri تمامًا قيمة مسجّلة في تطبيقك، و PKCE بطريقة method=S256 إلزامي.
https://afterlog.me/oauth/authorize?response_type=code
&client_id=YOUR_APP_ID
&redirect_uri=https://your.app/callback
&scope=journeys.read%20profile.read
&state=RANDOM_CSRF
&code_challenge=BASE64URL_SHA256_OF_VERIFIER
&code_challenge_method=S256مبادلة الرمز
بادل الـ code برمز وصول + refresh. عملاء confidential يرسلون client_secret أيضًا.
curl -X POST https://api.afterlog.me/v1/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"client_id": "YOUR_APP_ID",
"code": "<code from redirect>",
"redirect_uri": "https://your.app/callback",
"code_verifier": "<original PKCE verifier>"
}'استخدام الرمز
أرسل رمز الوصول كترويسة Bearer عند قراءات واجهة الشركاء. مع journeys.read تُضمَّن رحلات المستخدم المرتبط الخاصة.
curl https://api.afterlog.me/v1/partner/journeys/JOURNEY_ID \
-H "Authorization: Bearer <access_token>"ويب هوك
تلقَّ إشعارًا عندما يضيف مستخدم مرتبط سجلًا أو ينشر رحلة. الحمولات إشارات رفيعة — اجلب التفاصيل من واجهة الشركاء.
إدارة نقاط النهاية
سجّل نقاط النهاية واعرضها واحذفها لكل تطبيق في وحدة تحكم المطوّر. يظهر secret التوقيع مرة واحدة عند الإنشاء. يجب أن تكون الروابط https وألا تشير إلى مضيف خاص.
الأحداث
journey.update.created | أضاف مستخدم مرتبط سجلًا (Update) إلى رحلة. |
journey.published | نشر مستخدم مرتبط رحلة. |
الحمولة
لكل تسليم id فريد (استخدمه للـ idempotency) وحدث وطابع زمني وكائن data رفيع.
{
"id": "whd_5f3a1c...", // 배달 고유 id (수신측 idempotency 키)
"event": "journey.update.created",
"createdAt": "2026-07-19T09:00:00.000Z",
"data": {
"journeyId": "jr_...", "updateId": "up_...",
"username": "riah", "title": "코 성형 회복 여정"
}
}التحقق من التوقيع
يحمل كل طلب X-Afterlog-Signature: t=<unix>,v1=<hex> حيث v1 = HMAC-SHA256 لِـ "<t>.<الجسم الخام>". أعد الحساب على الجسم الخام وقارن بزمن ثابت.
// header: X-Afterlog-Signature: t=<unix>,v1=<hex>
const [t, v1] = header.split(',').map((s) => s.split('=')[1]);
const expected = crypto
.createHmac('sha256', secret) // secret = whsec_...
.update(`${t}.${rawBody}`) // 받은 원문 바디 그대로 사용
.digest('hex');
const ok = crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(v1),
);
// t 가 최근(±5분)인지도 확인해 재전송(replay)을 막는다.إعادة المحاولة والتعطيل التلقائي
2xx يعني نجاح. الإخفاقات والمهلة (10 ثوانٍ) تُعاد حتى 3 مرات. بعد 10 إخفاقات تراكمية تُعطَّل نقطة النهاية تلقائيًا؛ أعد إنشاءها لإعادة التفعيل.