Salesforce Open Badges: ellenőrizhető tanúsítványok kibocsátása CRM-eseményekből
Indíts Open Badge kibocsátást bármely Salesforce objektumesemény alapján — megnyert Lead, magasabb szintre lépett Account, teljesített képzési mérföldkő — egy Apex hívással a Badges Ninja API-ra.
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.
A legtöbb képzési csapat már most is a Salesforce-ban rögzíti, ki mit végzett el. Egy kurzusjelentkezés „Completed” állapotba kerül, egy partnerfiók eléri a tanúsítási szintet, egy ügyfél befejezi az onboardingot. A rekord megváltozik, aztán valaki egy hét múlva kiexportál egy listát, és kézzel e-mailezi a tanúsítványokat.
Ez az útmutató megmutatja, hogyan zárhatod be ezt a rést: amikor egy rekord eléri a számodra fontos állapotot, a Salesforce meghívja a https://badges.ninja API-t, kibocsátásra kerül egy Open Badge v2.0 tanúsítvány, az ellenőrző link pedig visszaíródik a rekordra. Ezt a linket utána beillesztheted e-mailsablonba, riportba vagy Experience Cloud oldalra.
Szükséged lesz egy Salesforce adminra (vagy fejlesztői sandboxra), egy már megtervezett jelvényre a https://badges.ninja oldalon, és egy API-kulcsra. Ha még sosem hívtad az API-t, olvasd el előbb az API gyorsindítót; tíz percet vesz igénybe.
Mikor jó eszköz a CRM-esemény
Mielőtt Apexet írsz, nézd meg, kell-e egyáltalán. Ha félévente vagy negyedévente, kötegekben bocsátasz ki tanúsítványokat, a vezérlőpult CSV-feltöltése gyorsabb, és egyáltalán nem igényel kódot. A Salesforce-os út akkor éri meg, ha:
- A kibocsátásnak a rekord megváltozásának pillanatában kell megtörténnie, emberi lépés nélkül.
- A „ki szerezte meg” adat már a Salesforce-ban van, és nem akarsz második igazságforrást.
- A tanúsítvány linkjét a Contact, Lead vagy egyedi képzési rekordon szeretnéd tárolni riportoláshoz.
Ha a munkafolyamat-eszközöd a Zapier az Apex helyett, ugyanez az API-hívás ott is működik; lásd a Zapier Open Badges automatizálást.
Mit építesz
A folyamat négy elemből áll:
- Egy jelvény, amelyet a vizuális szerkesztőben terveztél. Másold ki az azonosítóját (a
GET /badgesáltal visszaadottid). - Egy API-kulcs, amelyet a vezérlőpult API Keys oldalán hozol létre. A kulcs csak egyszer jelenik meg, ezért azonnal tárold el.
- Egy Named Credential a Salesforce-ban, amely a kulcsot tartja, így az sosem jelenik meg a kódban.
- Egy Apex trigger és egy Queueable osztály, amely kibocsátja az elismerést, és visszaírja a rekordra az elismerés linkjét.

