Salesforce Open Badges: Verifizierbare Credentials per CRM-Trigger ausstellen

Löse die Ausstellung von Open Badges bei jedem Salesforce-Objektereignis aus — Lead gewonnen, Account upgegradet, Schulungsmeilenstein — mit einem Apex-Callout an die Badges-Ninja-API.

Nacho Coll Von Aktualisiert 9 Min. Lesezeit
Löse die Ausstellung von Open Badges bei jedem Salesforce-Objektereignis aus — Lead gewonnen, Account upgegradet, Schulungsmeilenstein — mit einem Apex-Callout an die Badges-Ninja-API.

Die meisten Schulungsteams erfassen in Salesforce bereits, wer was abgeschlossen hat. Eine Kursanmeldung wechselt auf „Completed“, ein Partner-Account erreicht eine Zertifizierungsstufe, ein Kunde schließt das Onboarding ab. Der Datensatz ändert sich – und eine Woche später exportiert jemand eine Liste und verschickt Zertifikate von Hand per E-Mail.

Dieser Leitfaden zeigt, wie du diese Lücke schließt: Sobald ein Datensatz den gewünschten Status erreicht, ruft Salesforce die https://badges.ninja-API auf, ein Open-Badge-v2.0-Credential wird ausgestellt und der Verifizierungslink wird im Datensatz gespeichert. Diesen Link kannst du anschließend in eine E-Mail-Vorlage, einen Bericht oder eine Experience-Cloud-Seite einbauen.

Du brauchst einen Salesforce-Admin (oder eine Developer-Sandbox), ein bereits auf https://badges.ninja gestaltetes Badge und einen API-Schlüssel. Falls du die API noch nie aufgerufen hast, lies zuerst die API-Schnellstartanleitung; sie dauert zehn Minuten.

Wann ein CRM-Trigger das richtige Werkzeug ist

Prüfe vor dem Schreiben von Apex, ob du es überhaupt brauchst. Wenn du Credentials stapelweise einmal pro Semester oder Quartal ausstellst, ist der CSV-Upload im Dashboard schneller und kommt ganz ohne Code aus. Der Salesforce-Weg lohnt sich, wenn:

  • Die Ausstellung in dem Moment erfolgen soll, in dem sich ein Datensatz ändert – ohne manuellen Schritt.
  • Die Daten darüber, „wer es verdient hat“, bereits in Salesforce liegen und du keine zweite Quelle der Wahrheit willst.
  • Du den Credential-Link für Berichte am Kontakt, am Lead oder am benutzerdefinierten Schulungsdatensatz speichern möchtest.

Wenn dein Workflow-Tool Zapier statt Apex ist, funktioniert derselbe API-Aufruf auch dort; siehe Zapier-Automatisierung für Open Badges.

Was du baust

Der Ablauf besteht aus vier Teilen:

  1. Ein Badge, gestaltet im visuellen Designer. Kopiere seine ID (die id, die GET /badges zurückgibt).
  2. Ein API-Schlüssel, erstellt auf der Seite „API Keys“ deines Dashboards. Der Schlüssel wird nur einmal angezeigt, speichere ihn also sofort.
  3. Ein Named Credential in Salesforce, das den Schlüssel enthält, damit er nie im Code auftaucht.
  4. Ein Apex-Trigger plus eine Queueable-Klasse, die die Auszeichnung ausstellt und den Award-Link in den Datensatz zurückschreibt.

Neu erstellter API-Schlüssel, der nur einmal angezeigt wird

Schritt 1: Den Schlüssel in einem Named Credential speichern

Einen API-Schlüssel fest in Apex zu verdrahten, ist der Fehler, den du vermeiden solltest. Lege in Setup ein External Credential mit einem benutzerdefinierten Header an und danach ein Named Credential, das auf den API-Host zeigt:

  • URL: https://api.badges.ninja
  • Name des benutzerdefinierten Headers: X-Api-Key
  • Wert des benutzerdefinierten Headers: dein Schlüssel in der Form bws_YOUR_KEY_HERE
  • Name des Named Credential: BadgesNinja

Gib dem Permission Set, das deine Automatisierung ausführt, Zugriff auf den Principal des External Credential. Mit einem Named Credential brauchst du keine separate Remote Site Setting; Salesforce autorisiert den Callout über das Credential. Wenn deine Org noch Legacy-Named-Credentials oder einen einfachen Endpoint verwendet, füge https://api.badges.ninja als Remote Site Setting hinzu und sende den Header aus dem Code.

Schritt 2: Felder am Datensatz ergänzen

Ergänze am Objekt, das die Leistung repräsentiert (wir verwenden ein benutzerdefiniertes Objekt namens Training_Enrollment__c), Folgendes:

  • Badge_Id__c (Text): das auszustellende Badge. Wenn du es pro Kurs speicherst, bedient ein Trigger viele Badges.
  • Badge_Award_Id__c (Text, eindeutig): die von der API zurückgegebene Award-ID.
  • Badge_Url__c (URL): die öffentliche Verifizierungsseite.
  • Badge_Error__c (Langtext): der letzte Fehler, damit Admins Fehlschläge sehen, ohne Debug-Logs zu öffnen.

