Salesforce Open Badges: emiterea de credențiale verificabile din declanșatoare CRM
Declanșează emiterea unui Open Badge din orice eveniment al unui obiect Salesforce — Lead câștigat, Account promovat, etapă de instruire încheiată — cu un apel Apex către API-ul 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.
Majoritatea echipelor de instruire înregistrează deja în Salesforce cine ce a finalizat. O înscriere la curs trece pe „Completed”, un cont de partener atinge un nivel de certificare, un client termină onboarding-ul. Înregistrarea se schimbă, iar apoi cineva exportă o listă și trimite certificatele manual, după o săptămână.
Acest ghid îți arată cum închizi acest decalaj: când o înregistrare ajunge la statusul care contează, Salesforce apelează API-ul https://badges.ninja, se emite o credențială Open Badge v2.0, iar linkul de verificare este salvat înapoi în înregistrare. Apoi poți pune linkul într-un șablon de e-mail, într-un raport sau pe o pagină Experience Cloud.
Vei avea nevoie de un administrator Salesforce (sau de un sandbox de dezvoltare), de o insignă deja proiectată pe https://badges.ninja și de o cheie API. Dacă nu ai apelat niciodată API-ul, citește mai întâi ghidul rapid al API-ului; durează zece minute.
Când un declanșator CRM este instrumentul potrivit
Înainte să scrii Apex, verifică dacă chiar ai nevoie de el. Dacă emiți credențiale în loturi, o dată pe semestru sau pe trimestru, încărcarea CSV din tabloul de bord e mai rapidă și nu cere deloc cod. Varianta Salesforce merită efortul atunci când:
- Emiterea trebuie să se petreacă în clipa în care se schimbă înregistrarea, fără niciun pas manual.
- Datele despre „cine a obținut-o” se află deja în Salesforce și nu vrei o a doua sursă de adevăr.
- Vrei ca linkul credențialei să fie stocat pe Contact, Lead sau pe înregistrarea personalizată de instruire, pentru raportare.
Dacă instrumentul tău de automatizare este Zapier, nu Apex, același apel API funcționează și acolo; vezi automatizarea Open Badges cu Zapier.
Ce construiești
Fluxul are patru componente:
- O insignă proiectată în designerul vizual. Copiază-i id-ul (
id-ul returnat deGET /badges). - O cheie API creată în pagina API Keys din tabloul tău de bord. Cheia este afișată o singură dată, așa că salveaz-o imediat.
- Un Named Credential în Salesforce care păstrează cheia, astfel încât să nu apară niciodată în cod.
- Un trigger Apex plus o clasă Queueable care emite acordarea și scrie linkul acordării înapoi în înregistrare.

