Salesforce Open Badges: wystawianie weryfikowalnych poświadczeń z wyzwalaczy CRM
Uruchamiaj wystawianie Open Badge przy dowolnym zdarzeniu obiektu Salesforce — wygrany Lead, awans Account, kamień milowy szkolenia — za pomocą wywołania Apex do 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.
Większość zespołów szkoleniowych już zapisuje w Salesforce, kto co ukończył. Zapis na kurs zmienia status na „Completed”, konto partnera osiąga poziom certyfikacji, klient kończy onboarding. Rekord się zmienia, a tydzień później ktoś eksportuje listę i ręcznie wysyła certyfikaty e-mailem.
Ten przewodnik pokazuje, jak zamknąć tę lukę: gdy rekord osiąga interesujący cię status, Salesforce wywołuje API https://badges.ninja, wystawiane jest poświadczenie Open Badge v2.0, a link weryfikacyjny trafia z powrotem do rekordu. Możesz potem wstawić ten link do szablonu e-maila, raportu albo strony Experience Cloud.
Potrzebujesz administratora Salesforce (lub piaskownicy deweloperskiej), odznaki zaprojektowanej już na https://badges.ninja oraz klucza API. Jeśli nigdy wcześniej nie wywoływałeś tego API, przeczytaj najpierw krótki start z API; zajmie ci to dziesięć minut.
Kiedy wyzwalacz CRM to właściwe narzędzie
Zanim napiszesz Apex, sprawdź, czy w ogóle go potrzebujesz. Jeśli wystawiasz poświadczenia partiami raz na semestr albo raz na kwartał, szybsze będzie wgranie pliku CSV w panelu, bez żadnego kodu. Droga przez Salesforce się opłaca, gdy:
- Wystawienie ma nastąpić w chwili zmiany rekordu, bez udziału człowieka.
- Dane o tym, „kto to zdobył”, już są w Salesforce i nie chcesz drugiego źródła prawdy.
- Chcesz przechowywać link do poświadczenia w rekordzie Contact, Lead lub własnym rekordzie szkoleniowym na potrzeby raportowania.
Jeśli twoim narzędziem jest Zapier, a nie Apex, to samo wywołanie API zadziała także tam; zobacz automatyzację Open Badges w Zapierze.
Co budujesz
Przepływ składa się z czterech elementów:
- Odznaka zaprojektowana w projektancie wizualnym. Skopiuj jej identyfikator (pole
idzwracane przezGET /badges). - Klucz API utworzony na stronie API Keys w twoim panelu. Klucz jest pokazywany tylko raz, więc zapisz go od razu.
- Named Credential w Salesforce, który przechowuje klucz, dzięki czemu nigdy nie pojawia się w kodzie.
- Wyzwalacz Apex oraz klasa Queueable, które wystawiają nagrodę i zapisują link do niej w rekordzie.

