Salesforce Open Badges: Udsted verificerbare credentials fra CRM-triggere
Udløs udstedelse af Open Badge fra enhver hændelse på et Salesforce-objekt — Lead vundet, Account opgraderet, træningsmilepæl — med et Apex-callout til Badges Ninja API'et.
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.
De fleste træningsteams registrerer allerede i Salesforce, hvem der har gennemført hvad. En kursustilmelding skifter til “Completed”, en partnerkonto når et certificeringsniveau, en kunde bliver færdig med onboarding. Posten ændrer sig, og så eksporterer nogen en liste og sender certifikater i hånden en uge senere.
Den her guide viser, hvordan du lukker det hul: Når en post når den status, du interesserer dig for, kalder Salesforce https://badges.ninja API’et, der udstedes en Open Badge v2.0-credential, og verificeringslinket gemmes tilbage på posten. Derefter kan du indsætte linket i en e-mailskabelon, en rapport eller en Experience Cloud-side.
Du skal bruge en Salesforce-administrator (eller en developer sandbox), et badge, der allerede er designet på https://badges.ninja, og en API-nøgle. Hvis du aldrig har kaldt API’et før, så læs først API-quickstart. Det tager ti minutter.
Hvornår en CRM-trigger er det rigtige værktøj
Før du skriver Apex, så tjek, om du overhovedet har brug for det. Hvis du udsteder credentials i batches én gang pr. semester eller kvartal, er dashboardets CSV-upload hurtigere og kræver slet ingen kode. Salesforce-vejen betaler sig, når:
- Udstedelsen skal ske i det øjeblik, en post ændrer sig, uden noget menneskeligt trin.
- Data om, hvem der har opnået det, allerede ligger i Salesforce, og du ikke vil have en ekstra kilde til sandheden.
- Du vil have credential-linket gemt på Contact, Lead eller en brugerdefineret træningspost til rapportering.
Hvis dit workflow-værktøj er Zapier frem for Apex, virker det samme API-kald også dér; se Zapier Open Badges-automatisering.
Hvad du bygger
Flowet har fire dele:
- Et badge designet i det visuelle designværktøj. Kopiér dets id (det
id, somGET /badgesreturnerer). - En API-nøgle oprettet på siden API Keys i dit dashboard. Nøglen vises kun én gang, så gem den med det samme.
- En Named Credential i Salesforce, der rummer nøglen, så den aldrig optræder i koden.
- En Apex-trigger plus en Queueable-klasse, der udsteder tildelingen og skriver tildelingslinket tilbage på posten.

