Implement a SharinPix Token Decoder in Salesforce (Developer-Oriented)

This article demonstrates how to implement an Apex method to decode SharinPix tokens within Salesforce.

The following sections include:

  1. The Apex method to decode a SharinPix token.
  2. A use case example demonstrating how to call the Apex method in a Salesforce Flow to decode and save the decoded token in a Salesforce field.

Tip:

SharinPix tokens can also be decoded easily outside of Salesforce using the jwt.io website.

Apex Method

The code snippet below shows an Apex method used to decode SharinPix tokens.

public static Map<String, Object> decode(string token){
    string payload = token.split('\\.')[1];
    payload = payload.replace('-', '+');
    payload = payload.replace('_', '/');
    string jsonPayload = EncodingUtil.base64decode(payload).toString();
    Map<String, Object> decodeTokenObject = (Map<String, Object>) JSON.deserializeUntyped(jsonPayload);
    return decodeTokenObject;
}
Click to copy

Example: Using a Salesforce Flow to decode a token and save it in a field

In this section, we will demonstrate how to call the token decoder in a Salesforce Flow to decode an Account's token and save the decoded value in a field.


Creating the Invocable Class

To call the token decoder method in a Salesforce Flow, you should first create an Apex invocable class that will accept the following parameters from the Flow to decode the token:

  1.  recordId: ID of the record for which you want to decode the token.
  2.  encodedToken: The encoded token.
  3.  decodedTokenFieldName: API name of the field storing the decoded token.

The code below is an example of an invocable class used to decode SharinPix tokens.

public class SharinPixTokenDecoder {
    @InvocableMethod    
    public static void decodeToken(List<Parameters> paramsList) {
        SObject obj;        
        List<SObject> sObjectsToUpdate = new List<SObject>(); 

		for(Parameters params : paramsList) {
            obj = params.recordId.getSObjectType().newSObject(params.recordId);

            String payload = params.encodedToken.split('\\.')[1];
            payload = payload.replace('-', '+');
            payload = payload.replace('_', '/');
            string jsonPayload = EncodingUtil.base64decode(payload).toString();
            Map<String, Object> decodeTokenObject = (Map<String, Object>) JSON.deserializeUntyped(jsonPayload);

            obj.put(params.decodedTokenFieldName, decodeTokenObject.toString());
            sObjectsToUpdate.add(obj);
        }
        update sObjectsToUpdate;
    }       

    public with sharing class Parameters{
        @InvocableVariable(label='Record ID' description='ID of record.' required=true)
        public Id recordId;

        @InvocableVariable(label='Encoded Token' description='The encoded token.' required=true)
        public String encodedToken;
        
        @InvocableVariable(label='Decoded Token Field API Name' description='API name of field storing the decoded token.' required=true)
        public String decodedTokenFieldName;
    }
}
Click to copy

The corresponding test class is as follows:

@isTest
public class SharinPixTokenDecoderTest {
    @isTest static void testDecodedFieldValue() {
        String token;
        Account acc = new Account(Name = 'Test Record Name');
        insert acc;

        token = sharinpix.Client.getInstance().token(
            new Map<String, Object> {
                'exp' => 0,
				'album_id' => acc.Id,
				'name' => acc.name
			}
        );

        acc.SharinPix_Token__c = token;
        update acc;

        List<SharinPixTokenDecoder.Parameters> paramsList = new List<SharinPixTokenDecoder.Parameters>();
        SharinPixTokenDecoder.Parameters param = new SharinPixTokenDecoder.Parameters();
        param.recordId = acc.Id;
        param.encodedToken = acc.SharinPix_Token__c;
        param.decodedTokenFieldName = 'SharinPix_Decoded_Token__c';
        paramsList.add(param);

        Test.startTest();
        SharinPixTokenDecoder.decodeToken(paramsList);
        Test.stopTest();

        Account myAccount = [SELECT Id, Name, SharinPix_Decoded_Token__c FROM Account WHERE Id =: acc.Id LIMIT 1];
        String decodedToken = myAccount.SharinPix_Decoded_Token__c;
        System.assert(decodedToken.contains(myAccount.Id));
        System.assert(decodedToken.contains(myAccount.Name));
    }
}
Click to copy

Creating the Salesforce Flow

Once the invocable class is ready, go ahead and create the Salesforce Flow as explained below.

  • Go to Setup. In the Quick Find Box, type Flows.
  • Under Process Automation, select Flows.
  • Click on the New Flow button.
  • Select the option Record-Triggered Flow, and click on the Create button.
  • After clicking on Create, the Configure Start modal will be displayed. Fill in the modal as indicated below:
    • Select Object: Account
    • Configure Trigger: A record is created or updated
    • For the Set Entry Conditions, select All Conditions Are Met (AND)and fill in the details as follows:
      1.  Field: SharinPix_Token__c (or your token field API name)
      2.  Operator: Is Null
      3.  Value: False
    • Leave the other fields as is.
  • Click on Done to save the configuration.
  • Next, add an Action element.
  • On the Action modal, use the search bar to find the SharinPixTokenDecoder Apex class, that is, the name of the invocable Apex class.
  • On the Action modal for SharinPixTokenDecoder, populate the fields as indicated below:
  • Label: SharinPix Token Decoder
  • Description: Enter a description (optional)
  • Decoded Token Field API Name: SharinPix_Decoded_Token__c
  • Encoded Token: {!$Record.SharinPix_Token__c}
  • Record ID: {!$Record.Id}
  • Click Done to save the Action configurations.   
  • Save the Flow and activate it.

Demo

To test the Flow:

  1. Generate a new token on an Account record.
  2.  Verify that the decoded field is populated with the decoded value as depicted below.

0 Comments

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.