1. lépés: Tárold a kulcsot Named Credentialben
Az API-kulcs Apexbe égetése az a hiba, amit el kell kerülni. A Setupban hozz létre egy External Credentialt egyéni fejléccel, majd egy Named Credentialt, amely az API hosztjára mutat:
- URL:
https://api.badges.ninja - Egyéni fejléc neve:
X-Api-Key - Egyéni fejléc értéke: a kulcsod
bws_YOUR_KEY_HEREformában - Named Credential neve:
BadgesNinja
Adj hozzáférést az External Credential principaljához annak a permission setnek, amely az automatizálásodat futtatja. Named Credential mellett nincs szükség külön Remote Site Settingre; a Salesforce a credentialen keresztül engedélyezi a hívást. Ha a szervezeted még régi Named Credentialeket vagy sima endpointot használ, add hozzá a https://api.badges.ninja címet Remote Site Settingként, és a fejlécet küldd a kódból.
2. lépés: Adj mezőket a rekordhoz
Azon az objektumon, amely az eredményt képviseli (mi egy Training_Enrollment__c nevű egyedi objektumot használunk), vedd fel:
Badge_Id__c(Text): a kibocsátandó jelvény. Ha kurzusonként tárolod, egyetlen trigger több jelvényt is kiszolgálhat.Badge_Award_Id__c(Text, egyedi): az API által visszaadott elismerésazonosító.Badge_Url__c(URL): a nyilvános ellenőrző oldal.Badge_Error__c(Long Text): az utolsó hiba, hogy az adminok debug logok megnyitása nélkül lássák a hibákat.
A Badge_Award_Id__c mező kettős szerepet tölt be. Ez a duplikáció elleni védelmed: a trigger csak akkor bocsát ki, ha üres.
3. lépés: Az Apex hívás
Trigger nem hajthat végre közvetlenül külső hívást, mert a hívások nem engedélyezettek ugyanabban a tranzakcióban a még nem véglegesített DML-lel. Add át a munkát egy Database.AllowsCallouts-ot implementáló Queueable-nek.
A POST /awards API-szerződése rövid. A törzs tartalmazza a badgeId-t, egy beágyazott recipient objektumot name és email mezőkkel, valamint a kötelező issuedOn-t. A sikeres hívás HTTP 200-at ad vissza { "awardId": "..." } tartalommal. A címzett nevének legalább öt karakteresnek kell lennie, így egy „Al Li” nevű Contactot elutasítanának; hívás előtt érvényesítsd.
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;
}
}
Két említésre méltó részlet. Egyrészt az issuedOn epoch ezredmásodperc, pontosan az, amit a Datetime.getTime() visszaad. Másrészt a válasz nem tartalmazza az ellenőrző URL-t, ezért a kód az elismerés azonosítójából építi fel: https://badges.ninja/awards/<awardId>.
4. lépés: A trigger
Tartsd vékonyan a triggert. Csak azt dönti el, mely rekordok felelnek meg, és rekordonként egy jobot állít sorba.
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));
}
}
}
A wasCompleted ellenőrzés számít. Nélküle egy teljesített rekord bármely későbbi szerkesztése újra lefuttatná a logikát. A jobon belüli üres-elismerésazonosító védelemmel együtt egy rekord csak egyetlen tanúsítványt hozhat létre.
Egy betartandó korlát: a Salesforce egyetlen tranzakcióból csak kevés Queueable job sorba állítását engedi (szinkron környezetben 50-et). Ha tömegesen töltesz be teljesítéseket, mondjuk egy 2000 soros adatimporttal, a fenti trigger eléri ezt a plafont. Tömeges betöltésnél vagy töltsd fel a listát a vezérlőpult CSV-alapú tömeges elismerésével, vagy válts egy Database.AllowsCallouts-ot használó Batchable osztályra, amely scope-onként néhány rekordot dolgoz fel.

