Salesforce Open Badges: издавање верификованих сертификата из CRM окидача
Окините издавање Open Badge-а при било ком догађају на Salesforce објекту — добијен Lead, надограђен Account, завршен корак обуке — помоћу Apex callout-а ка Badges Ninja API-ју.
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 позива API на https://badges.ninja, издаје се Open Badge v2.0 сертификат, а линк за верификацију се уписује назад у запис. Тај линк затим можете убацити у имејл шаблон, извештај или страницу на Experience Cloud-у.
Потребни су вам Salesforce администратор (или developer sandbox), већ направљена значка на https://badges.ninja и API кључ. Ако никада нисте позивали API, прво прочитајте брзи почетак за API; траје десет минута.
Када је CRM окидач прави алат
Пре него што напишете Apex, проверите да ли вам је уопште потребан. Ако сертификате издајете у серијама једном по семестру или кварталу, CSV отпремање са контролне табле је брже и не захтева никакав код. Salesforce приступ се исплати када:
- Издавање треба да се деси чим се запис промени, без људског корака.
- Подаци о томе „ко је шта заслужио“ већ живе у Salesforce-у и не желите други извор истине.
- Желите да се линк ка сертификату чува на Contact-у, Lead-у или прилагођеном запису обуке ради извештавања.
Ако је ваш алат за токове рада Zapier, а не Apex, исти API позив ради и тамо; погледајте аутоматизацију Open Badges-а помоћу Zapier-а.
Шта градите
Ток има четири дела:
- Значка направљена у визуелном дизајнеру. Копирајте њен id (поље
idкоје враћаGET /badges). - API кључ направљен на страници API Keys ваше контролне табле. Кључ се приказује само једном, зато га одмах сачувајте.
- Named Credential у Salesforce-у који чува кључ, да се никада не појављује у коду.
- Apex окидач плус Queueable класа која издаје награду и уписује линк ка њој назад у запис.

Корак 1: Сачувајте кључ у Named Credential-у
Чврсто кодиран API кључ у Apex-у је грешка коју треба избећи. У Setup-у направите External Credential са прилагођеним хедером, а затим Named Credential који показује на хост API-ја:
- URL:
https://api.badges.ninja - Назив прилагођеног хедера:
X-Api-Key - Вредност прилагођеног хедера: ваш кључ у облику
bws_YOUR_KEY_HERE - Назив Named Credential-а:
BadgesNinja
Дајте permission set-у који покреће вашу аутоматизацију приступ principal-у External Credential-а. Када постоји Named Credential, не треба вам посебна Remote Site Setting; Salesforce ауторизује callout преко credential-а. Ако ваша организација још користи старије Named Credentials или обичан endpoint, додајте https://api.badges.ninja као Remote Site Setting и шаљите хедер из кода.
Корак 2: Додајте поља на запис
На објекту који представља постигнуће (користићемо прилагођени објекат Training_Enrollment__c) додајте:
Badge_Id__c(Text): значка коју треба издати. Ако је чувате по курсу, један окидач опслужује много значки.Badge_Award_Id__c(Text, unique): id награде који враћа API.Badge_Url__c(URL): јавна страница за верификацију.Badge_Error__c(Long Text): последња грешка, да администратори виде неуспехе без отварања debug логова.
Поље Badge_Award_Id__c ради двоструки посао. То је ваша заштита од дупликата: окидач издаје само када је оно празно.
Корак 3: Apex callout
Окидач не може да направи callout директно, јер callout-и нису дозвољени у истој трансакцији са неуписаним DML-ом. Предајте посао Queueable-у који имплементира Database.AllowsCallouts.
Уговор API-ја за POST /awards је кратак. Тело садржи badgeId, угнежђен објекат recipient са name и email, и обавезан issuedOn. Успешан позив враћа HTTP 200 са { "awardId": "..." }. Име примаоца мора имати најмање пет знакова, па ће Contact са именом „Al Li“ бити одбијен; проверите пре позива.
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 за верификацију, па га код склапа од id-ја награде: https://badges.ninja/awards/<awardId>.
Корак 4: Окидач
Држите окидач танким. Он само одлучује који записи испуњавају услов и ставља у ред по један посао за сваки запис.
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 послова у реду из једне трансакције (50 у синхроном контексту). Ако масовно учитавате завршетке, рецимо увоз од 2.000 редова, горњи окидач ће погодити то ограничење. За масовна учитавања или отпремите списак преко масовних награда путем CSV-а на контролној табли, или пређите на Batchable класу са Database.AllowsCallouts која обрађује по неколико записа по опсегу.

