ডেভেলপার
ওয়েবহুক এবং Zapier
আপনার ওয়ার্কস্পেসে কিছু ঘটার সঙ্গে সঙ্গে ওয়েবহুক আপনার সার্ভারে একটি HTTP রিকোয়েস্ট পাঠায়, যেমন কোনো অ্যাপ পজ করা হলে বা কোনো স্মার্ট লিংকে ক্লিক হলে। আপনার নিজের সিস্টেম আপডেট করতে, Slack-এ পোস্ট করতে, অথবা সার্ভার না লিখেই mapps.one-কে Zapier, Make বা n8n-এর সাথে যুক্ত করতে এগুলো ব্যবহার করুন। ওয়েবহুক Studio প্ল্যানে পাওয়া যায়, প্রতি ওয়ার্কস্পেসে সর্বোচ্চ 10টি এন্ডপয়েন্টসহ।
একটি এন্ডপয়েন্ট যোগ করুন
- ড্যাশবোর্ডে ডেভেলপার → ওয়েবহুক খুলুন এবং এন্ডপয়েন্ট যোগ করুন বেছে নিন। ওয়ার্কস্পেসের মালিক ও অ্যাডমিনরা এটি করতে পারেন।
- একটি পাবলিক
httpsURL লিখুন, কোন ইভেন্টগুলো পাঠানো হবে তা বেছে নিন (অথবা সব ইভেন্ট) এবং একটি বর্ণনা যোগ করুন। - সাইনিং সিক্রেট কপি করুন এবং আপনার সার্ভারের অন্যান্য সিক্রেটের সাথে সংরক্ষণ করুন।
- আপনার এন্ডপয়েন্ট সাড়া দেয় কিনা দেখতে টেস্ট ইভেন্ট পাঠান বেছে নিন।
এন্ডপয়েন্টের পেজে সাম্প্রতিক ডেলিভারিগুলো দেখানো হয়, সাথে রেসপন্স স্ট্যাটাস, রেসপন্স বডির প্রথম 2,000 অক্ষর এবং প্রতিটি চেষ্টায় কত সময় লেগেছে। আপনি API দিয়েও এন্ডপয়েন্ট তৈরি ও ডিলিট করতে পারেন।
ইভেন্ট
| টাইপ | কখন পাঠানো হয় |
|---|---|
app.created | ওয়ার্কস্পেসে একটি অ্যাপ যোগ করা হয়েছে। |
app.updated | অ্যাপের বিবরণ, লিংক বা পেজ সেটিংস পরিবর্তন করা হয়েছে। |
app.deleted | একটি অ্যাপ ডিলিট করা হয়েছে। |
app.status_changed | একটি অ্যাপ লাইভ হয়েছে, পজ করা হয়েছে বা স্থগিত করা হয়েছে। |
app.metadata_fetched | একটি অ্যাপের জন্য স্টোর মেটাডেটা ইম্পোর্ট করা হয়েছে। |
legal.published | একটি গোপনীয়তা নীতি বা শর্তাবলীর ডকুমেন্ট প্রকাশ করা হয়েছে। |
domain.verified | একটি কাস্টম ডোমেইন ভেরিফাই করা হয়েছে। |
link.clicked | প্রতিটি স্মার্ট লিংক ক্লিক। জনপ্রিয় অ্যাপের ক্ষেত্রে এতে অনেক রিকোয়েস্ট হতে পারে। |
analytics.daily_summary | প্রতিটি অ্যাপের আগের দিনের মোট ক্লিক, দিনে একবার পাঠানো হয়। |
রিকোয়েস্টের ফরম্যাট
প্রতিটি ইভেন্ট JSON বডিসহ একটি POST রিকোয়েস্ট হিসেবে পাঠানো হয়।
| হেডার | মান |
|---|---|
Content-Type | application/json |
User-Agent | mapps.one-Webhooks/1.0 |
X-Mapps-Event | ইভেন্টের টাইপ, যেমন link.clicked |
X-Mapps-Delivery | ইভেন্টের ID। প্রতিটি রিট্রাইতে এটি একই থাকে। |
X-Mapps-Timestamp | এই ডেলিভারি চেষ্টার Unix time |
X-Mapps-Signature | t={timestamp},v1={signature} |
বডিটি একটি এনভেলপ, যার গঠন প্রতিটি ইভেন্টের জন্য একই:
{
"id": "evt_01j8c3m9t5v2x7z4b6d8f0h2k4",
"type": "app.status_changed",
"created_at": "2026-09-14T09:41:07+00:00",
"workspace": {
"id": "01j8a0f4c7d2e9h6k3m5n8q1r4",
"name": "Habitly Labs"
},
"data": {
"app": {
"id": "01j8b2k6r3xq9v7m4n5p0s1t2w",
"slug": "habitly",
"name": "Habitly"
},
"status": "paused"
}
}
data-এর ভেতরে কী থাকবে তা ইভেন্টের ওপর নির্ভর করে। কোনো অ্যাপ সম্পর্কিত ইভেন্টে একটি app অবজেক্ট থাকে, যাতে থাকে এর id, slug এবং name।
link.clicked
"data": {
"app": { "id": "01j8b2k6r3xq9v7m4n5p0s1t2w", "slug": "habitly", "name": "Habitly" },
"click": {
"occurred_at": "2026-09-14 09:41:07",
"os": "iOS",
"device_type": "mobile",
"country": "TR",
"source": "instagram",
"destination": "app_store",
"utm_source": "instagram",
"utm_medium": "social",
"utm_campaign": "launch"
}
}
occurred_at UTC-তে থাকে। device_type হলো mobile, tablet অথবা desktop। destination হলো একটি স্টোর কী, web অথবা landing। অজানা ফিল্ডগুলো null হয়। বটের ভিজিটে এই ইভেন্ট কখনো ট্রিগার হয় না।
app.metadata_fetched
"data": {
"app": { "id": "01j8b2k6r3xq9v7m4n5p0s1t2w", "slug": "habitly", "name": "Habitly" },
"source": "app_store"
}
সিগনেচার ভেরিফাই করুন
প্রতিটি রিকোয়েস্টের সিগনেচার চেক করুন, যাতে আপনি নিশ্চিত হতে পারেন যে এটি mapps.one থেকে এসেছে এবং পথে বদলানো হয়নি:
X-Mapps-Signatureহেডার থেকেtএবংv1পড়ুন।- আপনার এন্ডপয়েন্টের সাইনিং সিক্রেট ব্যবহার করে
{t}.{raw request body}-এর একটি HMAC-SHA256 হিসাব করুন, ছোট হাতের hex হিসেবে। - একটি constant-time তুলনা ব্যবহার করে এটিকে
v1-এর সাথে মিলিয়ে দেখুন। - রিপ্লে করা রিকোয়েস্ট আটকাতে,
tআপনার সার্ভারের ঘড়ি থেকে পাঁচ মিনিটের বেশি দূরে থাকলে রিকোয়েস্টটি প্রত্যাখ্যান করুন।
PHP
<?php
$secret = getenv('MAPPS_WEBHOOK_SECRET');
$body = file_get_contents('php://input');
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_MAPPS_SIGNATURE'] ?? ''), $parts);
$timestamp = (int) ($parts['t'] ?? 0);
$expected = hash_hmac('sha256', $timestamp.'.'.$body, $secret);
if (! hash_equals($expected, (string) ($parts['v1'] ?? '')) || abs(time() - $timestamp) > 300) {
http_response_code(400);
exit;
}
$event = json_decode($body, true);
if ($event['type'] === 'link.clicked') {
// Store $event['data']['click'] ...
}
http_response_code(200);
Laravel-এ $request->getContent() দিয়ে বডি এবং $request->header('X-Mapps-Signature') দিয়ে হেডার পড়ুন, এবং রাউটটিকে CSRF সুরক্ষা থেকে বাদ দিন।
Node.js (Express)
import crypto from 'node:crypto';
import express from 'express';
const app = express();
const secret = process.env.MAPPS_WEBHOOK_SECRET;
app.post('/webhooks/mapps', express.raw({ type: 'application/json' }), (req, res) => {
const header = req.get('X-Mapps-Signature') ?? '';
const parts = Object.fromEntries(header.split(',').map((pair) => pair.split('=')));
const timestamp = Number(parts.t);
const body = req.body.toString('utf8');
const expected = crypto.createHmac('sha256', secret).update(`${timestamp}.${body}`).digest();
const received = Buffer.from(parts.v1 ?? '', 'hex');
const valid = received.length === expected.length && crypto.timingSafeEqual(received, expected);
if (!valid || Math.abs(Date.now() / 1000 - timestamp) > 300) {
return res.sendStatus(400);
}
const event = JSON.parse(body);
if (event.type === 'link.clicked') {
// Store event.data.click ...
}
res.sendStatus(200);
});
app.listen(3000);
রেসপন্স এবং রিট্রাই
- 10 সেকেন্ডের মধ্যে যেকোনো 2xx স্ট্যাটাস দিয়ে সাড়া দিন। সময়সাপেক্ষ কাজ সাড়া দেওয়ার পরে একটি ব্যাকগ্রাউন্ড জবে করুন।
- রিডাইরেক্ট অনুসরণ করা হয় না, তাই চূড়ান্ত URL ব্যবহার করুন।
- URL-টি অবশ্যই পাবলিক
httpsহতে হবে। প্রাইভেট ও লোকাল নেটওয়ার্কের ঠিকানা গ্রহণ করা হয় না। - আপনার এন্ডপয়েন্ট টাইম আউট হলে বা 2xx ছাড়া অন্য কিছু রিটার্ন করলে, আমরা আরও সর্বোচ্চ পাঁচবার চেষ্টা করি: প্রায় 1 মিনিট, 5 মিনিট, 30 মিনিট, 2 ঘণ্টা এবং 6 ঘণ্টা পরে। প্রতিটি চেষ্টায় নতুন timestamp ও সিগনেচার থাকে।
- একই ইভেন্ট একাধিকবার আসতে পারে, এবং ইভেন্টগুলো ক্রমের বাইরে আসতে পারে। ডুপ্লিকেট উপেক্ষা করতে ইভেন্টের
id, অর্থাৎX-Mapps-Deliveryব্যবহার করুন, এবং ক্রম সাজাতেcreated_atব্যবহার করুন। - পরপর 20টি চেষ্টা ব্যর্থ হলে এন্ডপয়েন্টটি বন্ধ করে দেওয়া হয় এবং এতে আর কিছু পাঠানো হয় না। সমস্যাটি ঠিক করুন, তারপর ড্যাশবোর্ডে এটি আবার চালু করুন।
Zapier, Make এবং n8n
কোনো সার্ভার না চালিয়েই আপনি mapps.one-কে হাজারো অ্যাপের সাথে যুক্ত করতে পারেন।
Zapier
- ট্রিগার হিসেবে Webhooks by Zapier দিয়ে একটি Zap তৈরি করুন এবং Catch Hook বেছে নিন।
- Zapier আপনাকে যে ওয়েবহুক URL দেয় সেটি কপি করুন।
- mapps.one-এ ওই URL দিয়ে একটি এন্ডপয়েন্ট যোগ করুন এবং আপনার পছন্দের ইভেন্টগুলো বেছে নিন, যেমন
app.status_changedবাanalytics.daily_summary। - mapps.one-এ টেস্ট ইভেন্ট পাঠান বেছে নিন, তারপর Zapier-এ Test trigger। পেলোডের ফিল্ডগুলো, যেমন
data.app.name, এখন পরের ধাপগুলোতে ব্যবহার করা যাবে।
উদাহরণ: কোনো অ্যাপ পজ করা হলে Slack-এ একটি মেসেজ পোস্ট করুন, প্রতিদিনের ক্লিক একটি Google Sheet-এ যোগ করুন, অথবা কোনো ক্লায়েন্টের ডোমেইন ভেরিফাই হলে তাকে ইমেইল করুন।
Make এবং n8n
Make-এ Webhooks → Custom webhook ট্রিগার ব্যবহার করুন। n8n-এ POST মেথডসহ Webhook নোড ব্যবহার করুন। তারপর ওপরের মতো করে mapps.one-এ URL-টি একটি এন্ডপয়েন্ট হিসেবে যোগ করুন।
একটি ইন্টিগ্রেশন তৈরি করা
আপনি যদি অন্যদের জন্য একটি mapps.one ইন্টিগ্রেশন তৈরি করেন, তাহলে কোনো ব্যবহারকারী সংযুক্ত হলে API দিয়ে সাবস্ক্রাইব করুন (POST /api/v1/webhooks), সংযোগ বিচ্ছিন্ন করলে আনসাবস্ক্রাইব করুন (DELETE /api/v1/webhooks/{id}), ইভেন্ট বাছাইয়ের জন্য GET /api/v1/events ব্যবহার করুন, এবং সংযোগ টেস্ট করতে GET /api/v1/workspace ব্যবহার করুন। API রেফারেন্স দেখুন।