Showing posts with label sharinpix. Show all posts
Showing posts with label sharinpix. Show all posts

Thursday, July 30, 2020

Getting Started with Salesforce Einstein Vision OCR - Part 1

What is Einstein OCR?

We all know that OCR is an Optical Character Recognition which can detect and extract text from images. But, what about Einstein OCR?

Einstein OCR provides models that can detect text in an image such as Business cards, Images that contain unformatted data and images that contain data in tables.

In this blog post, we will focus on the Business Card Model. When choosing business card model, Einstein OCR can detect the entity type text such as Person, Organization, Email, Phone, Address, etc...

Sign Up

To get Started with Einstein Vision, you first need to register for an Account (If you don't already have one). 
Go to: https://api.einstein.ai/signup and Click on Sign Up using Salesforce.



Sign Up Einstein Vision
Sign Up


It is quite straight forward after that. If all goes well, you should see a screen with your Einstein Private Key like below. Download the key and keep it safe for later.

Private key
Private Key

Setup

Deploy Salesforce code

Once you have an Einstein Account, we can start the setup. For the next step, you will require some basic developer skills. 

Download this SFDX project from my public github repository: https://github.com/kevanmoothien/einsteinvisionocr

Connect the project to your Organization using SFDX: Authorize an Org option and then deploy all the elements inside the project structure.

Configure Permission for Salesforce App

When everything has been deployed, you can assign the App Einstein OCR to the desired Profile. 

profile assignment
Profile Assignment


Setup Einstein Vision

Configuring Einstein Vision is pretty straight forward, just switch to the Einstein OCR app on your Salesforce and open the Einstein Vision Setup tab

Enter the email address you used to Sign Up (make sure it is the email and not the Salesforce Username; you should find it in the welcome Einstein Mail).
Then use the Upload Files button to upload the private key (einstein_platform.pem file that you downloaded previously)

When saving the setting, you should have a green tick icon on the right hand side of the component to validate that the Account is valid.

Setup Einstein Vision
Setup Einstein Vision


OCR in Action

To see the OCR in action, simply click on the Einstein OCR tab next to the Einstein Vision Setup tab.

Insert a Business Card Image Url and click on Scan.

Demo

The page comprises of 3 simple component: 
  • Component to input the Image Url
  • Another one for Preview the Business Card
  • lastly, result previewer
From the above example, you can see Mark Benioff business card. It has already categorised the different elements found on the Business  Card.

Wrap-Up

If you want to dive into more details on how the API call is done and detection result is processed, you can just take a look at the class EinsteinVisionUtils and Prediction class in the source code. 

Monday, December 3, 2018

Mock HTTP callouts in a Managed Package


In this blog, I will show you how to mock callout response which is in a managed package.


I found out that many developers are using Test.IsRunningTest() in their Apex classes to avoid writing Mock responses for http callouts and if the callout comes from a Managed Package, they are stuck with this message "Methods defined as TestMethod do not support Web service callouts".

As per Salesforce Documentation, "To mock a callout if the code that performs the callout is in a managed package, call Test.setMock from a test method in the same package with the same namespace."

So to be able to mock callout which is performed in a managed package, the line doing "Test.setMock" should be called from the managed package itself.

So what we did in the SharinPix (ISV) managed package, we added a global class which take a HttpCalloutMock class as parameter and execute the Test.setMock from within the package.

@isTest
global class HttpCalloutSimulator {
    global static void setMock(HttpCalloutMock mock) {
        Test.setMock(HttpCalloutMock.class, mock);
    }
}

By adding the above class in your package and making it global so that it ca be called outside the managed package make it easy to mock code which are doing callout in your package without getting error messages.

You will just need to call it as below:

[namespace].HttpCalloutSimulator.setMock(mock);

Example on how to use it:

sharinpix.HttpCalloutSimulator.setMock(HttpCalloutMock mock);  
//where the variable mock is the instance of your HttpCalloutMock class

Links: 

Tuesday, May 16, 2017

Automatic package license assignment to Users

We have been asked by one of our customer at SharinPix if it was possible to assign Licenses to newly created user automatically and removing the license on user upon deactivation. The solution that I was asked to do was a trigger. But this solution requires coding which will require a test class, changeset for deployment, giving user permission to execute the trigger which it quite a lot to do. In case something is wrong with the trigger, we will be required to modify on the customer sandbox and deploying again, which is kind of tedious. 

But recently I did a module on Trailhead about Process Automation which explain how to achieve complex logic without having the need to write a single piece of Apex Code. It is only by configuring Flows and Process Builders. 

Here is the solution for the above requirement

The following objects will be used to automate assigning user license: 

Below are the steps to create a Flow and Process Builder.

Flow


1. Go to Setup, Search Flows from the Quick Find textbox
2. Click on New Flow, the Flow Designer will open. 
On the left sidebar, click on the tab Resources. Create two variables var_UserId of type text and var_isNew which will store the package license id and the user id. See screenshot below. 

Variable User Id

Variable IsNew
Create a third variable of type SObject variable. Name is SharinPixLicense and Object Type is PackageLicense.

SharinPix License sobject variable

3. We now need to retrieve the Id of the license for the SharinPix package. Drag and drop a Record Lookup element to the canvas. Enter a name and insert the following properties: 
  • Look up: PackageLicense
  • Field: NamespacePrefix, Operator: 'equals', Value: 'sharinpix' (The namespace prefix of the package: Setup | Build | Installed Packages)
  • Variable assignment 
    • Field: Id, Variable: '{!SharinPixLicense.Id}'
    • Field: AllowedLicenses, Variable: '{!SharinPixLicense.AllowedLicenses}'
    • Field: UsedLicenses, Variable: '{!SharinPixLicense.UsedLicenses}'





4. Drag and drop the Record Create element to the canvas. Enter a name and insert the following properties: 
  • Create: UserPackageLicense
  • Field: PackageLicenseId, Value: {!SharinPixLicense.Id}
  • Field: UserId, Value: {!var_UserId} 
Assign license to user


Now that we have the create record, we now need to have the delete license equivalent

5. Drag and drop the Record Delete element. Enter a name and the following properties
  • Delete: UserPackageLicense
  • Field: UserId, Value: {!var_UserId} 
  • Field: PackageLicenseId, Value: {!SharinPixLicense.Id}
Remove license from user

6. Let's create the logic and assemble all the component. 
Drag and drop the Decision element on the canvas. Enter a name and create two outcomes
  • Outcome 1 
    • Name: Created
    • Resource: {!var_isNew}, Operator: equals, Value: {!$GlobalConstant.True}
    • Resource: {!SharinPixLicense.UsedLicenses}, Operator: less than, Value: {!SharinPixLicense.AllowedLicenses}
Note: I have added the condition that Used licenses should be less than Allowed Licenses in order for the flow not to crash if all licenses have been used. 
  • Outcome 2
    • Name: Deleted
    • Resource: {!var_isNew}, Operator: equals, Value: {!$GlobalConstant.False}



7. Link the component same as in the image below and set the Record Lookup as the start of the flow (click on the green arrow icon)
Wrap everything

8. Save your Flow with a name, select type Autolaunched Flow and activate it once done. 
Save flow

Process Builder


Now that our flow is completed. We need to trigger the flow and we will use a process builder to do that.

1. Go to Setup | App Setup | Create | Workflows & Approvals | Process Builder
Click on the New button, Enter the Process Name and API Name and click on Save button.
New Process

2. We need to trigger the process on a specific Object. For this, click on Add Object and in the properties, select User and select when a record is created or edited. Click on Save.
Entry criteria

3. Next step is to add the Process Criterias. In our case, we will have two criteria. One will cater for new user and the other one for user which has been deactivated.
  • Let's create the first one. Click on Add Criteria
    • Criteria Name: User is active
    • Select Formula evaluates to true
    • In the formula field, insert the following formula
      • ( ISNEW() && [User].IsActive ) || ( ISCHANGED([User].IsActive) &&  [User].IsActive )
Save the criteria
New user active or update a user to active

  • Let's create the first one. Click on Add Criteria
    • Criteria Name: User is not active
    • Select Formula evaluates to true
    • In the formula field, insert the following formula
      • ( ISCHANGED([User].IsActive) && NOT( [User].IsActive ))
Save the criteria 


4. Now we add the actions for each criteria. 
For the User is active criteria. In the Intermediate Action section, click Add Action with the following properties:
  • Action Type: Flows
  • Action name: Create License
  • Flow: Automatic Package License assignment (Yours may be under a different name)
  • Set Flow Variables
    • Flow Variable: var_UserId, Type: Reference, Value: [User].Id
    • Flow Variable: var_isNew, Type: Boolean, Value: True

5. Let's repeat step 4 for the User is not active criteria. Change the Action Name to Delete License and set the flow variable var_isNew to False.

Your process builder should look like below. 
Finally, Click on Activate to enable it. 



Every new user shall be affected a License to the package and user being deactivated will have their license removed. 

Do not hesitate to contact me in case something is missing or needs improvements. 

Cheers :)