Salesforce Open Badges: CRM ট্রিগার থেকে যাচাইযোগ্য ক্রেডেনশিয়াল ইস্যু করুন
Salesforce-এর যেকোনো অবজেক্ট ইভেন্ট থেকে — Lead won, Account upgraded, ট্রেনিং মাইলস্টোন — Badges Ninja API-তে একটি Apex callout দিয়ে Open Badge ইস্যু ট্রিগার করুন।
Nacho founded Badges Ninja to make issuing verifiable digital credentials as simple as a single API call — Open Badge v2.0 badges and certificates, minted, hosted, and verifiable without standing up your own issuer infrastructure.
বেশিরভাগ ট্রেনিং টিম Salesforce-এর ভেতরেই ইতিমধ্যে রেকর্ড করে রাখে কে কী শেষ করেছে। একটি কোর্স এনরোলমেন্ট “Completed” হয়ে যায়, একটি পার্টনার অ্যাকাউন্ট সার্টিফিকেশন টিয়ারে পৌঁছায়, একজন গ্রাহক অনবোর্ডিং শেষ করেন। রেকর্ড বদলায়, আর তারপর এক সপ্তাহ পরে কেউ একটি তালিকা এক্সপোর্ট করে হাতে হাতে সার্টিফিকেট ইমেইল করেন।
এই গাইডে দেখানো হয়েছে কীভাবে এই ফাঁক বন্ধ করবেন: কোনো রেকর্ড আপনার কাঙ্ক্ষিত স্ট্যাটাসে পৌঁছালেই Salesforce https://badges.ninja API কল করে, একটি Open Badge v2.0 ক্রেডেনশিয়াল ইস্যু হয়, এবং যাচাই লিংকটি রেকর্ডে ফিরিয়ে সংরক্ষিত হয়। এরপর সেই লিংক আপনি ইমেইল টেমপ্লেট, রিপোর্ট বা Experience Cloud পেজে বসাতে পারেন।
আপনার দরকার হবে একজন Salesforce অ্যাডমিন (বা একটি ডেভেলপার স্যান্ডবক্স), https://badges.ninja-তে আগে থেকে ডিজাইন করা একটি ব্যাজ, এবং একটি API কী। আগে কখনও API কল না করে থাকলে প্রথমে API quickstart পড়ে নিন; দশ মিনিটেই হয়ে যায়।
কখন CRM ট্রিগারই সঠিক হাতিয়ার
Apex লেখার আগে দেখে নিন সত্যিই এটি দরকার কি না। যদি আপনি প্রতি টার্মে বা প্রতি কোয়ার্টারে একসঙ্গে ক্রেডেনশিয়াল ইস্যু করেন, তাহলে ড্যাশবোর্ডের CSV আপলোড দ্রুততর এবং এতে কোনো কোডই লাগে না। Salesforce পথটি তখনই কাজে আসে যখন:
- রেকর্ড বদলানোর মুহূর্তেই ইস্যু হওয়া দরকার, কোনো মানুষের ধাপ ছাড়াই।
- “কে অর্জন করেছে” তথ্য ইতিমধ্যে Salesforce-এ আছে এবং আপনি দ্বিতীয় কোনো সত্যের উৎস চান না।
- আপনি রিপোর্টিংয়ের জন্য Contact, Lead বা কাস্টম ট্রেনিং রেকর্ডে ক্রেডেনশিয়াল লিংক সংরক্ষণ করতে চান।
আপনার ওয়ার্কফ্লো টুল যদি Apex-এর বদলে Zapier হয়, সেখানেও একই API কল কাজ করে; দেখুন Zapier Open Badges automation।
আপনি কী তৈরি করছেন
পুরো ফ্লোতে চারটি অংশ আছে:
- ভিজ্যুয়াল ডিজাইনারে ডিজাইন করা একটি ব্যাজ। এর id কপি করুন (
GET /badgesযেidফেরত দেয়)। - আপনার ড্যাশবোর্ডের API Keys পেজে তৈরি করা একটি API কী। কী-টি শুধু একবার দেখানো হয়, তাই সঙ্গে সঙ্গে সংরক্ষণ করুন।
- Salesforce-এ একটি Named Credential, যেখানে কী-টি থাকে, ফলে তা কখনও কোডে দেখা যায় না।
- একটি Apex ট্রিগার এবং একটি Queueable ক্লাস, যা অ্যাওয়ার্ড ইস্যু করে এবং অ্যাওয়ার্ড লিংকটি রেকর্ডে লিখে রাখে।