Trin 1: Gem nøglen i en Named Credential
At hardcode en API-nøgle i Apex er den fejl, du skal undgå. Opret i Setup en External Credential med en brugerdefineret header, og derefter en Named Credential, der peger på API-værten:
- URL:
https://api.badges.ninja - Custom header name:
X-Api-Key - Custom header value: din nøgle, i formen
bws_YOUR_KEY_HERE - Named Credential name:
BadgesNinja
Giv det permission set, der kører din automatisering, adgang til External Credentialens principal. Med en Named Credential på plads behøver du ikke en separat Remote Site Setting; Salesforce autoriserer callouttet via credentialen. Hvis din org stadig bruger ældre Named Credentials eller et almindeligt endpoint, så tilføj https://api.badges.ninja som Remote Site Setting og send headeren fra koden i stedet.
Trin 2: Tilføj felter til posten
På det objekt, der repræsenterer præstationen (vi bruger et brugerdefineret objekt kaldet Training_Enrollment__c), tilføjer du:
Badge_Id__c(Text): det badge, der skal udstedes. Når du gemmer det pr. kursus, kan én trigger betjene mange badges.Badge_Award_Id__c(Text, unique): tildelings-id’et, som API’et returnerer.Badge_Url__c(URL): den offentlige verificeringsside.Badge_Error__c(Long Text): den seneste fejl, så administratorer kan se fejl uden at åbne debug-logs.
Feltet Badge_Award_Id__c har en dobbelt funktion. Det er din beskyttelse mod dubletter: Triggeren udsteder kun, når det er tomt.
Trin 3: Apex-callouttet
En trigger kan ikke foretage et callout direkte, fordi callouts ikke er tilladt i den samme transaktion som ikke-committet DML. Overlad arbejdet til en Queueable, der implementerer Database.AllowsCallouts.
API-kontrakten for POST /awards er kort. Body’en indeholder badgeId, et indlejret recipient-objekt med name og email samt et obligatorisk issuedOn. Et vellykket kald returnerer HTTP 200 med { "awardId": "..." }. Modtagerens navn skal være mindst fem tegn langt, så en Contact ved navn “Al Li” ville blive afvist; valider, før du kalder.
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;
}
}
To detaljer er værd at lægge mærke til. For det første er issuedOn epoch-millisekunder, som er præcis det, Datetime.getTime() returnerer. For det andet indeholder svaret ikke verificerings-URL’en, så koden bygger den ud fra tildelings-id’et: https://badges.ninja/awards/<awardId>.
Trin 4: Triggeren
Hold triggeren tynd. Den afgør kun, hvilke poster der kvalificerer, og sætter ét job i kø pr. post.
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));
}
}
}
Tjekket wasCompleted er vigtigt. Uden det ville enhver senere redigering af en gennemført post udløse logikken igen. Sammen med beskyttelsen mod tomt tildelings-id inde i jobbet kan en post kun nogensinde frembringe én credential.
Én grænse skal du respektere: Salesforce tillader et lille antal Queueable-job i kø fra en enkelt transaktion (50 i synkron kontekst). Hvis du indlæser gennemførelser i bulk, fx en dataimport på 2.000 rækker, vil triggeren ovenfor ramme det loft. Ved bulkindlæsninger kan du enten uploade listen via dashboardets CSV-bulktildelinger i stedet eller skifte til en Batchable-klasse med Database.AllowsCallouts, der behandler nogle få poster pr. scope.