Krok 1: Zapisz klucz w Named Credential
Wpisanie klucza API na stałe w Apex to błąd, którego należy unikać. W Setup utwórz External Credential z własnym nagłówkiem, a następnie Named Credential wskazujący na host API:
- URL:
https://api.badges.ninja - Nazwa własnego nagłówka:
X-Api-Key - Wartość własnego nagłówka: twój klucz w postaci
bws_YOUR_KEY_HERE - Nazwa Named Credential:
BadgesNinja
Nadaj zestawowi uprawnień, który uruchamia twoją automatyzację, dostęp do principala External Credential. Gdy Named Credential jest na miejscu, nie potrzebujesz osobnego Remote Site Setting; Salesforce autoryzuje wywołanie przez to poświadczenie. Jeśli twoja organizacja nadal używa starszych Named Credentials albo zwykłego endpointu, dodaj https://api.badges.ninja jako Remote Site Setting i wysyłaj nagłówek z kodu.
Krok 2: Dodaj pola do rekordu
W obiekcie reprezentującym osiągnięcie (użyjemy własnego obiektu Training_Enrollment__c) dodaj:
Badge_Id__c(Text): odznaka do wystawienia. Zapisanie jej przy każdym kursie pozwala jednemu wyzwalaczowi obsługiwać wiele odznak.Badge_Award_Id__c(Text, unique): identyfikator nagrody zwrócony przez API.Badge_Url__c(URL): publiczna strona weryfikacji.Badge_Error__c(Long Text): ostatni błąd, aby administratorzy widzieli awarie bez otwierania logów debugowania.
Pole Badge_Award_Id__c pełni podwójną rolę. To twoja ochrona przed duplikatami: wyzwalacz wystawia poświadczenie tylko wtedy, gdy jest ono puste.
Krok 3: Wywołanie Apex
Wyzwalacz nie może wykonać wywołania bezpośrednio, ponieważ wywołania zewnętrzne nie są dozwolone w tej samej transakcji co niezatwierdzony DML. Przekaż pracę klasie Queueable implementującej Database.AllowsCallouts.
Kontrakt API dla POST /awards jest krótki. Treść zawiera badgeId, zagnieżdżony obiekt recipient z polami name i email oraz wymagane issuedOn. Udane wywołanie zwraca HTTP 200 z { "awardId": "..." }. Nazwa odbiorcy musi mieć co najmniej pięć znaków, więc Contact o imieniu „Al Li” zostałby odrzucony; zwaliduj dane przed wywołaniem.
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;
}
}
Warto zwrócić uwagę na dwa szczegóły. Po pierwsze, issuedOn to epoch w milisekundach, czyli dokładnie to, co zwraca Datetime.getTime(). Po drugie, odpowiedź nie zawiera adresu URL weryfikacji, więc kod buduje go z identyfikatora nagrody: https://badges.ninja/awards/<awardId>.
Krok 4: Wyzwalacz
Niech wyzwalacz będzie cienki. Decyduje tylko, które rekordy się kwalifikują, i kolejkuje jedno zadanie na rekord.
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));
}
}
}
Warunek wasCompleted ma znaczenie. Bez niego każda późniejsza edycja ukończonego rekordu ponownie uruchomiłaby logikę. W połączeniu ze strażnikiem pustego identyfikatora nagrody wewnątrz zadania rekord może wytworzyć tylko jedno poświadczenie.
Jeden limit trzeba respektować: Salesforce pozwala zakolejkować z jednej transakcji niewielką liczbę zadań Queueable (50 w kontekście synchronicznym). Jeśli ładujesz ukończenia zbiorczo, powiedzmy importem 2000 wierszy, powyższy wyzwalacz uderzy w ten pułap. Przy ładowaniu zbiorczym wgraj listę przez zbiorcze nagrody CSV w panelu albo przełącz się na klasę Batchable z Database.AllowsCallouts, która przetwarza kilka rekordów na zakres.

