Salesforce Open Badges: Utsted verifiserbare credentials fra CRM-triggere

Utløs utstedelse av Open Badge fra enhver hendelse på et Salesforce-objekt — Lead vunnet, Account oppgradert, opplæringsmilepæl — med et Apex-callout til Badges Ninja-API-et.

Nacho Coll Av Oppdatert 9 min lesing
Utløs utstedelse av Open Badge fra enhver hendelse på et Salesforce-objekt — Lead vunnet, Account oppgradert, opplæringsmilepæl — med et Apex-callout til Badges Ninja-API-et.

De fleste opplæringsteam registrerer allerede i Salesforce hvem som har fullført hva. En kurspåmelding settes til “Completed”, en partnerkonto når et sertifiseringsnivå, en kunde blir ferdig med onboarding. Posten endres, og så eksporterer noen en liste og sender sertifikater for hånd en uke senere.

Denne guiden viser hvordan du tetter det gapet: Når en post når statusen du bryr deg om, kaller Salesforce https://badges.ninja-API-et, det utstedes en Open Badge v2.0-credential, og verifiseringslenken lagres tilbake på posten. Deretter kan du sette lenken inn i en e-postmal, en rapport eller en Experience Cloud-side.

Du trenger en Salesforce-administrator (eller en developer sandbox), et badge som allerede er designet på https://badges.ninja, og en API-nøkkel. Hvis du aldri har kalt API-et før, les API-quickstart først. Det tar ti minutter.

Når en CRM-trigger er riktig verktøy

Før du skriver Apex, sjekk om du trenger det. Hvis du utsteder credentials i batcher én gang per semester eller kvartal, er CSV-opplastingen i dashbordet raskere og krever ingen kode i det hele tatt. Salesforce-løsningen lønner seg når:

  • Utstedelsen skal skje i det øyeblikket en post endres, uten noe menneskelig trinn.
  • Dataene om hvem som har oppnådd det allerede ligger i Salesforce, og du ikke vil ha en ekstra sannhetskilde.
  • Du vil ha credential-lenken lagret på Contact, Lead eller en egendefinert opplæringspost for rapportering.

Hvis arbeidsflytverktøyet ditt er Zapier i stedet for Apex, fungerer det samme API-kallet der også; se Zapier Open Badges-automatisering.

Hva du bygger

Flyten har fire deler:

  1. Et badge designet i det visuelle designverktøyet. Kopier id-en (id som GET /badges returnerer).
  2. En API-nøkkel opprettet på siden API Keys i dashbordet ditt. Nøkkelen vises bare én gang, så lagre den med en gang.
  3. En Named Credential i Salesforce som holder nøkkelen, slik at den aldri dukker opp i koden.
  4. En Apex-trigger pluss en Queueable-klasse som utsteder tildelingen og skriver tildelingslenken tilbake til posten.

Newly created API key revealed once

Trinn 1: Lagre nøkkelen i en Named Credential

Å hardkode en API-nøkkel i Apex er feilen du bør unngå. Opprett i Setup en External Credential med en egendefinert header, og deretter en Named Credential som peker på API-verten:

  • URL: https://api.badges.ninja
  • Custom header name: X-Api-Key
  • Custom header value: nøkkelen din, på formen bws_YOUR_KEY_HERE
  • Named Credential name: BadgesNinja

Gi permission set-et som kjører automatiseringen din tilgang til principalen i External Credential. Med en Named Credential på plass trenger du ingen egen Remote Site Setting; Salesforce autoriserer calloutet gjennom credentialen. Hvis orgen din fortsatt bruker eldre Named Credentials eller et vanlig endepunkt, legg til https://api.badges.ninja som Remote Site Setting og send headeren fra koden i stedet.

Trinn 2: Legg til felt på posten

På objektet som representerer prestasjonen (vi bruker et egendefinert objekt kalt Training_Enrollment__c) legger du til:

  • Badge_Id__c (Text): badget som skal utstedes. Når du lagrer det per kurs, kan én trigger betjene mange badger.
  • Badge_Award_Id__c (Text, unique): tildelings-id-en som API-et returnerer.
  • Badge_Url__c (URL): den offentlige verifiseringssiden.
  • Badge_Error__c (Long Text): den siste feilen, slik at administratorer kan se feil uten å åpne debug-logger.