Das Feld Badge_Award_Id__c erfüllt einen doppelten Zweck. Es ist dein Schutz vor Duplikaten: Der Trigger stellt nur aus, wenn es leer ist.

Schritt 3: Der Apex-Callout

Ein Trigger kann nicht direkt einen Callout ausführen, da Callouts in derselben Transaktion wie nicht committetes DML nicht erlaubt sind. Übergib die Arbeit an einen Queueable, der Database.AllowsCallouts implementiert.

Der API-Vertrag für POST /awards ist kurz. Der Body enthält badgeId, ein verschachteltes recipient-Objekt mit name und email sowie ein Pflichtfeld issuedOn. Ein erfolgreicher Aufruf liefert HTTP 200 mit { "awardId": "..." }. Der Name des Empfängers muss mindestens fünf Zeichen lang sein, ein Kontakt namens „Al Li“ würde also abgelehnt; validiere deshalb vor dem Aufruf.

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;
    }
}

Zwei Details sind erwähnenswert. Erstens ist issuedOn in Epoch-Millisekunden angegeben, genau das, was Datetime.getTime() zurückgibt. Zweitens enthält die Antwort nicht die Verifizierungs-URL, deshalb baut der Code sie aus der Award-ID zusammen: https://badges.ninja/awards/<awardId>.

Schritt 4: Der Trigger

Halte den Trigger schlank. Er entscheidet nur, welche Datensätze qualifiziert sind, und stellt pro Datensatz einen Job in die Queue.

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));
        }
    }
}

Die Prüfung wasCompleted ist wichtig. Ohne sie würde jede spätere Änderung an einem abgeschlossenen Datensatz die Logik erneut auslösen. Zusammen mit dem Schutz über die leere Award-ID im Job kann ein Datensatz immer nur ein einziges Credential erzeugen.

Ein Limit solltest du beachten: Salesforce erlaubt nur wenige Queueable-Jobs pro Transaktion (50 im synchronen Kontext). Wenn du Abschlüsse in großen Mengen lädst, etwa bei einem Datenimport mit 2.000 Zeilen, stößt der obige Trigger an diese Grenze. Für Massenladungen lädst du die Liste entweder stattdessen über den CSV-Massenupload des Dashboards hoch oder wechselst auf eine Batchable-Klasse mit Database.AllowsCallouts, die pro Scope nur wenige Datensätze verarbeitet.

Liste der API-Schlüssel mit maskiertem Präfix

Fehlerbehandlung und Wiederholungen

Die API liefert Standard-Statuscodes, und jeder verlangt eine andere Reaktion deines Codes:

StatusBedeutungWas zu tun ist
400Ein Feld fehlte oder war ungültig, auch ein Empfängername unter fünf ZeichenNicht wiederholen. Daten korrigieren und die Meldung in Badge_Error__c schreiben.
401Falscher oder fehlender API-SchlüsselDas Named Credential prüfen. Wiederholen hilft nicht, bevor es korrigiert ist.
402Keine Credentials oder Kontingent im Tarif mehrAusstellung stoppen und einen Admin alarmieren; nach dem Upgrade oder dem Zurücksetzen des Kontingents erneut versuchen.
404Die badgeId existiert nichtBadge_Id__c am Datensatz oder Kurs korrigieren.
5xx oder TimeoutVorübergehender FehlerKann später gefahrlos wiederholt werden.

Da der Job den Fehler in den Datensatz schreibt und Badge_Award_Id__c leer lässt, genügt für eine Wiederholung das Umschalten einer Checkbox oder ein erneutes Speichern des Datensatzes. Eine kleine geplante Apex-Klasse, die abgeschlossene Anmeldungen ohne Award-ID und mit einem vorübergehenden Fehler sucht und erneut in die Queue stellt, liefert dir eine automatische Retry-Queue ohne zusätzliche Infrastruktur. Begrenze die Versuche mit einem Zählerfeld, damit ein dauerhaft fehlerhafter Datensatz nicht endlos läuft.

Prüfe deinen Tarif, bevor du das in Produktion anbindest. Der Free-Tarif umfasst 1.200 Credentials pro Jahr; Starter kostet $9 pro Monat und Pro $29 pro Monat. Ein Trigger, der bei jedem Lead feuert, würde einen kleinen Tarif schnell aufbrauchen – beschränke die Kriterien daher auf echte Leistungen.

Das Credential in Salesforce sichtbar machen