Obsługa błędów i ponowienia
API zwraca standardowe kody statusu, a każdy z nich wymaga innej reakcji twojego kodu:
| Status | Znaczenie | Co zrobić |
|---|---|---|
| 400 | Brakujące lub nieprawidłowe pole, w tym nazwa odbiorcy krótsza niż pięć znaków | Nie ponawiaj. Popraw dane i zapisz komunikat w Badge_Error__c. |
| 401 | Zły lub brakujący klucz API | Sprawdź Named Credential. Ponawianie nie pomoże, dopóki tego nie naprawisz. |
| 402 | Brak poświadczeń lub przekroczony limit twojego planu | Przestań wystawiać i powiadom administratora; ponów po zmianie planu lub po odnowieniu limitu. |
| 404 | badgeId nie istnieje | Popraw Badge_Id__c w rekordzie lub kursie. |
| 5xx lub timeout | Przejściowa awaria | Można bezpiecznie ponowić później. |
Ponieważ zadanie zapisuje błąd w rekordzie i zostawia Badge_Award_Id__c puste, ponowienie to kwestia przestawienia pola wyboru albo ponownego zapisania rekordu. Mała zaplanowana klasa Apex, która szuka ukończonych zapisów bez identyfikatora nagrody i z błędem przejściowym, a potem ponownie je kolejkuje, daje automatyczną kolejkę ponowień bez dodatkowej infrastruktury. Ogranicz liczbę prób polem licznika, aby na stałe wadliwy rekord nie zapętlał się w nieskończoność.
Sprawdź swój plan, zanim podłączysz to do produkcji. Plan Free obejmuje 1200 poświadczeń rocznie; Starter kosztuje $9 miesięcznie, a Pro $29 miesięcznie. Wyzwalacz uruchamiany na każdym Lead szybko wyczerpałby mały plan, więc ogranicz kryteria do prawdziwych osiągnięć.
Jak uwidocznić poświadczenie w Salesforce
Gdy Badge_Url__c jest wypełnione, możesz użyć go wszędzie:
- Alerty e-mail i szablony: wstaw pole do e-maila „Gratulacje, oto twoje poświadczenie”.
- Raporty: raport z warunkiem
Badge_Award_Id__c != nulldaje liczbę wystawień według kursu, regionu lub właściciela konta. - Experience Cloud: pokaż link na stronie certyfikacji partnera, aby kupujący mogli sami go zweryfikować.
- Układy stron: dodaj pole URL, aby pracownicy wsparcia mogli odpowiedzieć na pytanie „czy dostała swoją odznakę?” jednym spojrzeniem.
Strona weryfikacji jest publiczna i nie wymaga rejestracji, i o to właśnie chodzi. Odbiorca, rekruter albo dział zakupów klienta może otworzyć link i potwierdzić, kto wystawił poświadczenie, co ono poświadcza i kiedy. Do kontroli maszynowych JSON-LD Open Badge v2.0 dla każdej nagrody jest dostępny pod adresem https://api.badges.ninja/certify-badge/award/<awardId>.
Odbiorcy dostają też zwykłe dodatki: unikalny adres URL weryfikacji, kod QR, certyfikat PDF w formacie A4 oraz opcję Add to LinkedIn z portalu odbiorcy, który loguje się linkiem magicznym zamiast hasła.
Dlaczego to lepsze niż wtyczka z odznakami z AppExchange
Wtyczki z odznakami na AppExchange są zwykle wyceniane za stanowisko Salesforce albo za licencję pakietu zarządzanego. Ten koszt rośnie wraz z wielkością zespołu Salesforce, a nie liczbą wystawianych poświadczeń, więc dziesięcioosobowy zespół szkoleniowy i program dla dziesięciu tysięcy uczących się płacą za ten sam wynik zupełnie inaczej.
Integracja przez API odwraca ten model. Płacisz według wolumenu poświadczeń w stałym planie, kod wyzwalacza możesz czytać i zmieniać, a wynik to standardowy Open Badge v2.0, więc odbiorcy nie są uwiązani do własnościowej przeglądarki. Zachowujesz też swobodę projektowania: projektant wizualny oferuje ponad 80 szablonów, kształty, ikony i własne uploady, zamiast stałego układu wewnątrz pakietu.
Uczciwy kompromis: wtyczkę instaluje się jednym kliknięciem i nie wymaga Apex. Jeśli nikt w twoim zespole nie utrzyma kilkudziesięciu linii kodu, lepszym wyborem może być wtyczka lub konektor no-code. Jeśli porównujesz platformy ogólnie, a nie integracje, zestawienie alternatywy dla Credly omawia różnice w cenach i funkcjach obok siebie.
Testowanie przed uruchomieniem
Najpierw uruchom cały przepływ w piaskownicy.
- Utwórz testową odznakę i testowego odbiorcę z adresem e-mail, który kontrolujesz.
- W testach Apex zaimplementuj
HttpCalloutMockzwracający status 200 i{"awardId":"test-award-id"}; Salesforce nie zezwala na prawdziwe wywołania w kontekście testowym, a to pokrycie jest potrzebne do wdrożenia. - W piaskownicy ustaw jeden zapis na Completed i sprawdź, czy
Badge_Award_Id__corazBadge_Url__cwypełnią się w ciągu minuty. - Otwórz adres URL w prywatnym oknie przeglądarki, aby potwierdzić, że publiczna strona weryfikacji wyświetla się bez logowania.
- Wymuś błąd (wyczyść identyfikator odznaki albo użyj nazwy odbiorcy krótszej niż pięć znaków) i potwierdź, że błąd trafia do
Badge_Error__c.
Zrotuj klucz API, jeśli kiedykolwiek wycieknie do logu debugowania lub zrzutu ekranu. Unieważnienie jest natychmiastowe na stronie API Keys, a zaktualizować trzeba tylko External Credential, nie kod.
Podsumowanie
Wzorzec jest mały: cienki wyzwalacz decyduje kiedy, Queueable wykonuje wywołanie, Named Credential przechowuje klucz, a trzy pola w rekordzie zapisują wynik. Sprawdza się przy kamieniach milowych szkoleń, poziomach partnerów, obecności na wydarzeniach i każdej zmianie stanu, którą da się wyrazić w Salesforce.
Zacznij od jednego obiektu i jednej odznaki, obserwuj ją przez tydzień i rozszerzaj, gdy zachowanie ponowień będzie pasować do twoich danych.
Gotowy, by wystawić pierwsze weryfikowalne poświadczenie? Zacznij za darmo na badges.ninja — projektant wizualny, publiczna strona weryfikacji, certyfikat PDF, wyjście Open Badge v2.0. Karta kredytowa nie jest wymagana.
Jak powstał ten artykuł
Niektóre wpisy na tym blogu powstają z pomocą asystenta AI, a następnie są sprawdzane, weryfikowane merytorycznie i redagowane przez zespół Badges Ninja przed publikacją. Każdy przykład kodu i cena są weryfikowane względem działającego produktu. Więcej o naszym procesie redakcyjnym i wykorzystaniu AI przeczytasz na naszej stronie procesu redakcyjnego .

O autorze
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.