Feltet Badge_Award_Id__c har en dobbel funksjon. Det er vernet ditt mot duplikater: Triggeren utsteder bare når det er tomt.

Trinn 3: Apex-calloutet

En trigger kan ikke gjøre et callout direkte, fordi callouts ikke er tillatt i samme transaksjon som ikke-committet DML. Overlat jobben til en Queueable som implementerer Database.AllowsCallouts.

API-kontrakten for POST /awards er kort. Body inneholder badgeId, et nøstet recipient-objekt med name og email, og et obligatorisk issuedOn. Et vellykket kall returnerer HTTP 200 med { "awardId": "..." }. Mottakerens navn må være minst fem tegn, så en Contact som heter “Al Li” ville bli avvist; valider før du kaller.

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 verdt å legge merke til. For det første er issuedOn epoch-millisekunder, som er nøyaktig det Datetime.getTime() returnerer. For det andre inneholder ikke svaret verifiserings-URL-en, så koden bygger den fra tildelings-id-en: https://badges.ninja/awards/<awardId>.

Trinn 4: Triggeren

Hold triggeren tynn. Den avgjør bare hvilke poster som kvalifiserer, og setter én jobb i kø per 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));
        }
    }
}

Sjekken wasCompleted er viktig. Uten den ville enhver senere redigering av en fullført post utløse logikken på nytt. Sammen med vernet mot tom tildelings-id inne i jobben kan en post bare noensinne gi én credential.

Én grense må du respektere: Salesforce tillater et lite antall Queueable-jobber i kø fra én enkelt transaksjon (50 i synkron kontekst). Hvis du laster inn fullføringer i bulk, for eksempel en dataimport på 2 000 rader, vil triggeren over treffe taket. Ved bulkinnlasting kan du enten laste opp listen via CSV-bulktildelinger i dashbordet i stedet, eller bytte til en Batchable-klasse med Database.AllowsCallouts som behandler noen få poster per scope.

API keys list showing the masked prefix

Feilhåndtering og nye forsøk

API-et returnerer standard statuskoder, og hver av dem krever sitt svar fra koden din:

StatusBetydningHva du bør gjøre
400Et felt manglet eller var ugyldig, inkludert et mottakernavn under fem tegnIkke prøv på nytt. Rett dataene og skriv meldingen til Badge_Error__c.
401Feil eller manglende API-nøkkelSjekk Named Credential. Nye forsøk hjelper ikke før den er rettet.
402Tom for credentials eller kvote for planen dinStopp utstedelsen og varsle en administrator; prøv på nytt etter oppgradering eller når kvoten nullstilles.
404badgeId finnes ikkeRett Badge_Id__c på posten eller kurset.
5xx eller timeoutMidlertidig feilTrygt å prøve på nytt senere.

Fordi jobben skriver feilen til posten og lar Badge_Award_Id__c stå tomt, er et nytt forsøk like enkelt som å slå av og på en avkrysningsboks eller lagre posten på nytt. En liten planlagt Apex-klasse som leter etter fullførte påmeldinger uten tildelings-id og med en midlertidig feil, og deretter setter dem i kø igjen, gir deg en automatisk køordning for nye forsøk uten ekstra infrastruktur. Begrens antall forsøk med et tellerfelt, slik at en permanent dårlig post ikke går i løkke for alltid.

Sjekk planen din før du kobler dette til produksjon. Free-planen dekker 1 200 credentials i året; Starter koster $9 i måneden og Pro $29 i måneden. En trigger som utløses på hver Lead ville raskt spist opp en liten plan, så avgrens kriteriene til reelle prestasjoner.

Gjør credentialen synlig i Salesforce