Hibakezelés és újrapróbálkozások
Az API szabványos állapotkódokat ad vissza, és mindegyik másfajta választ kíván a kódodtól:
| Státusz | Jelentés | Teendő |
|---|---|---|
| 400 | Hiányzó vagy érvénytelen mező, beleértve az öt karakternél rövidebb címzettnevet | Ne próbáld újra. Javítsd az adatot, és írd az üzenetet a Badge_Error__c mezőbe. |
| 401 | Hibás vagy hiányzó API-kulcs | Ellenőrizd a Named Credentialt. Az újrapróbálás a javításig nem segít. |
| 402 | Elfogytak a tanúsítványok vagy a csomagod kerete | Állítsd le a kibocsátást, és értesíts egy admint; próbáld újra a csomag bővítése vagy a keret nullázódása után. |
| 404 | A badgeId nem létezik | Javítsd a Badge_Id__c értékét a rekordon vagy a kurzuson. |
| 5xx vagy időtúllépés | Átmeneti hiba | Később nyugodtan újrapróbálható. |
Mivel a job a hibát a rekordra írja, és a Badge_Award_Id__c üres marad, az újrapróbálás olyan egyszerű, mint egy jelölőnégyzet átkapcsolása vagy a rekord újramentése. Egy kis ütemezett Apex osztály, amely megkeresi a teljesített jelentkezéseket elismerésazonosító nélkül és átmeneti hibával, majd újra sorba állítja őket, extra infrastruktúra nélkül automatikus újrapróbálási sort ad. Korlátozd a próbálkozások számát számlálómezővel, hogy egy tartósan hibás rekord ne forogjon örökké.
Mielőtt élesbe kötöd, ellenőrizd a csomagodat. A Free csomag évi 1200 tanúsítványt fed le; a Starter havi $9, a Pro havi $29. Egy minden Leadnél lefutó trigger gyorsan felemésztene egy kis csomagot, ezért a feltételeket valódi teljesítményekre szűkítsd.
A tanúsítvány láthatóvá tétele a Salesforce-ban
Ha a Badge_Url__c kitöltődött, bárhol felhasználhatod:
- E-mail értesítések és sablonok: olvaszd bele a mezőt egy „Gratulálunk, itt a tanúsítványod” e-mailbe.
- Riportok: a
Badge_Award_Id__c != nullfeltételű riport kurzusonkénti, régiónkénti vagy fiókfelelősönkénti kibocsátási számokat ad. - Experience Cloud: jelenítsd meg a linket egy partner tanúsítási oldalán, hogy a vevők maguk ellenőrizhessék.
- Page layoutok: add hozzá az URL mezőt, hogy a support egy pillantással megválaszolhassa: „megkapta már a jelvényét?”
Az ellenőrző oldal nyilvános, és nem kér regisztrációt, ez a lényege. Egy címzett, egy felvételi vezető vagy egy ügyfél beszerzési csapata megnyithatja a linket, és megerősítheti, ki bocsátotta ki a tanúsítványt, mit igazol, és mikor. Gépi ellenőrzéshez bármely elismerés Open Badge v2.0 JSON-LD-je elérhető a https://api.badges.ninja/certify-badge/award/<awardId> címen.
A címzettek a szokásos extrákat is megkapják: egyedi ellenőrző URL, QR-kód, A4-es PDF tanúsítvány és Add to LinkedIn opció a címzetti portálról, amely jelszó helyett magic linkkel léptet be.
Miért jobb egy AppExchange jelvénybővítménynél
Az AppExchange jelvénybővítményei jellemzően Salesforce-felhasználónként vagy managed package licencenként árazottak. Ez a költség a Salesforce-csapatod méretével nő, nem a kibocsátott tanúsítványok számával, így egy tízfős képzési csapat és egy tízezer tanulós program nagyon eltérő összeget fizet ugyanazért a kimenetért.
Az API-integráció megfordítja ezt a modellt. A tanúsítványok mennyisége szerint fizetsz, fix csomaggal, a trigger kódja a tiéd, olvashatod és módosíthatod, a kimenet pedig szabványos Open Badge v2.0, így a címzettek nincsenek egy saját fejlesztésű megjelenítőhöz kötve. A tervezési szabadságod is megmarad: a vizuális szerkesztő több mint 80 sablont, formát, ikont és egyedi feltöltést kínál, nem egy csomagon belüli fix elrendezést.
Az őszinte kompromisszum: a bővítmény egy kattintással telepíthető, és nem kell hozzá Apex. Ha a csapatodban senki sem tud karbantartani pár tucat sornyi kódot, egy bővítmény vagy no-code összekötő lehet a jobb választás. Ha általában platformokat hasonlítasz össze, nem integrációkat, a Credly alternatíva összehasonlítás egymás mellett mutatja az árakat és a funkciókülönbségeket.
Tesztelés élesítés előtt
Az egész folyamatot előbb sandboxban futtasd le.
- Hozz létre egy teszt jelvényt és egy teszt címzettet olyan e-mail-címmel, amelyet te kezelsz.
- Az Apex tesztekben implementálj egy
HttpCalloutMock-ot, amely 200-as státuszt és{"awardId":"test-award-id"}választ ad; a Salesforce nem enged valódi hívást teszt kontextusban, és erre a lefedettségre szükséged van a deployhoz. - A sandboxban állíts egy jelentkezést Completed állapotra, és ellenőrizd, hogy a
Badge_Award_Id__cés aBadge_Url__cegy percen belül kitöltődik. - Nyisd meg az URL-t privát böngészőablakban, hogy megbizonyosodj: a nyilvános ellenőrző oldal bejelentkezés nélkül megjelenik.
- Idézz elő hibát (hagyd üresen a jelvényazonosítót, vagy használj öt karakternél rövidebb címzettnevet), és ellenőrizd, hogy a hiba a
Badge_Error__cmezőbe kerül.
Cseréld le az API-kulcsot, ha valaha kiszivárog egy debug logba vagy képernyőképre. A visszavonás azonnali az API Keys oldalról, és csak az External Credentialt kell frissítened, a kódot nem.
Összegzés
A minta kicsi: egy vékony trigger dönti el a mikort, egy Queueable végzi a hívást, egy Named Credential tartja a kulcsot, a rekord három mezője pedig az eredményt tárolja. Működik képzési mérföldkövekre, partnerszintekre, eseménylátogatásra vagy bármely állapotváltozásra, amelyet ki tudsz fejezni a Salesforce-ban.
Kezdj egy objektummal és egy jelvénnyel, figyeld egy hétig, és bővítsd, ha az újrapróbálási viselkedés illik az adataidhoz.
Készen állsz az első ellenőrizhető tanúsítványod kibocsátására? Kezdd ingyen a badges.ninja-n — vizuális szerkesztő, nyilvános ellenőrző oldal, PDF tanúsítvány, Open Badge v2.0 kimenet. Bankkártya nélkül.
Hogyan készült ez a cikk
A blog egyes bejegyzéseit AI-asszisztens segítségével írjuk, majd közzététel előtt a Badges Ninja csapata ellenőrzi, tényellenőrzi és szerkeszti. Minden kódrészletet és árat az élő termékkel egyeztetve ellenőrzünk. Szerkesztési és AI-folyamatunkról bővebben olvashat a szerkesztési folyamat oldalunkon .

A szerzőről
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.
Több cikk tőle: Nacho Coll
- Open Badges kibocsátása a Badges Ninja REST API-n keresztül: gyorsindító2026. szept. 28. · 9perc olvasás
- Jelvényellenőrzés beágyazása a weboldaladra (iframe és SDK nélkül)2026. szept. 24. · 9perc olvasás
- Certifier vs Accredible: tanúsítványplatformok összehasonlítása (2026)2026. szept. 21. · 8perc olvasás