Обрада грешака и поновни покушаји
API враћа стандардне статус кодове, а сваки захтева другачији одговор вашег кода:
| Статус | Значење | Шта урадити |
|---|---|---|
| 400 | Поље недостаје или је неважеће, укључујући име примаоца краће од пет знакова | Не понављајте. Исправите податке и упишите поруку у Badge_Error__c. |
| 401 | Погрешан или непостојећи API кључ | Проверите Named Credential. Понављање неће помоћи док се не исправи. |
| 402 | Нема више сертификата или квоте за ваш план | Зауставите издавање и обавестите администратора; покушајте поново након надоградње или ресетовања квоте. |
| 404 | badgeId не постоји | Исправите Badge_Id__c на запису или курсу. |
| 5xx или timeout | Привремени квар | Безбедно је покушати касније. |
Пошто посао уписује грешку у запис и оставља Badge_Award_Id__c празним, поновни покушај је једноставан као промена чекбокса или поновно снимање записа. Мала заказана Apex класа која тражи завршене уписе без award id-ја и са привременом грешком, па их поново ставља у ред, даје вам аутоматски ред за поновне покушаје без додатне инфраструктуре. Ограничите покушаје пољем-бројачем да трајно лош запис не би кружио у недоглед.
Проверите свој план пре него што ово повежете са продукцијом. План Free покрива 1.200 сертификата годишње; Starter је $9 месечно, а Pro је $29 месечно. Окидач који се активира на сваки Lead брзо би потрошио мали план, зато ограничите критеријуме на стварна постигнућа.
Како сертификат учинити видљивим у Salesforce-у
Када се Badge_Url__c попуни, можете га користити било где:
- Имејл обавештења и шаблони: убаците поље у имејл „Честитамо, ево вашег сертификата“.
- Извештаји: извештај по
Badge_Award_Id__c != nullдаје вам број издатих по курсу, региону или власнику налога. - Experience Cloud: прикажите линк на партнеровој страници сертификације да га купци могу сами верификовати.
- Page layouts: додајте URL поље да подршка на први поглед одговори на „да ли је добила значку?“.
Страница за верификацију је јавна и не тражи регистрацију, у томе је цела поента. Прималац, послодавац или набавка клијента може отворити линк и потврдити ко је издао сертификат, шта он потврђује и када. За машински читљиве провере, Open Badge v2.0 JSON-LD за било коју награду доступан је на https://api.badges.ninja/certify-badge/award/<awardId>.
Примаоци добијају и уобичајене додатке: јединствен URL за верификацију, QR код, PDF сертификат формата A4 и опцију Add to LinkedIn са портала за примаоце, који се пријављује magic линком, а не лозинком.
Зашто је ово боље од плагина за значке са AppExchange-а
Плагини за значке на AppExchange-у обично се наплаћују по Salesforce кориснику или по лиценци managed пакета. Тај трошак расте са величином вашег Salesforce тима, а не са бројем издатих сертификата, па десеточлани тим за обуку и програм са десет хиљада полазника плаћају веома различито за исти резултат.
API интеграција обрће тај модел. Плаћате према обиму сертификата на фиксном плану, код окидача је ваш да га читате и мењате, а резултат је стандардни Open Badge v2.0, па примаоци нису закључани у власнички прегледач. Задржавате и слободу дизајна: визуелни дизајнер нуди 80+ шаблона, облика, икона и прилагођених отпремања, уместо фиксног распореда унутар пакета.
Поштен компромис: плагин се инсталира једним кликом и не тражи Apex. Ако нико у вашем тиму не може да одржава неколико десетина редова кода, плагин или no-code конектор може бити бољи избор. Ако упоређујете платформе уопште, а не интеграције, преглед алтернативе за Credly поредно покрива цене и разлике у функцијама.
Тестирање пре пуштања у рад
Прво покрените цео ток у sandbox-у.
- Направите пробну значку и пробног примаоца са имејл адресом коју контролишете.
- У Apex тестовима имплементирајте
HttpCalloutMockкоји враћа статус 200 и{"awardId":"test-award-id"}; Salesforce не дозвољава стварне callout-е у тест контексту, а то покривање вам је потребно за деплој. - У sandbox-у поставите један упис на Completed и проверите да се
Badge_Award_Id__cиBadge_Url__cпопуне у року од минут. - Отворите URL у приватном прозору прегледача да потврдите да се јавна страница за верификацију приказује без пријављивања.
- Изазовите грешку (обришите id значке или користите име примаоца краће од пет знакова) и потврдите да грешка стиже у
Badge_Error__c.
Промените API кључ ако икада процури у debug лог или снимак екрана. Опозив је тренутан са странице 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.