Sobald Badge_Url__c gefüllt ist, kannst du es überall nutzen:

  • E-Mail-Benachrichtigungen und Vorlagen: Füge das Feld in eine E-Mail „Glückwunsch, hier ist dein Credential“ ein.
  • Berichte: Ein Bericht auf Badge_Award_Id__c != null liefert dir Ausstellungszahlen nach Kurs, Region oder Account-Inhaber.
  • Experience Cloud: Zeige den Link auf der Zertifizierungsseite eines Partners, damit Käufer ihn selbst verifizieren können.
  • Seitenlayouts: Füge das URL-Feld hinzu, damit der Support die Frage „Hat sie ihr Badge bekommen?“ auf einen Blick beantworten kann.

Die Verifizierungsseite ist öffentlich und erfordert keine Anmeldung – genau darum geht es. Ein Empfänger, eine Personalverantwortliche oder das Beschaffungsteam eines Kunden kann den Link öffnen und bestätigen, wer das Credential ausgestellt hat, was es bescheinigt und wann. Für maschinenlesbare Prüfungen steht das Open-Badge-v2.0-JSON-LD jeder Auszeichnung unter https://api.badges.ninja/certify-badge/award/<awardId> bereit.

Empfänger erhalten außerdem die üblichen Extras: eine eindeutige Verifizierungs-URL, einen QR-Code, ein PDF-Zertifikat im A4-Format und eine „Zu LinkedIn hinzufügen“-Option im Empfängerportal, in dem man sich per Magic Link statt mit einem Passwort anmeldet.

Warum das besser ist als ein Badge-Plugin aus dem AppExchange

Badge-Plugins im AppExchange werden meist pro Salesforce-Lizenz oder pro Managed-Package-Lizenz berechnet. Diese Kosten wachsen mit der Größe deines Salesforce-Teams, nicht mit der Anzahl der ausgestellten Credentials – ein zehnköpfiges Schulungsteam und ein Programm mit zehntausend Lernenden zahlen also für dasselbe Ergebnis sehr unterschiedlich.

Eine API-Integration kehrt dieses Modell um. Du zahlst nach Credential-Volumen in einem Pauschaltarif, der Trigger-Code gehört dir und lässt sich lesen und ändern, und das Ergebnis ist Standard-Open-Badge-v2.0, sodass Empfänger nicht an einen proprietären Viewer gebunden sind. Auch gestalterisch bleibst du frei: Der visuelle Designer bietet 80+ Vorlagen, Formen, Icons und eigene Uploads statt eines festen Layouts innerhalb eines Pakets.

Der ehrliche Kompromiss: Ein Plugin ist per Klick installiert und braucht kein Apex. Wenn niemand in deinem Team ein paar Dutzend Zeilen Code pflegen kann, passt ein Plugin oder ein No-Code-Connector womöglich besser. Wenn du Plattformen allgemein statt Integrationen vergleichst, findest du in der Credly-Alternative einen direkten Vergleich von Preisen und Funktionen.

Testen vor dem Livegang

Spiele den gesamten Ablauf zuerst in einer Sandbox durch.

  1. Erstelle ein Test-Badge und einen Test-Empfänger mit einer E-Mail-Adresse, auf die du Zugriff hast.
  2. Implementiere in den Apex-Tests einen HttpCalloutMock, der Status 200 und {"awardId":"test-award-id"} zurückgibt; Salesforce erlaubt im Testkontext keine echten Callouts, und du brauchst diese Abdeckung für das Deployment.
  3. Setze in der Sandbox eine Anmeldung auf Completed und prüfe, dass sich Badge_Award_Id__c und Badge_Url__c innerhalb einer Minute füllen.
  4. Öffne die URL in einem privaten Browserfenster, um zu bestätigen, dass die öffentliche Verifizierungsseite ohne Anmeldung angezeigt wird.
  5. Erzwinge einen Fehler (lösche die Badge-ID oder nimm einen Empfängernamen unter fünf Zeichen) und prüfe, dass der Fehler in Badge_Error__c landet.

Rotiere den API-Schlüssel, falls er je in einem Debug-Log oder Screenshot auftaucht. Das Widerrufen wirkt sofort über die Seite „API Keys“, und du musst nur das External Credential aktualisieren, nicht deinen Code.

Zusammenfassung

Das Muster ist klein: Ein schlanker Trigger entscheidet, wann; ein Queueable führt den Callout aus; ein Named Credential hält den Schlüssel; und drei Felder am Datensatz speichern das Ergebnis. Es funktioniert für Schulungsmeilensteine, Partnerstufen, Veranstaltungsteilnahme oder jede Zustandsänderung, die sich in Salesforce ausdrücken lässt.

Beginne mit einem Objekt und einem Badge, beobachte es eine Woche lang und erweitere, sobald das Wiederholungsverhalten zu deinen Daten passt.

Bereit, dein erstes verifizierbares Credential auszustellen? Kostenlos starten auf badges.ninja — visueller Designer, öffentliche Verifizierungsseite, PDF-Zertifikat, Open-Badge-v2.0-Ausgabe. Keine Kreditkarte erforderlich.

Nacho Coll

Über den Autor

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.

Zurück zum Blog

Verwandte Artikel