Når Badge_Url__c er fylt ut, kan du bruke den overalt:

  • E-postvarsler og maler: flett feltet inn i en e-post med «Gratulerer, her er credentialen din».
  • Rapporter: en rapport på Badge_Award_Id__c != null gir deg antall utstedelser per kurs, region eller kontoeier.
  • Experience Cloud: vis lenken på en partners sertifiseringsside, slik at kjøpere kan verifisere den selv.
  • Page layouts: legg til URL-feltet slik at supportmedarbeidere kan svare på «fikk hun badget sitt?» med et enkelt blikk.

Verifiseringssiden er offentlig og krever ingen registrering, og det er hele poenget. En mottaker, en rekrutterer eller innkjøpsavdelingen til en kunde kan åpne lenken og bekrefte hvem som utstedte credentialen, hva den sertifiserer og når. For maskinlesbare sjekker finnes Open Badge v2.0 JSON-LD for enhver tildeling på https://api.badges.ninja/certify-badge/award/<awardId>.

Mottakere får også de vanlige tilleggene: en unik verifiserings-URL, en QR-kode, et A4-PDF-sertifikat og et Add to LinkedIn-alternativ fra mottakerportalen, som logger inn med en magic link i stedet for et passord.

Hvorfor dette slår en AppExchange-badgeplugin

Badgepluginer på AppExchange er som regel priset per Salesforce-bruker eller per lisens for managed package. Den kostnaden skalerer med størrelsen på Salesforce-teamet ditt, ikke med antall credentials du utsteder, så et opplæringsteam på ti personer og et program med ti tusen kursdeltakere betaler vidt forskjellig for det samme resultatet.

En API-integrasjon snur den modellen. Du betaler etter credential-volum på en fast plan, triggerkoden er din å lese og endre, og resultatet er standard Open Badge v2.0, så mottakerne ikke er låst til en proprietær viewer. Du beholder også designfriheten: Det visuelle designverktøyet tilbyr 80+ maler, former, ikoner og egne opplastinger, i stedet for en fast layout inne i en pakke.

Den ærlige avveiningen: En plugin installeres med ett klikk og krever ingen Apex. Hvis ingen på teamet ditt kan vedlikeholde noen titalls linjer kode, kan en plugin eller en no-code-connector passe bedre. Hvis du sammenligner plattformer generelt i stedet for integrasjoner, dekker gjennomgangen Credly-alternativ priser og funksjonsforskjeller side om side.

Test før du går live

Kjør hele flyten i en sandbox først.

  1. Opprett et testbadge og en testmottaker med en e-postadresse du kontrollerer.
  2. Implementer i Apex-tester en HttpCalloutMock som returnerer status 200 og {"awardId":"test-award-id"}; Salesforce tillater ikke ekte callouts i testkontekst, og du trenger den dekningen for å deploye.
  3. Sett én påmelding til Completed i sandboxen, og sjekk at Badge_Award_Id__c og Badge_Url__c fylles ut i løpet av et minutt.
  4. Åpne URL-en i et privat nettleservindu for å bekrefte at den offentlige verifiseringssiden vises uten innlogging.
  5. Fremprovoser en feil (tøm badge-id-en, eller bruk et mottakernavn under fem tegn) og bekreft at feilen havner i Badge_Error__c.

Roter API-nøkkelen hvis den noen gang lekker inn i en debug-logg eller et skjermbilde. Tilbakekalling skjer umiddelbart fra siden API Keys, og du trenger bare å oppdatere External Credential, ikke koden din.

Oppsummering

Mønsteret er lite: En tynn trigger avgjør når, en Queueable gjør calloutet, en Named Credential holder nøkkelen, og tre felt på posten lagrer utfallet. Det fungerer for opplæringsmilepæler, partnernivåer, arrangementsdeltakelse eller enhver tilstandsendring du kan uttrykke i Salesforce.

Start med ett objekt og ett badge, følg med i en uke, og utvid når oppførselen ved nye forsøk passer dataene dine.

Klar til å utstede din første verifiserbare credential? Kom i gang gratis på badges.ninja — visuelt designverktøy, offentlig verifiseringsside, PDF-sertifikat, Open Badge v2.0-utdata. Ingen kredittkort nødvendig.

Nacho Coll

Om forfatteren

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.

Tilbake til bloggen

Relaterte artikler