ধাপ ১: কী-টি একটি Named Credential-এ রাখুন
Apex-এ API কী হার্ড-কোড করা এড়িয়ে চলার মতো ভুল। Setup-এ একটি কাস্টম হেডারসহ External Credential তৈরি করুন, তারপর API হোস্টের দিকে নির্দেশ করা একটি Named Credential তৈরি করুন:
- URL:
https://api.badges.ninja - Custom header name:
X-Api-Key - Custom header value: আপনার কী,
bws_YOUR_KEY_HEREআকারে - Named Credential name:
BadgesNinja
আপনার অটোমেশন যে পারমিশন সেট চালায়, সেটিকে External Credential-এর principal-এ অ্যাক্সেস দিন। Named Credential থাকলে আলাদা Remote Site Setting লাগে না; Salesforce ক্রেডেনশিয়ালের মাধ্যমেই callout অনুমোদন করে। আপনার org যদি এখনও legacy Named Credentials বা সাধারণ endpoint ব্যবহার করে, তাহলে https://api.badges.ninja-কে Remote Site Setting হিসেবে যোগ করুন এবং হেডারটি কোড থেকে পাঠান।
ধাপ ২: রেকর্ডে ফিল্ড যোগ করুন
যে অবজেক্ট অর্জনটি উপস্থাপন করে (আমরা Training_Enrollment__c নামের একটি কাস্টম অবজেক্ট ব্যবহার করব), সেখানে যোগ করুন:
Badge_Id__c(Text): যে ব্যাজটি ইস্যু হবে। প্রতিটি কোর্সের জন্য এটি সংরক্ষণ করলে একটি ট্রিগারই অনেক ব্যাজ সামলাতে পারে।Badge_Award_Id__c(Text, unique): API থেকে ফেরত আসা award id।Badge_Url__c(URL): পাবলিক যাচাই পেজ।Badge_Error__c(Long Text): সর্বশেষ ত্রুটি, যাতে অ্যাডমিনরা ডিবাগ লগ না খুলেই ব্যর্থতা দেখতে পারেন।
Badge_Award_Id__c ফিল্ডটি দুটি কাজ করে। এটি আপনার ডুপ্লিকেট প্রহরী: ট্রিগার শুধু তখনই ইস্যু করে যখন এটি ফাঁকা থাকে।
ধাপ ৩: Apex callout
একটি ট্রিগার সরাসরি callout করতে পারে না, কারণ কমিট না হওয়া DML-এর একই ট্রানজ্যাকশনে callout অনুমোদিত নয়। কাজটি Database.AllowsCallouts ইমপ্লিমেন্ট করা একটি Queueable-এর হাতে দিন।
POST /awards-এর API চুক্তি সংক্ষিপ্ত। বডিতে থাকে badgeId, name ও email সহ একটি নেস্টেড recipient অবজেক্ট, এবং একটি আবশ্যিক issuedOn। সফল কল HTTP 200 এবং { "awardId": "..." } ফেরত দেয়। প্রাপকের নাম কমপক্ষে পাঁচ অক্ষরের হতে হবে, তাই “Al Li” নামের একটি Contact প্রত্যাখ্যাত হবে; কল করার আগে যাচাই করুন।
public class BadgeIssueJob implements Queueable, Database.AllowsCallouts {
private Id enrollmentId;
public BadgeIssueJob(Id enrollmentId) { this.enrollmentId = enrollmentId; }
public void execute(QueueableContext ctx) {
Training_Enrollment__c e = [
SELECT Id, Badge_Id__c, Badge_Award_Id__c, Contact__r.Name, Contact__r.Email
FROM Training_Enrollment__c WHERE Id = :enrollmentId LIMIT 1
];
if (e.Badge_Award_Id__c != null) { return; } // already issued
Map<String, Object> recipient = new Map<String, Object>{
'name' => e.Contact__r.Name,
'email' => e.Contact__r.Email
};
Map<String, Object> body = new Map<String, Object>{
'badgeId' => e.Badge_Id__c,
'recipient' => recipient,
'issuedOn' => Datetime.now().getTime()
};
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:BadgesNinja/awards');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setBody(JSON.serialize(body));
HttpResponse res = new Http().send(req);
if (res.getStatusCode() == 200) {
Map<String, Object> out = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
String awardId = (String) out.get('awardId');
e.Badge_Award_Id__c = awardId;
e.Badge_Url__c = 'https://badges.ninja/awards/' + awardId;
e.Badge_Error__c = null;
} else {
e.Badge_Error__c = res.getStatusCode() + ': ' + res.getBody();
}
update e;
}
}
দুটি খুঁটিনাটি লক্ষ করার মতো। প্রথমত, issuedOn হলো epoch মিলিসেকেন্ড, ঠিক যা Datetime.getTime() ফেরত দেয়। দ্বিতীয়ত, রেসপন্সে যাচাই URL থাকে না, তাই কোডটি award id থেকে সেটি তৈরি করে: https://badges.ninja/awards/<awardId>।
ধাপ ৪: ট্রিগার
ট্রিগারকে হালকা রাখুন। এটি শুধু ঠিক করে কোন রেকর্ড যোগ্য, এবং প্রতিটি রেকর্ডের জন্য একটি করে জব এনকিউ করে।
trigger TrainingEnrollmentBadge on Training_Enrollment__c (after insert, after update) {
for (Training_Enrollment__c e : Trigger.new) {
Boolean completed = e.Status__c == 'Completed';
Boolean wasCompleted = Trigger.isUpdate && Trigger.oldMap.get(e.Id).Status__c == 'Completed';
if (completed && !wasCompleted && e.Badge_Award_Id__c == null && e.Badge_Id__c != null) {
System.enqueueJob(new BadgeIssueJob(e.Id));
}
}
}
wasCompleted যাচাইটি গুরুত্বপূর্ণ। এটি ছাড়া, সম্পন্ন হওয়া রেকর্ডে পরবর্তী যেকোনো সম্পাদনা লজিকটি আবার চালু করে দেবে। জবের ভেতরের ফাঁকা award id প্রহরীর সঙ্গে মিলিয়ে, একটি রেকর্ড কেবল একটিমাত্র ক্রেডেনশিয়ালই তৈরি করতে পারে।
একটি সীমা মনে রাখুন: Salesforce একটি ট্রানজ্যাকশন থেকে অল্প সংখ্যক Queueable জব এনকিউ করার অনুমতি দেয় (সিনক্রোনাস প্রেক্ষাপটে ৫০টি)। আপনি যদি বাল্কে সম্পন্নতার ডেটা লোড করেন, ধরুন ২,০০০ সারির একটি ডেটা ইমপোর্ট, তাহলে উপরের ট্রিগার সেই সীমায় ঠেকে যাবে। বাল্ক লোডের জন্য হয় তালিকাটি বরং ড্যাশবোর্ডের CSV bulk awards দিয়ে আপলোড করুন, অথবা Database.AllowsCallouts সহ একটি Batchable ক্লাসে যান, যা প্রতি স্কোপে অল্প কয়েকটি রেকর্ড প্রক্রিয়া করে।

