function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Thiago Barbosa 10Thiago Barbosa 10 

Is there some Trailhead API?

The Endpoint return only html. I want to restore points, badges and trails in Trailhead, but after change web site trailhead, it is no longer possible.

public class RESTGetHttpContentCallout {
    private static final String htmlBadgesClass = 'tds-tally__count tds-tally__count_success">';
    private static final String htmlPointsClass = 'tds-tally__count tds-tally__count_success">'; 
    private static final String htmlTrailsClass = 'tds-tally__count tds-tally__count_success">';
    private static final String htmlBadgesJson = '<div data-react-class="BadgesPanel" data-react-props="';
    private static final string JsonFinalChar = '">';
    private static integer modulos = 0, superbadges = 0, eventos = 0, projetos = 0;


    public static Map<String, String> getCalloutResponseContents(String url){
        HttpResponse res = new HttpResponse();
        try{
            Http h = new Http();
            HttpRequest req = new HttpRequest();
            req.setEndpoint('https://trailblazer.me/id/+ profilenameorId);
            req.setMethod('GET'); 
            req.setHeader('Content-Type', 'application/json');
            System.debug('req' + req);
            res = h.send(req);
            System.debug('THBS ---- res' + res);
        }catch(Exception e){
            System.debug('An exception occurred: ' + e.getMessage());
        }
        String lBody = res.getBody(); 

        System.debug('THBS ---- res.getBody();' + res.getBody());
        String lContactBadges = getValue( htmlBadgesClass, lBody );
        String lContactPoints = getValue( htmlPointsClass, lBody );
        String lContactTrails = getValue( htmlTrailsClass, lBody );
        String lJsonBadges = getJsonValue( htmlBadgesJson, JsonFinalChar, lBody);
        system.debug('--->> ' + lContactBadges);
        system.debug('THBS ---- lContactPoints' + lContactPoints);
        System.debug('THBS ---- lContactTrails' + lContactTrails);
        Map<String,String> lMapToReturn = new Map<String,String>();
        lMapToReturn.put('Badges', lContactBadges); 
        lMapToReturn.put('Pontos', lContactPoints);
        lMapToReturn.put('Trails', lContactTrails);
        lMapToReturn.put('Modulos', string.valueOf(modulos));
        lMapToReturn.put('Superbadges', string.valueOf(superbadges));
        lMapToReturn.put('Projetos', string.valueOf(projetos));
        lMapToReturn.put('Eventos', string.valueOf(eventos));
        system.debug('THBS ---- lMapToReturn' + JSON.serialize(lMapToReturn));
        return lMapToReturn;
    }

    private static String getJsonValue(string aClass, string finalChar, string aBody){
        Integer lInit = getInitialLocationByAttributeClass(aClass, aBody);
        Integer lEnd = getFinalLocationByInitialLocationAndFinalChar(lInit, finalChar, aBody);
        return getAttributeValues(lInit, lEnd, aBody);
    }  

    private static String getValue( String aClass, String aBody )
    {
        Integer lInit = getInitialLocationByAttributeClass(aClass, aBody);
        Integer lEnd = getFinalLocationByInitialLocation(lInit, aBody);
        return getAttributeValues(lInit, lEnd, aBody);
    }

    private static Integer getInitialLocationByAttributeClass(String lClassName, String lBody){
        System.debug('THBS ---- lClassName' + lClassName);
        System.debug('THBS ---- lClassName length' + lClassName.length());
        System.debug('THBS ---- lBody.indexOf(lClassName)' + lBody.indexOf(lClassName));
        return lBody.indexOf(lClassName) + lClassName.length();   
    }

    private static Integer getFinalLocationByInitialLocation(Integer lInitialLocation, String lBody){
        return lBody.indexOf('</html>',lInitialLocation);      
    }
    private static Integer getFinalLocationByInitialLocationAndFinalChar(Integer lInitialLocation, string finalChar ,String lBody){
        return lBody.indexOf(finalChar,lInitialLocation);      
    }

    private static String getAttributeValues(Integer lAttrInitialLocation, Integer lAttrFinalLocation, String lBody){
        System.debug('THBS ---- lAttrFinalLocation' + lAttrFinalLocation);
        System.debug('THBS ---- lBody' + lBody);
        System.debug('THBS ---- lAttrInitialLocation' + lAttrInitialLocation);

        return lBody.substring(lAttrInitialLocation,lAttrFinalLocation).replace('\n','');  
    }

}
global class BatchGetTrailheadOfContacts implements Database.Batchable<sObject>, Database.AllowsCallouts {

   global Database.QueryLocator start( Database.BatchableContext bc ) {
      return Database.getQueryLocator('SELECT Id, Link_para_o_perfil_no_trailhead__c,Total_Pontos__c '
                                    + 'FROM Contact WHERE Ativo__c = true '
                                    + 'AND Link_para_o_perfil_no_trailhead__c != null');
    }    

   global void execute( Database.BatchableContext bc, List<Contact> scope ){
       Contact lcontact_Total_Pontos = new contact();
       decimal total_pontos = 0;

       for ( Contact lContact : scope ) {
            Map<String,String> lMapToGetStats = RESTGetHttpContentCallout.getCalloutResponseContents(lContact.Link_para_o_perfil_no_trailhead__c);
            if ( lMapToGetStats == null ) continue;

            System.debug('lMapToGetStats' + lMapToGetStats);
            System.debug('lMapToGetStats Badges' + lMapToGetStats.get('Badges'));
            String Pontos = lMapToGetStats.get('Pontos').replace('.', '');
            System.debug('lMapToGetStats' + lMapToGetStats.get('Pontos'));
            System.debug('Points' + Pontos);
            lContact.Pontos_no_trailhead__c = Pontos.isNumeric() ?  integer.valueOf(Pontos) : 0;
            lContact.Badges_no_trailhead__c = lMapToGetStats.get('Badges').isNumeric() ?  integer.valueOf(lMapToGetStats.get('Badges')) : 0;
            lContact.Trilhas_concluidas__c  = lMapToGetStats.get('Trails').isNumeric() ?  integer.valueOf(lMapToGetStats.get('Trails')) : 0;
            total_pontos +=  lContact.Pontos_no_trailhead__c;
          system.debug('pontos de cada talento: '+ lContact.Pontos_no_trailhead__c);
         // system.debug( 'total de pontos:'+ total_pontos);
      }
      lcontact_Total_Pontos.Total_Pontos__c =  total_pontos;
        system.debug( 'total de pontos:'+  lcontact_Total_Pontos.Total_Pontos__c);
      update scope;
   }

  global void finish( Database.BatchableContext bc ) {}

    global void execute(SchedulableContext sc) {
 BatchGetTrailheadOfContacts lbatch = new BatchGetTrailheadOfContacts();
    Database.executeBatch(lbatch); 
  }
}

 
AbhishekAbhishek (Salesforce Developers) 
Hi,

For all the Trailhead issues please report it here,

https://trailhead.salesforce.com/en/help?support=home

So that our trailhead support engineers will look into it and get back to you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Regards,
​​​​​​​Salesforce Support.