সীমিত পরিসরের ম্যানেজমেন্ট API টোকেন দিয়ে জমা পড়ুন
ম্যানেজমেন্ট API টোকেন হ্যাশে রাখা হয়, একবার দেখানো হয় এবং সামর্থ্য দিয়ে সীমিত: ফর্ম, জমা, প্রত্যাখ্যান আর একটি প্রচেষ্টার সূত্রে পাঁচটি পড়ার রুট, কার্সর পেজিনেশনসহ এবং লেখার কোনো পৃষ্ঠ নেই।
এই পোস্টটি যন্ত্রের মাধ্যমে অনুবাদ করা হয়েছে। ইংরেজিতে মূল পোস্টটি পড়ুন

ম্যানেজমেন্ট API হলো FormFlow-এর পড়ার দিক: পাঁচটি GET রুট, একটি বিয়ারার টোকেন, আর কিছু লেখার কোনো উপায় নেই। টিমের নিজের টুল যখন FormFlow-এ আগেই রাখা জমাগুলো চায়, স্প্রেডশিটে রাখা একটি নকল নয়, তখন এই পৃষ্ঠই ব্যবহার করে।
টোকেনকে কাজের মতোই সংকীর্ণ রাখুন
টোকেন টিমের, কোনো ব্যক্তির নয়। তৈরি করার সময় এটিকে একটি নাম, অন্তত একটি সামর্থ্য — submissions:read, refusals:read বা forms:read —, ঐচ্ছিকভাবে ফর্মের তালিকা এবং ঐচ্ছিকভাবে মেয়াদ শেষের তারিখ দেওয়া হয়। FormFlow শুধু হ্যাশ রাখে, তাই শংসাপত্র তৈরি করার সময় একবারই দেখানো হয়, পরে কখনও নয়। প্রত্যাহার সঙ্গে সঙ্গে কার্যকর; মেয়াদোত্তীর্ণ টোকেন তার সারি রাখে আর তার জায়গা ছেড়ে দেয়।
এর মধ্যে দুটি সেটিংই বেশিরভাগ কাজ করে। নাম দেওয়া ফর্মে সীমিত টোকেন সেই ফর্মগুলোতেই পৌঁছায়, আর কোথাও নয়। শুধু forms:read থাকা টোকেন একটি জমাও না পড়ে ফর্মের মেটাডেটা তালিকায় পারে। কোনোটিই পছন্দ নয়: টোকেনের পরিসরের বাইরের পাঠ ঠিক সেই রকম উত্তর দেয় যেমন একটি না-থাকা রেকর্ডের পাঠ, তাই অনুপস্থিত ও নিষিদ্ধ রেকর্ড একই রকম দেখায়।
পাঁচটি পাঠ
প্রতিটি রুট /api/v1/manage-এর নিচে এবং Authorization হেডারে বিয়ারার টোকেন দিয়ে প্রমাণিত হয়।
GET /api/v1/manage/forms — ফর্মের মেটাডেটা। forms:read দরকার।
GET /api/v1/manage/submissions — জমার একটি পাতা। submissions:read দরকার।
GET /api/v1/manage/submissions/{uuid} — একটি জমা, তালিকা যে স্প্যাম সংকেত বাদ দেয় তা সহ।
GET /api/v1/manage/refused-submissions — ফর্মের খাতা যে প্রত্যাখ্যান রেখেছে। refusals:read দরকার।
GET /api/v1/manage/attempts/{attemptId} — একটি প্রচেষ্টার ক্রমিক জীবন, তা লিপিবদ্ধ করা সব খাতায়।
জমার বডি ফিল্ডের নাম দিয়ে কী করা থাকে এবং যেমন পাঠানো হয়েছিল তেমনই ফেরত আসে। বেশিরভাগ ফিল্ড স্ট্রিং, মাল্টিসিলেক্ট তালিকা, ফাইল ফিল্ড তার সংরক্ষিত নামসহ রেফারেন্স, আর গ্রিড সারির লেবেল দিয়ে কী করা অবজেক্ট। শুধু একক-জমার রুটই স্প্যাম সংকেত ফেরত দেয়।
কার্সর দিয়ে পৃষ্ঠা ঘুরুন
তালিকার রুট data ও meta ফেরত দেয়। limit 1 থেকে 200 নেয় এবং ডিফল্ট 50, আর ক্রম created_at তারপর id, অবরোহ। meta.has_more বলে পরের পাতা আছে কি না; meta.next_cursor হলো অস্পষ্ট মান যা cursor হিসেবে ফেরত পাঠাতে হয়। এখানে অফসেট নেই, কারণ পড়ার সময় সমষ্টি নড়তে থাকে আর অফসেট নীরবে সারি বাদ দিত বা পুনরাবৃত্তি করত।
cursor=""
while :; do
page=$(curl -sS "https://formflow.digital/api/v1/manage/submissions?limit=100&cursor=$cursor" \
-H "Authorization: Bearer $FORMFLOW_TOKEN")
echo "$page" | jq -r '.data[] | [.uuid, .form_id, .created_at] | @tsv'
cursor=$(echo "$page" | jq -r '.meta.next_cursor // empty')
[ "$(echo "$page" | jq -r '.meta.has_more')" = "true" ] || break
doneফিল্টার ইচ্ছাকৃতভাবে সংকীর্ণ: form_id, since, until, is_spam, unread এবং q। q হলো ব্লাইন্ড ইনডেক্সে সঠিক-টোকেন অনুসন্ধান, উপস্ট্রিং অনুসন্ধান নয়, আর এটি কেবল সেখানেই উত্তর দেয় যেখানে অনুসন্ধান সূচিকরণ চালু আছে।
একটি প্রত্যাখ্যান থেকে তার প্রচেষ্টা পর্যন্ত
প্রত্যাখ্যাত জমা আর জমা আলাদা রেকর্ড। প্রত্যাখ্যান রাখা হয় যাতে গ্রাহক তার উপর কাজ করতে পারেন; এটি কখনও বিতরণ হয় না এবং কখনও গণিত জমা হয় না। দুটোতেই প্রচেষ্টার আইডি থাকে, আর প্রচেষ্টার রুট সেই এক প্রচেষ্টার সূত্র জোড়া দেয় — প্রি-ফ্লাইট ঘর্ষণ, প্রত্যাখ্যান, গ্রহণ, উদ্ধার, পুনরুদ্ধার, রসিদ এবং প্রতিটি বিতরণ বাধ্যবাধকতা — কোনো পাঠানো মান বা জমা দেওয়া ব্যক্তির মেটাডেটা ছাড়াই।
প্রচেষ্টার আইডি নিজে থেকে অনন্য নয়, তাই সূত্রটি সর্বদা একটি ফর্মে সীমিত। যখন আইডিটি একাধিক ফর্মে থাকে, উত্তর 409 হয় এবং সেগুলোর নাম বলে, আর আপনি form_uuid দিয়ে অনুরোধ পুনরাবৃত্তি করে বেছে নেন।
যেখানে পড়ার পৃষ্ঠ ভোঁতা
এর উপর কিছু বানানোর আগে আরও তিনটি সীমা জেনে নিন। বডি FormFlow-এর ভেতরে ডিক্রিপ্ট হয় এবং যেমন সংরক্ষিত ছিল তেমনই ফেরত আসে, তাই জমা পড়া টোকেন ব্যক্তিগত তথ্য পড়া টোকেন, আর তার সংরক্ষণ শংসাপত্রের মতোই যত্ন দাবি করে। যে সারির বডি ডিক্রিপ্ট করা যায় না তা payload_error-এর সাথে payload_unavailable ফেরত দেয়, পাতার বাকি অংশ আসতেই থাকে। আর কোডগুলো নির্দিষ্ট: অবৈধ, মেয়াদোত্তীর্ণ বা প্রত্যাহৃত টোকেনে 401; সামর্থ্য নেই বা প্ল্যান পাওয়া যাচ্ছে না বলে 403; রেকর্ড টোকেনের পরিসরের বাইরে হলে 404; অবৈধ ফিল্টার বা কার্সরে 422; আর হার-সীমায় 429, Retry-After সহ।
পুরো চুক্তি — প্রতিটি প্যারামিটার, উত্তরের গঠন ও ত্রুটি — /docs/api-এ। আর v1.0.0-এর পরিবর্তন তালিকার এন্ট্রি এই API-কে যেমন এসেছিল তেমনই লিখে রাখে: জমা গ্রহণ করা সেই একমাত্র এন্ডপয়েন্টের পাশে একটি নথিভুক্ত ম্যানেজমেন্ট API।