Pasul 1: Stochează cheia într-un Named Credential
Greșeala de evitat este să scrii cheia API direct în Apex. În Setup, creează un External Credential cu un header personalizat, apoi un Named Credential care indică spre gazda API-ului:
- URL:
https://api.badges.ninja - Numele headerului personalizat:
X-Api-Key - Valoarea headerului personalizat: cheia ta, în forma
bws_YOUR_KEY_HERE - Numele Named Credential:
BadgesNinja
Acordă permission set-ului care rulează automatizarea acces la principalul External Credential. Cu un Named Credential pe loc, nu ai nevoie de un Remote Site Setting separat; Salesforce autorizează apelul prin credențială. Dacă organizația ta folosește încă Named Credentials vechi sau un endpoint simplu, adaugă https://api.badges.ninja ca Remote Site Setting și trimite headerul din cod.
Pasul 2: Adaugă câmpuri în înregistrare
Pe obiectul care reprezintă realizarea (vom folosi un obiect personalizat numit Training_Enrollment__c), adaugă:
Badge_Id__c(Text): insigna de emis. Dacă o stochezi per curs, un singur trigger poate deservi mai multe insigne.Badge_Award_Id__c(Text, unic): id-ul acordării returnat de API.Badge_Url__c(URL): pagina publică de verificare.Badge_Error__c(Long Text): ultima eroare, ca administratorii să vadă eșecurile fără să deschidă debug logs.
Câmpul Badge_Award_Id__c are o dublă funcție. Este protecția ta împotriva duplicatelor: triggerul emite doar când câmpul este gol.
Pasul 3: Apelul Apex
Un trigger nu poate face direct un apel extern, deoarece apelurile nu sunt permise în aceeași tranzacție cu DML necomis. Predă munca unui Queueable care implementează Database.AllowsCallouts.
Contractul API pentru POST /awards este scurt. Corpul conține badgeId, un obiect recipient imbricat cu name și email, și un issuedOn obligatoriu. Un apel reușit returnează HTTP 200 cu { "awardId": "..." }. Numele destinatarului trebuie să aibă cel puțin cinci caractere, deci un Contact numit „Al Li” ar fi respins; validează înainte să apelezi.
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;
}
}
Două detalii de remarcat. În primul rând, issuedOn este în milisecunde epoch, exact ce returnează Datetime.getTime(). În al doilea rând, răspunsul nu include URL-ul de verificare, așa că codul îl construiește din id-ul acordării: https://badges.ninja/awards/<awardId>.
Pasul 4: Triggerul
Păstrează triggerul subțire. El doar decide ce înregistrări se califică și pune în coadă câte un job pentru fiecare.
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));
}
}
}
Verificarea wasCompleted contează. Fără ea, orice modificare ulterioară a unei înregistrări finalizate ar redeclanșa logica. Împreună cu protecția „id de acordare gol” din interiorul jobului, o înregistrare poate produce vreodată o singură credențială.
O limită de respectat: Salesforce permite un număr mic de joburi Queueable puse în coadă dintr-o singură tranzacție (50 în context sincron). Dacă încarci finalizări în masă, de exemplu un import de 2.000 de rânduri, triggerul de mai sus va atinge acest plafon. Pentru încărcări în masă, fie încarci lista prin acordările în masă din CSV ale tabloului de bord, fie treci la o clasă Batchable cu Database.AllowsCallouts care procesează câteva înregistrări pe scope.

