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 Coll Autor Zaktualizowano 8 min czytania
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.

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:

  1. Odznaka zaprojektowana w projektancie wizualnym. Skopiuj jej identyfikator (pole id zwracane przez GET /badges).
  2. Klucz API utworzony na stronie API Keys w twoim panelu. Klucz jest pokazywany tylko raz, więc zapisz go od razu.
  3. Named Credential w Salesforce, który przechowuje klucz, dzięki czemu nigdy nie pojawia się w kodzie.
  4. Wyzwalacz Apex oraz klasa Queueable, które wystawiają nagrodę i zapisują link do niej w rekordzie.

Nowo utworzony klucz API pokazany tylko raz

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.

Lista kluczy API z zamaskowanym prefiksem

Obsługa błędów i ponowienia

API zwraca standardowe kody statusu, a każdy z nich wymaga innej reakcji twojego kodu:

StatusZnaczenieCo zrobić
400Brakujące lub nieprawidłowe pole, w tym nazwa odbiorcy krótsza niż pięć znakówNie ponawiaj. Popraw dane i zapisz komunikat w Badge_Error__c.
401Zły lub brakujący klucz APISprawdź Named Credential. Ponawianie nie pomoże, dopóki tego nie naprawisz.
402Brak poświadczeń lub przekroczony limit twojego planuPrzestań wystawiać i powiadom administratora; ponów po zmianie planu lub po odnowieniu limitu.
404badgeId nie istniejePopraw Badge_Id__c w rekordzie lub kursie.
5xx lub timeoutPrzejściowa awariaMoż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 != null daje 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.

  1. Utwórz testową odznakę i testowego odbiorcę z adresem e-mail, który kontrolujesz.
  2. W testach Apex zaimplementuj HttpCalloutMock zwracają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.
  3. W piaskownicy ustaw jeden zapis na Completed i sprawdź, czy Badge_Award_Id__c oraz Badge_Url__c wypełnią się w ciągu minuty.
  4. Otwórz adres URL w prywatnym oknie przeglądarki, aby potwierdzić, że publiczna strona weryfikacji wyświetla się bez logowania.
  5. 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.

Nacho Coll

O autorze

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.

Powrót do bloga

Powiązane artykuły