ত্রুটি সামলানো ও পুনঃচেষ্টা
API স্ট্যান্ডার্ড স্ট্যাটাস কোড ফেরত দেয়, এবং প্রতিটির জন্য আপনার কোডের আলাদা সাড়া দরকার:
| Status | Meaning | What to do |
|---|---|---|
| 400 | কোনো ফিল্ড অনুপস্থিত বা অবৈধ ছিল, পাঁচ অক্ষরের কম প্রাপকের নামসহ | পুনঃচেষ্টা করবেন না। ডেটা ঠিক করুন এবং বার্তাটি Badge_Error__c-এ লিখুন। |
| 401 | ভুল বা অনুপস্থিত API কী | Named Credential যাচাই করুন। ঠিক না হওয়া পর্যন্ত পুনঃচেষ্টায় লাভ নেই। |
| 402 | আপনার প্ল্যানের ক্রেডেনশিয়াল বা কোটা শেষ | ইস্যু বন্ধ করুন এবং অ্যাডমিনকে জানান; আপগ্রেডের পরে বা কোটা রিসেট হলে আবার চেষ্টা করুন। |
| 404 | badgeId-টি নেই | রেকর্ড বা কোর্সে Badge_Id__c সংশোধন করুন। |
| 5xx or timeout | সাময়িক ব্যর্থতা | পরে পুনঃচেষ্টা করা নিরাপদ। |
জবটি যেহেতু ত্রুটিটি রেকর্ডে লেখে এবং Badge_Award_Id__c ফাঁকা রাখে, তাই পুনঃচেষ্টা করা একটি চেকবক্স উল্টে দেওয়া বা রেকর্ড আবার সেভ করার মতোই সহজ। একটি ছোট শিডিউলড Apex ক্লাস, যা award id ছাড়া এবং সাময়িক ত্রুটিসহ সম্পন্ন এনরোলমেন্ট খুঁজে আবার এনকিউ করে, কোনো বাড়তি অবকাঠামো ছাড়াই আপনাকে স্বয়ংক্রিয় পুনঃচেষ্টার সারি দেয়। চেষ্টার সংখ্যা একটি কাউন্টার ফিল্ড দিয়ে সীমিত করুন, যাতে স্থায়ীভাবে খারাপ রেকর্ড চিরকাল ঘুরতে না থাকে।
প্রোডাকশনে যুক্ত করার আগে আপনার প্ল্যান দেখে নিন। Free প্ল্যানে বছরে ১,২০০টি ক্রেডেনশিয়াল মেলে; Starter মাসে $9 এবং Pro মাসে $29। প্রতিটি Lead-এ চালু হওয়া একটি ট্রিগার ছোট প্ল্যান দ্রুত শেষ করে ফেলবে, তাই মানদণ্ডটি প্রকৃত অর্জনের মধ্যে সীমিত রাখুন।
Salesforce-এ ক্রেডেনশিয়ালকে দৃশ্যমান করা
Badge_Url__c ভরে গেলে সেটি আপনি যেকোনো জায়গায় ব্যবহার করতে পারেন:
- ইমেইল অ্যালার্ট ও টেমপ্লেট: ফিল্ডটি একটি “অভিনন্দন, এই যে আপনার ক্রেডেনশিয়াল” ইমেইলে মার্জ করুন।
- রিপোর্ট:
Badge_Award_Id__c != null-এর ওপর একটি রিপোর্ট আপনাকে কোর্স, অঞ্চল বা অ্যাকাউন্ট ওনার অনুযায়ী ইস্যুর সংখ্যা দেয়। - Experience Cloud: পার্টনারের সার্টিফিকেশন পেজে লিংকটি দেখান, যাতে ক্রেতারা নিজেরাই যাচাই করতে পারেন।
- পেজ লেআউট: URL ফিল্ডটি যোগ করুন, যাতে সাপোর্ট স্টাফ “উনি কি ওঁর ব্যাজ পেয়েছেন?” প্রশ্নের উত্তর এক নজরে দিতে পারেন।
যাচাই পেজটি পাবলিক এবং এতে সাইনআপ লাগে না, আর সেটাই আসল কথা। একজন প্রাপক, একজন হায়ারিং ম্যানেজার, বা একজন গ্রাহকের প্রকিউরমেন্ট টিম লিংকটি খুলে নিশ্চিত হতে পারেন কে ক্রেডেনশিয়ালটি ইস্যু করেছে, এটি কী প্রত্যয়ন করে এবং কবে। মেশিন-রিডেবল যাচাইয়ের জন্য যেকোনো award-এর Open Badge v2.0 JSON-LD পাওয়া যায় https://api.badges.ninja/certify-badge/award/<awardId> ঠিকানায়।
প্রাপকরা স্বাভাবিক বাড়তি সুবিধাগুলোও পান: একটি অনন্য যাচাই URL, একটি QR কোড, একটি A4 PDF সার্টিফিকেট, এবং রিসিপিয়েন্ট পোর্টাল থেকে Add to LinkedIn বিকল্প, যেখানে পাসওয়ার্ডের বদলে ম্যাজিক লিংকে সাইন ইন করা হয়।
কেন এটি AppExchange-এর ব্যাজ প্লাগইনের চেয়ে ভালো
AppExchange-এর ব্যাজ প্লাগইনগুলোর দাম সাধারণত প্রতি Salesforce সিট বা ম্যানেজড-প্যাকেজ লাইসেন্স হিসেবে নির্ধারিত হয়। সেই খরচ বাড়ে আপনার Salesforce টিমের আকারের সঙ্গে, ইস্যু করা ক্রেডেনশিয়ালের সংখ্যার সঙ্গে নয়, ফলে দশজনের ট্রেনিং টিম আর দশ হাজার শিক্ষার্থীর প্রোগ্রাম একই ফলাফলের জন্য একেবারে আলাদা দাম দেয়।
API ইন্টিগ্রেশন এই মডেল উল্টে দেয়। আপনি একটি নির্দিষ্ট প্ল্যানে ক্রেডেনশিয়ালের পরিমাণ অনুযায়ী দাম দেন, ট্রিগার কোড আপনার পড়া ও বদলানোর জন্য খোলা, এবং আউটপুট স্ট্যান্ডার্ড Open Badge v2.0, তাই প্রাপকরা কোনো মালিকানাধীন ভিউয়ারে আটকে যান না। ডিজাইনের স্বাধীনতাও আপনার থাকে: একটি প্যাকেজের ভেতরের স্থির লেআউটের বদলে ভিজ্যুয়াল ডিজাইনারে আছে ৮০+ টেমপ্লেট, শেপ, আইকন ও কাস্টম আপলোড।
সৎ ভারসাম্য হলো: একটি প্লাগইন ক্লিক করে ইনস্টল করা যায় এবং Apex লাগে না। আপনার টিমে কেউ যদি কয়েক ডজন লাইন কোড রক্ষণাবেক্ষণ করতে না পারেন, তাহলে প্লাগইন বা একটি no-code কানেক্টরই ভালো মানাতে পারে। আপনি যদি ইন্টিগ্রেশন নয়, সাধারণভাবে প্ল্যাটফর্ম তুলনা করছেন, তাহলে Credly alternative বিশ্লেষণে দাম ও ফিচারের পার্থক্য পাশাপাশি দেখানো আছে।
লাইভ হওয়ার আগে পরীক্ষা
প্রথমে পুরো ফ্লো একটি স্যান্ডবক্সে চালান।
- একটি টেস্ট ব্যাজ এবং আপনার নিয়ন্ত্রণে থাকা ইমেইল ঠিকানাসহ একজন টেস্ট প্রাপক তৈরি করুন।
- Apex টেস্টে স্ট্যাটাস 200 এবং
{"awardId":"test-award-id"}ফেরত দেওয়া একটিHttpCalloutMockইমপ্লিমেন্ট করুন; Salesforce টেস্ট প্রেক্ষাপটে আসল callout অনুমতি দেয় না, আর ডিপ্লয়ের জন্য এই কভারেজ আপনার লাগবে। - স্যান্ডবক্সে একটি এনরোলমেন্ট Completed করুন এবং দেখুন
Badge_Award_Id__cওBadge_Url__cএক মিনিটের মধ্যে ভরে যায় কি না। - একটি প্রাইভেট ব্রাউজার উইন্ডোতে URL খুলে নিশ্চিত করুন পাবলিক যাচাই পেজ সাইন ইন ছাড়াই দেখা যাচ্ছে।
- ইচ্ছাকৃতভাবে ব্যর্থতা ঘটান (ব্যাজ id ফাঁকা রাখুন, বা পাঁচ অক্ষরের কম প্রাপকের নাম ব্যবহার করুন) এবং নিশ্চিত করুন ত্রুটিটি
Badge_Error__c-এ জমা হয়েছে।
API কী কখনও ডিবাগ লগ বা স্ক্রিনশটে ফাঁস হলে সেটি রোটেট করুন। API Keys পেজ থেকে বাতিল করা তাৎক্ষণিক, এবং আপনাকে কেবল External Credential আপডেট করতে হবে, কোড নয়।
উপসংহার
প্যাটার্নটি ছোট: একটি হালকা ট্রিগার ঠিক করে কখন, একটি Queueable callout করে, একটি Named Credential কী ধরে রাখে, এবং রেকর্ডের তিনটি ফিল্ড ফলাফল সংরক্ষণ করে। এটি কাজ করে ট্রেনিং মাইলস্টোন, পার্টনার টিয়ার, ইভেন্টে উপস্থিতি, বা Salesforce-এ প্রকাশ করা যায় এমন যেকোনো স্টেট পরিবর্তনের জন্য।
একটি অবজেক্ট ও একটি ব্যাজ দিয়ে শুরু করুন, এক সপ্তাহ নজর রাখুন, এবং পুনঃচেষ্টার আচরণ আপনার ডেটার সঙ্গে মানিয়ে গেলে প্রসারিত করুন।
আপনার প্রথম যাচাইযোগ্য ক্রেডেনশিয়াল ইস্যু করতে প্রস্তুত? badges.ninja-তে বিনামূল্যে শুরু করুন — ভিজ্যুয়াল ডিজাইনার, পাবলিক যাচাই পেজ, PDF সার্টিফিকেট, Open Badge v2.0 আউটপুট। কোনো ক্রেডিট কার্ড লাগবে না।
এই নিবন্ধটি যেভাবে তৈরি হয়েছে
এই ব্লগের কিছু পোস্ট এআই সহায়কের সাহায্যে খসড়া করা হয় এবং প্রকাশের আগে Badges Ninja টিম তা পর্যালোচনা, তথ্য যাচাই ও সম্পাদনা করে। প্রতিটি কোড নমুনা ও মূল্য লাইভ প্রোডাক্টের সাথে যাচাই করা হয়। আমাদের সম্পাদকীয় ও এআই প্রক্রিয়া সম্পর্কে আরও পড়ুন আমাদের সম্পাদকীয় প্রক্রিয়া পৃষ্ঠা .

লেখক সম্পর্কে
Nacho Coll
Founder & Engineer at Badges Ninja
Nacho founded Badges Ninja to make issuing verifiable digital credentials as simple as a single API call — Open Badge v2.0 badges and certificates, minted, hosted, and verifiable without standing up your own issuer infrastructure. Writes about the Open Badges spec, credential verification, and running a credentialing platform serverless on AWS, from the operator side of the wire.

