Salesforce Open Badges: издаване на верифицируеми удостоверения от CRM тригери
Задействайте издаването на Open Badge при всяко събитие на обект в Salesforce — спечелен Lead, надграден Account, учебен етап — с Apex callout към API на 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.
Повечето обучителни екипи вече записват в 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 link, а не с парола.
Защо това е по-добре от плъгин за значки от 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. Без кредитна карта.
Как беше създадена тази статия
Някои публикации в този блог се изготвят с помощта на AI асистент, след което се преглеждат, проверяват и редактират от екипа на Badges Ninja преди публикуване. Всеки примерен код и цена се проверяват спрямо реалния продукт. Прочетете повече за нашия редакционен и AI процес на нашата страница за редакционния процес .

За автора
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.

