অ্যাকশন: আপনার নিজস্ব সিস্টেম থেকে উত্তর
একটি অ্যাকশন আপনার বটকে চ্যাটের মাঝখানেই আপনার নিজস্ব সিস্টেমে কিছু খুঁজে দেখতে দেয় — অর্ডার কোথায়, কবে ডেলিভারি হবে, বুকিং নিশ্চিত হয়েছে কি না। গ্রাহক জিজ্ঞাসা করেন, বট যা দরকার তা সংগ্রহ করে, আপনার API কল করে, এবং যা ফেরত আসে তা থেকে গ্রাহকের ভাষায় উত্তর দেয়।
আপনার বট যেখানে কাজ করে সেখানেই এটি কাজ করে: ওয়েবসাইট উইজেট, আপনার বট লিঙ্ক ও QR কোড, এবং Android, iOS, React Native, Flutter ও Ionic অ্যাপ। কিছু ইনস্টল বা আপডেট করা হয় না — কলটি আমাদের সার্ভার থেকে করা হয়, তাই আপনার API ক্রেডেনশিয়াল কখনও কোনো ব্রাউজার বা ফোনে পৌঁছায় না।
শুরু করার আগে: যে কেউ আপনার বটের সাথে চ্যাট করতে পারে
আপনার বট একটি পাবলিক চ্যাট। শুধু অর্ডার নম্বর দিয়েই যদি একটি অর্ডার দেখা যায়, তাহলে যে কেউ একটি না মেলা পর্যন্ত নম্বর টাইপ করে যেতে পারে।
বট তিনভাবে সাহায্য করে, কিন্তু এর কোনোটিই সেই যাচাইয়ের বিকল্প নয়: এটি শুধু গ্রাহকের সত্যিই টাইপ করা ভ্যালু পাঠায়, একটি চ্যাট বা একটি ঠিকানা কতগুলো লুকআপ করতে পারে তা সীমিত করে, এবং রেসপন্সের কোন ফিল্ডগুলো এটি দেখতে পারবে তা আপনি বেছে নিতে পারেন।
একটি সেট আপ করুন
ড্যাশবোর্ডে অ্যাকশন খুলুন এবং নতুন অ্যাকশন বেছে নিন। মালিক ও অ্যাডমিনরা এই স্ক্রিনটি দেখতে পারেন।
- নাম — আপনার জন্য, যেমন "অর্ডার স্ট্যাটাস"।
- বট কখন এটি ব্যবহার করবে? — এক বাক্যে, যেভাবে আপনি একজন নতুন সহকর্মীকে বলতেন: "গ্রাহক জিজ্ঞাসা করেন তার অর্ডার কোথায় বা কখন পৌঁছাবে।"
- আপনার API ঠিকানা —
GETবাPOST, এবং একটিhttps://ঠিকানা। যেখানে ভ্যালু বসবে সেখানে{{order_id}}লিখুন। - বট গ্রাহকের কাছে যা চায় — সর্বোচ্চ ছয়টি ভ্যালু। প্রতিটির একটি লেবেল আপনার নিজের ভাষায় ("অর্ডার নম্বর"), আপনার API যে নাম ব্যবহার করে (
order_id) এবং একটি ধরন থাকে: যেকোনো টেক্সট, একটি সংখ্যা, একটি ইমেইল ঠিকানা বা একটি ফোন নম্বর। - হেডার — আপনার API কি (key) বা টোকেন। এনক্রিপ্ট করে সংরক্ষিত এবং আর কখনও দেখানো হয় না।
- শুধু এই ফিল্ডগুলো বটের সাথে শেয়ার করুন — ঐচ্ছিক। রেসপন্সের যে অংশগুলো বট ব্যবহার করতে পারে সেগুলোর তালিকা দিন, যেমন
status, eta, items[].name। বাকি সবকিছু AI দেখার আগেই বাদ দেওয়া হয়।
টেস্ট চাপুন, নমুনা ভ্যালু লিখুন, আর দেখুন কোন রিকোয়েস্ট পাঠানো হয়েছে এবং বট ঠিক কী পেত। তারপর টেস্ট স্ক্রিনে সত্যিকারভাবে চেষ্টা করুন: "আমার অর্ডার 48213 কোথায়? আমার ইমেইল asha@example.com"।
আপনার API যা পায়
GET-এর ক্ষেত্রে, ঠিকানায় আপনার বসানো ভ্যালুগুলো পূরণ হয় এবং বাকিগুলো কোয়েরি স্ট্রিংয়ে যোগ হয়:
GET https://api.yourshop.com/orders/48213?email=asha%40example.comPOST-এর ক্ষেত্রে, ভ্যালুগুলোই JSON বডি:
POST https://api.yourshop.com/lookup
Content-Type: application/json
{"order_id":"48213","email":"asha@example.com"}প্রতিটি রিকোয়েস্টে আপনার নিজের হেডারগুলোর সাথে এগুলোও থাকে:
| হেডার | এটি কী |
|---|---|
webhook-id | এই রিকোয়েস্টের জন্য একটি ইউনিক আইডি |
webhook-timestamp | কখন পাঠানো হয়েছে, সেকেন্ডে |
webhook-signature | সিগনেচার — নিচে দেখুন |
X-Keyda-Bot | আপনার বটের Client ID |
X-Keyda-Action | অ্যাকশনের কি (key), যেমন order_status |
X-Keyda-Conversation | যে চ্যাট থেকে এটি এসেছে |
কী ফেরত পাঠাবেন
8 সেকেন্ডের মধ্যে JSON, অথবা এক লাইনের ছোট প্লেইন টেক্সট দিয়ে উত্তর দিন।
- 200 ডেটাসহ — বট সেখান থেকে উত্তর দেয়। এটি ছোট রাখুন এবং স্পষ্ট ফিল্ডের নাম ব্যবহার করুন: অভ্যন্তরীণ কোডের চেয়ে
{"status":"shipped","eta":"2 October"}ভালো কাজ করে। - 404 যখন কিছু মেলে না — বট গ্রাহককে জানায় এবং তিনি যা টাইপ করেছেন তা যাচাই করতে বলে।
- অন্য যেকোনো কিছু, বা সময়মতো উত্তর না এলে — বট দুঃখ প্রকাশ করে, আপনার যোগাযোগের তথ্য দেয়, এবং চ্যাটটি আপনার জন্য ফ্ল্যাগ করা হয়। কারণটি অ্যাকশন স্ক্রিনে দেখানো হয়।
রিডাইরেক্ট অনুসরণ করা হয় না, এবং 256 KB-এর বেশি রেসপন্স পড়া হয় না।
সিগনেচার যাচাই করুন
রিকোয়েস্টগুলো Standard Webhooks পদ্ধতিতে সাইন করা হয়, তাই আপনি বিদ্যমান কোনো লাইব্রেরি ব্যবহার করতে পারেন। আপনার সাইনিং সিক্রেট অ্যাকশন স্ক্রিনে রয়েছে।
নিজে হাতে: আইডি, টাইমস্ট্যাম্প এবং হুবহু বডি ফুল স্টপ দিয়ে জুড়ুন, সিক্রেট (whsec_-এর পরের অংশ, base64-ডিকোড করা) ব্যবহার করে HMAC-SHA256 দিয়ে সেটি সাইন করুন, এবং তুলনা করুন।
const crypto = require('crypto');
function isFromKeyda(req, rawBody, secret) {
const id = req.headers['webhook-id'];
const ts = req.headers['webhook-timestamp'];
const given = String(req.headers['webhook-signature'] || '').replace(/^v1,/, '');
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // older than 5 minutes
const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64');
const want = crypto.createHmac('sha256', key).update(`${id}.${ts}.${rawBody}`).digest('base64');
return given.length === want.length
&& crypto.timingSafeEqual(Buffer.from(given), Buffer.from(want));
}GET রিকোয়েস্টের ক্ষেত্রে বডি খালি থাকে, তাই সাইন করা টেক্সট একটি ফুল স্টপ দিয়ে শেষ হয়। ভ্যালুগুলোকেও সিগনেচারের আওতায় আনতে চাইলে POST ব্যবহার করুন।
বট এটি কীভাবে ব্যবহার করে
- যা কিছু অনুপস্থিত তা এটি চেয়ে নেয়, একবারে একটি ছোট প্রশ্ন করে, এবং গ্রাহক চ্যাটে আগে যা বলেছেন তা মনে রাখে।
- এটি কখনও কোনো ভ্যালু অনুমান করে না। গ্রাহক যদি তা টাইপ না করে থাকেন, বট জিজ্ঞাসা করে।
- প্রতি মেসেজে একটি লুকআপ। আপনার সেভ করা উত্তর এখনও আগে আসে, তাই যে প্রশ্নের উত্তর আপনি নিজে হাতে দিয়েছেন তা কখনও আপনার API কল করে না।
- একটি লুকআপ থেকে পাওয়া উত্তর কখনও অন্য গ্রাহকের জন্য পুনরায় ব্যবহার করা হয় না।
- একটি লুকআপ একটি উত্তর হিসেবে গণ্য হয়, AI-এর লেখা অন্য যেকোনো উত্তরের মতোই।
চ্যাটসমূহ-এ, লুকআপ থেকে আসা উত্তরের নিচে তা উল্লেখ থাকে: কোন অ্যাকশন চলেছে এবং কীভাবে শেষ হয়েছে। গ্রাহকের টাইপ করা ভ্যালুগুলো ট্রান্সক্রিপ্টে থাকে, আর কোথাও নয়।
লিমিট
অ্যাকশন তথ্য পড়ে। এমন কোনো ঠিকানায় অ্যাকশন নির্দেশ করবেন না যা কিছু পরিবর্তন করে — অর্ডার বাতিল করা বা রিফান্ড দেওয়ার জন্য একটি নিশ্চিতকরণ ধাপ দরকার, যা বটের এখনও নেই।