Fejlhåndtering og genforsøg
API’et returnerer standardstatuskoder, og hver af dem kræver sit svar fra din kode:
| Status | Betydning | Hvad du skal gøre |
|---|---|---|
| 400 | Et felt manglede eller var ugyldigt, herunder et modtagernavn under fem tegn | Forsøg ikke igen. Ret dataene og skriv beskeden til Badge_Error__c. |
| 401 | Forkert eller manglende API-nøgle | Tjek Named Credentialen. Genforsøg hjælper ikke, før den er rettet. |
| 402 | Ikke flere credentials eller kvote for din plan | Stop udstedelsen og giv en administrator besked; forsøg igen efter en opgradering eller når kvoten nulstilles. |
| 404 | badgeId findes ikke | Ret Badge_Id__c på posten eller kurset. |
| 5xx eller timeout | Midlertidig fejl | Sikkert at forsøge igen senere. |
Fordi jobbet skriver fejlen til posten og lader Badge_Award_Id__c stå tomt, er et genforsøg lige så enkelt som at slå en afkrydsningsboks til eller gemme posten igen. En lille planlagt Apex-klasse, der leder efter gennemførte tilmeldinger uden tildelings-id og med en midlertidig fejl og derefter sætter dem i kø igen, giver dig en automatisk genforsøgskø uden ekstra infrastruktur. Begræns antallet af forsøg med et tællerfelt, så en permanent dårlig post ikke løber i ring for evigt.
Tjek din plan, før du kobler det til produktion. Free-planen dækker 1.200 credentials om året; Starter koster $9 om måneden og Pro $29 om måneden. En trigger, der udløses på hver Lead, ville hurtigt æde en lille plan, så afgræns kriterierne til reelle præstationer.
Gør credentialen synlig i Salesforce
Når Badge_Url__c er udfyldt, kan du bruge den overalt:
- E-mailalarmer og skabeloner: flet feltet ind i en e-mail med “Tillykke, her er din credential”.
- Rapporter: en rapport på
Badge_Award_Id__c != nullgiver dig antal udstedelser pr. kursus, region eller kontoejer. - Experience Cloud: vis linket på en partners certificeringsside, så købere selv kan verificere det.
- Page layouts: tilføj URL-feltet, så supportmedarbejdere kan svare på “fik hun sit badge?” med et enkelt blik.
Verificeringssiden er offentlig og kræver ingen tilmelding, og det er hele pointen. En modtager, en rekrutteringsansvarlig eller en kundes indkøbsafdeling kan åbne linket og bekræfte, hvem der har udstedt credentialen, hvad den certificerer, og hvornår. Til maskinlæsbare tjek findes Open Badge v2.0 JSON-LD for enhver tildeling på https://api.badges.ninja/certify-badge/award/<awardId>.
Modtagere får også de sædvanlige ekstra ting: en unik verificerings-URL, en QR-kode, et A4-PDF-certifikat og en Add to LinkedIn-mulighed fra modtagerportalen, som logger ind med et magic link frem for en adgangskode.
Hvorfor det slår et AppExchange-badgeplugin
Badgeplugins på AppExchange er typisk prissat pr. Salesforce-bruger eller pr. managed-package-licens. Den pris skalerer med størrelsen af dit Salesforce-team, ikke med antallet af credentials, du udsteder, så et træningsteam på ti personer og et program med ti tusind kursister betaler vidt forskelligt for det samme output.
En API-integration vender den model om. Du betaler efter credential-volumen på en fast plan, triggerkoden er din at læse og ændre, og outputtet er standard Open Badge v2.0, så modtagerne ikke er låst til en proprietær viewer. Du bevarer også din designfrihed: Det visuelle designværktøj tilbyder 80+ skabeloner, former, ikoner og egne uploads i stedet for et fast layout inde i en pakke.
Den ærlige afvejning: Et plugin installeres med et klik og kræver ingen Apex. Hvis ingen på dit team kan vedligeholde nogle få dusin linjer kode, kan et plugin eller en no-code-connector være det bedre valg. Hvis du sammenligner platforme generelt frem for integrationer, dækker gennemgangen Credly-alternativ priser og funktionsforskelle side om side.
Test, før du går live
Kør hele flowet i en sandbox først.
- Opret et testbadge og en testmodtager med en e-mailadresse, du selv kontrollerer.
- Implementer i Apex-tests en
HttpCalloutMock, der returnerer status 200 og{"awardId":"test-award-id"}; Salesforce tillader ikke rigtige callouts i testkontekst, og du skal bruge den dækning for at deploye. - Sæt i sandboxen én tilmelding til Completed, og tjek, at
Badge_Award_Id__cogBadge_Url__cbliver udfyldt inden for et minut. - Åbn URL’en i et privat browservindue for at bekræfte, at den offentlige verificeringsside vises uden login.
- Fremprovokér en fejl (tøm badge-id’et, eller brug et modtagernavn under fem tegn), og bekræft, at fejlen lander i
Badge_Error__c.
Roter API-nøglen, hvis den nogensinde slipper ud i en debug-log eller et screenshot. Tilbagekaldelse sker øjeblikkeligt fra siden API Keys, og du skal kun opdatere External Credentialen, ikke din kode.
Opsummering
Mønsteret er lille: En tynd trigger afgør hvornår, en Queueable udfører callouttet, en Named Credential rummer nøglen, og tre felter på posten gemmer resultatet. Det virker til træningsmilepæle, partnerniveauer, eventdeltagelse eller enhver tilstandsændring, du kan udtrykke i Salesforce.
Start med ét objekt og ét badge, hold øje med det i en uge, og udvid, når genforsøgsadfærden passer til dine data.
Klar til at udstede din første verificerbare credential? Kom i gang gratis på badges.ninja — visuelt designværktøj, offentlig verificeringsside, PDF-certifikat, Open Badge v2.0-output. Intet kreditkort påkrævet.
Sådan blev denne artikel til
Nogle indlæg på denne blog udarbejdes med hjælp fra en AI-assistent og gennemgås, faktatjekkes og redigeres af Badges Ninja-teamet inden udgivelse. Alle kodeeksempler og priser verificeres mod det live produkt. Læs mere om vores redaktionelle proces og AI-proces på vores side om vores redaktionelle proces .

Om forfatteren
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.

