Introduction

In this tutorial we will get to know how can we use Einstein Vision API from Apex Classes i.e. creating the data sets, training data sets and the getting predictions based on the data set. Below are the prerequisite to be done before starting the tutorial:

  1. Navigate to singup page at https://api.einstein.ai/signup
  2. Upload the einstein_platform.pem file in Salesforce documents.
  3. Add https://api.einstein.ai/ and https://api.metamind.io/ to Remote Site in Salesforce.
  4. Download the JWT and JWTBearer classes to be used from https://github.com/salesforceidentity/jwt

 

Getting the Access Token

To perform any operation like creating dataset, checking for status, etc would require you to have a valid access token. Below is the code which is used to generate the access token:

public String getAccessToken() {
	String tokenEndpoint = 'https://api.metamind.io/v1/oauth2/token';
	
	ContentVersion base64Content = [
		SELECT  Title
				,VersionData
		FROM    ContentVersion
		WHERE   Title = 'einstein_platform'
		OR      Title = 'predictive_services'
		ORDER BY Title
		LIMIT 1
	];
	
	String keyContents  = base64Content.VersionData.tostring();
	keyContents         = keyContents.replace( '-----BEGIN RSA PRIVATE KEY-----', '' );
	keyContents         = keyContents.replace( '-----END RSA PRIVATE KEY-----', '' );
	keyContents         = keyContents.replace( '\n', '' );

	JWT jwt             = new JWT( 'RS256' );
	
	jwt.pkcs8           = keyContents; 
	jwt.iss             = 'developer.force.com';
	jwt.sub             = registeredEmail;
	jwt.aud             = tokenEndpoint;
	jwt.exp             = String.valueOf( tokenExpirationSeconds );
	String access_token = JWTBearerFlow.getAccessToken( tokenEndpoint, jwt );
	return access_token;
}

Creating Dataset

Let us create a dataset with some input csv file located on internet space like dropbox, google drive etc:

public void createDataset() {
	String key = getAccessToken();
	String filePath = 'https://path-to-file';
	String separationString = 'WebKitFormBoundaryTest';

	String header = '------' + separationString + '\r\n';
	header += 'Content-Disposition: form-data; name="type"\r\n\r\n';
	header += 'text-intent' + '\r\n';
	header += '------' + separationString + '\r\n';
	header += 'Content-Disposition: form-data; name="path"\r\n\r\n';
	header += filePath;
	String footer = '\r\n------' + separationString + '--';
	String bodyPayload = header + footer;
	
	Http http = new Http();
	
	HttpRequest req = new HttpRequest();
	req.setMethod( 'POST' );
	req.setEndpoint('https://api.einstein.ai/v2/language/datasets/upload');
	req.setHeader( 'Authorization', 'Bearer ' + key );
	req.setHeader('Content-Type', 'multipart/form-data; boundary=----' + separationString);
	req.setHeader('Content-Length', ''+bodyPayLoad.length());
	req.setHeader( 'Cache-Control', 'no-cache' );
	req.setBody(bodyPayload);
	
	HTTPResponse res = http.send( req );
}

Get Dataset Status

We can check the status of dataset is it is created successfully or not using the below code:

public void getDatasetStatus(String datasetId) {
	String key = getAccessToken();
	Http http = new Http();
	HttpRequest req = new HttpRequest();
	req.setMethod( 'GET' );
	req.setEndpoint('https://api.einstein.ai/v2/language/datasets/'+datasetId);
	req.setHeader( 'Authorization', 'Bearer ' + key );
	req.setHeader( 'Cache-Control', 'no-cache' );
	
	HTTPResponse res = http.send( req );
}

Train your Dataset

This is the main thing where AI plays its role and trains the data to be utilized based on occurrence, please use below code to train you dataset:

public void trainDataset(String datasetId) {
	String key = getAccessToken();
	String separationString = 'WebKitFormBoundaryTest';
	String header = '------' + separationString + '\r\n';
	header += 'Content-Disposition: form-data; name="name"\r\n\r\n';
	header += 'Case Routing Model' + '\r\n';
	header += '------' + separationString + '\r\n';
	header += 'Content-Disposition: form-data; name="datasetId"\r\n\r\n';
	header += datasetId + '\r\n';
	String footer = '\r\n------' + separationString + '--';
	String bodyPayload = header + footer;
	
	Http http = new Http();
	HttpRequest req = new HttpRequest();
	req.setMethod( 'POST' );
	req.setEndpoint('https://api.einstein.ai/v2/language/train');
	req.setHeader( 'Authorization', 'Bearer ' + key );
	req.setHeader('Content-Type', 'multipart/form-data; boundary=----' + separationString);
	req.setHeader('Content-Length', ''+bodyPayLoad.length());
	req.setHeader( 'Cache-Control', 'no-cache' );
	req.setBody(bodyPayload);
	
	HTTPResponse res = http.send( req );
}

Get Training Status

Sometimes training datasets can take up to days depending on size, hence we can check the training status using below code:

public void getTrainDatasetStatus(String modelId) {
	String key = getAccessToken();
	Http http = new Http();
	HttpRequest req = new HttpRequest();
	req.setMethod( 'GET' );
	req.setEndpoint('https://api.einstein.ai/v2/language/train/'+modelId);
	req.setHeader( 'Authorization', 'Bearer ' + key );
	req.setHeader( 'Cache-Control', 'no-cache' );
	
	HTTPResponse res = http.send( req );
}

Get AI Predictions

After training the dataset we can use it to predict the outcomes based on our custom inputs as shown in below code:

public void predictDataset(String modelId, String searchText) {
	String key = getAccessToken();
	String separationString = 'WebKitFormBoundaryTest';
	String header = '------' + separationString + '\r\n';
	header += 'Content-Disposition: form-data; name="modelId"\r\n\r\n';
	header += modelId + '\r\n';
	header += '------' + separationString + '\r\n';
	header += 'Content-Disposition: form-data; name="document"\r\n\r\n';
	header += searchText + '\r\n';
	String footer = '\r\n------' + separationString + '--';
	String bodyPayload = header + footer;
	
	Http http = new Http();
	HttpRequest req = new HttpRequest();
	req.setMethod( 'POST' );
	req.setEndpoint('https://api.einstein.ai/v2/language/intent');
	req.setHeader( 'Authorization', 'Bearer ' + key );
	req.setHeader('Content-Type', 'multipart/form-data; boundary=----' + separationString);
	req.setHeader('Content-Length', ''+bodyPayLoad.length());
	req.setHeader( 'Cache-Control', 'no-cache' );
	req.setBody(bodyPayload);
	
	HTTPResponse res = http.send( req );
}

Conclusion

Vision API is really interesting and easy to integrate with Salesforce yet you have to think on your data sets, how to prepare the data which can be trained and used meaningfully by the system. Please do let me know if you have any queries or need assistance in setting up Einstein in your ORG.


0 Comments

Leave a Reply