Gestionarea erorilor și reîncercările
API-ul returnează coduri de stare standard, iar fiecare cere un răspuns diferit din partea codului tău:
| Status | Semnificație | Ce faci |
|---|---|---|
| 400 | Un câmp lipsea sau era invalid, inclusiv un nume de destinatar sub cinci caractere | Nu reîncerca. Corectează datele și scrie mesajul în Badge_Error__c. |
| 401 | Cheie API greșită sau lipsă | Verifică Named Credential. Reîncercarea nu ajută până la remediere. |
| 402 | Fără credențiale sau cotă epuizată pentru planul tău | Oprește emiterea și alertează un administrator; reîncearcă după upgrade sau după resetarea cotei. |
| 404 | badgeId nu există | Corectează Badge_Id__c pe înregistrare sau pe curs. |
| 5xx sau timeout | Eșec tranzitoriu | Poți reîncerca ulterior fără risc. |
Deoarece jobul scrie eroarea în înregistrare și lasă Badge_Award_Id__c gol, o reîncercare e la fel de simplă ca bifarea unei casete sau resalvarea înregistrării. O mică clasă Apex programată care caută înscrieri finalizate fără id de acordare și cu o eroare tranzitorie, apoi le repune în coadă, îți oferă o coadă automată de reîncercări fără infrastructură suplimentară. Limitează numărul de încercări cu un câmp contor, ca o înregistrare permanent greșită să nu intre în buclă la nesfârșit.
Verifică-ți planul înainte să conectezi totul la producție. Planul Free acoperă 1.200 de credențiale pe an; Starter costă $9 pe lună, iar Pro $29 pe lună. Un trigger care se declanșează la fiecare Lead ar consuma rapid un plan mic, așa că restrânge criteriile la realizări reale.
Cum faci credențiala vizibilă în Salesforce
Odată completat Badge_Url__c, îl poți folosi oriunde:
- Alerte și șabloane de e-mail: îmbină câmpul într-un e-mail „Felicitări, iată credențiala ta”.
- Rapoarte: un raport pe
Badge_Award_Id__c != nullîți dă numărul de emiteri pe curs, regiune sau proprietar de cont. - Experience Cloud: afișează linkul pe pagina de certificare a unui partener, ca cumpărătorii să o poată verifica singuri.
- Page layouts: adaugă câmpul URL ca echipa de suport să poată răspunde dintr-o privire la „și-a primit insigna?“.
Pagina de verificare este publică și nu cere înregistrare, ceea ce e tocmai ideea. Un destinatar, un manager de recrutare sau echipa de achiziții a unui client poate deschide linkul și confirma cine a emis credențiala, ce atestă și când. Pentru verificări automate, JSON-LD-ul Open Badge v2.0 al oricărei acordări este disponibil la https://api.badges.ninja/certify-badge/award/<awardId>.
Destinatarii primesc și extrasele obișnuite: un URL unic de verificare, un cod QR, un certificat PDF A4 și opțiunea Add to LinkedIn din portalul destinatarului, care se autentifică printr-un magic link, nu printr-o parolă.
De ce e mai bun decât un plugin de insigne din AppExchange
Pluginurile de insigne din AppExchange sunt de obicei tarifate per utilizator Salesforce sau per licență de pachet gestionat. Costul crește cu mărimea echipei tale Salesforce, nu cu numărul de credențiale emise, așa că o echipă de instruire de zece persoane și un program cu zece mii de cursanți plătesc foarte diferit pentru același rezultat.
O integrare prin API inversează modelul. Plătești în funcție de volumul de credențiale, pe un plan fix, codul triggerului este al tău, îl poți citi și modifica, iar rezultatul este Open Badge v2.0 standard, deci destinatarii nu sunt blocați într-un vizualizator proprietar. Îți păstrezi și libertatea de design: designerul vizual oferă peste 80 de șabloane, forme, pictograme și încărcări personalizate, nu un aspect fix dintr-un pachet.
Compromisul sincer: un plugin se instalează cu un clic și nu cere Apex. Dacă nimeni din echipa ta nu poate întreține câteva zeci de linii de cod, un plugin sau un conector no-code poate fi alegerea mai bună. Dacă compari platforme în general, nu integrări, analiza alternativei la Credly acoperă prețurile și diferențele de funcții una lângă alta.
Testarea înainte de lansare
Rulează mai întâi tot fluxul într-un sandbox.
- Creează o insignă de test și un destinatar de test cu o adresă de e-mail pe care o controlezi.
- În testele Apex, implementează
HttpCalloutMockcare returnează statusul 200 și{"awardId":"test-award-id"}; Salesforce nu permite apeluri reale în contextul de test, iar ai nevoie de această acoperire pentru a face deploy. - În sandbox, setează o înscriere pe Completed și verifică dacă
Badge_Award_Id__cșiBadge_Url__cse completează în decurs de un minut. - Deschide URL-ul într-o fereastră privată de browser pentru a confirma că pagina publică de verificare se afișează fără autentificare.
- Provoacă un eșec (lasă gol id-ul insignei sau folosește un nume de destinatar sub cinci caractere) și confirmă că eroarea ajunge în
Badge_Error__c.
Rotește cheia API dacă ajunge vreodată într-un debug log sau într-o captură de ecran. Revocarea este imediată din pagina API Keys și trebuie să actualizezi doar External Credential, nu codul.
Încheiere
Tiparul este mic: un trigger subțire decide când, un Queueable face apelul, un Named Credential păstrează cheia, iar trei câmpuri din înregistrare stochează rezultatul. Funcționează pentru etape de instruire, niveluri de parteneri, participarea la evenimente sau orice schimbare de stare pe care o poți exprima în Salesforce.
Începe cu un singur obiect și o singură insignă, urmărește-le o săptămână și extinde după ce comportamentul reîncercărilor se potrivește datelor tale.
Ești gata să emiți prima ta credențială verificabilă? Începe gratuit pe badges.ninja — designer vizual, pagină publică de verificare, certificat PDF, ieșire Open Badge v2.0. Fără card de credit.
Cum a fost realizat acest articol
Unele articole de pe acest blog sunt redactate cu ajutorul unui asistent AI, apoi revizuite, verificate și editate de echipa Badges Ninja înainte de publicare. Fiecare exemplu de cod și fiecare preț este verificat cu produsul live. Citește mai multe despre procesul nostru editorial și de AI pe pagina despre procesul editorial .

Despre autor
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.
Mai multe de la Nacho Coll
- Emiterea de Open Badges prin API-ul REST Badges Ninja: ghid rapid28 sept. 2026 · 10min de citit
- Integrează verificarea insignelor pe site-ul tău (fără iframe, fără SDK)24 sept. 2026 · 10min de citit
- Certifier vs Accredible: comparație între platformele de certificate (2026)21 sept. 2026 · 10min de citit

