Capture document details via OCR

Use the OCR component provided by OneSDK to extract document details from a document images supplied by the user. The OCR component dynamically loads the OCR provider configured for your account, which can be modified even after your application is live in production.

To implement the OCR component, you implement your own user interface to capture document images, and OneSDK automates the process of communicating with the FrankieOne platform and evaluating the verification results.

Implement an OCR flow by responding to events

A typical OCR flow consists of the following steps:

  1. Capture an image of a physical identity document
  2. If required, capture a second image. For example, the back side of a drivers license.
  3. Obtain document OCR results, with all data extracted from the images.

Each one of those steps are managed by the OCR component as an event driven interaction with the host UI. You may trigger step 1 by calling the method start in the OCR component and for each step a different event will be emitted, where the host UI can react accordingly. Said events are:

The input_required event

ocr.on('input_required', (info, status, provideFile) => {
  // your code here
});

The input_required event is called when the user needs to supply an image for the document. You can inspect event's arguments to determine how to prompt the user.

Your event listener should be a callback of the form (info, status, provideFile) => void.

ParameterDescription
infoAn object describing the document image to request from the user. The object contains two properties, documentType, which may be one of "PASSPORT" or "DRIVERS_LICENCE", and side, which may be one of "front" or "back".
statusThe status of the OCR flow. See the table below.
provideFileA function that accepts a single argument], file, of type File.

The OCR flow status is described as a string constant, which you can access from the OCRStatuses object.

The OCRStatus type

StatusDescription
OCRStatus.WAITING_OCR_RUNWaiting for OCR to be run on existing scans, most common after interrupted flows
OCRStatus.WAITING_BACKWaiting for the back scan of a document
OCRStatus.WAITING_FRONTWaiting for the front scan of a document
OCRStatus.COMPLETECurrent OCR process was completed
OCRStatus.DOCUMENTS_INVALIDDocument type is invalid or couldn't be inferred. Could happen with bad captures
OCRStatus.DOCUMENTS_UPLOAD_FAILEDProvided scan was rejected by provider. Probably means low quality capture
OCRStatus.PROVIDER_OFFLINEProvider is not available at the moment
OCRStatus.FAILED_FILE_SIZEProvided file is too large
OCRStatus.FAILED_FILE_FORMATProvided file format wasn't accepted

The results event

ocr.on('results', (document) => {
  // your code here
);

The results event is called when OCR is complete and data was extracted from the supplied images.

Your event listener should be a callback of the form (document) => void.

ParameterDescription
documentA Document object. See the table below.

The error event

ocr.on('error', (error) => {
  console.error(error.message)
});

The error event is called when the OCR component encounters a problem it cannot recover from.

Your event listener should be a callback of the form (error) => void.

ParameterDescription
errorAn object with a message property containing a string and a payload property containing an object with more details about the error.

Access the OCR flow status

The following example accesses the status of the OCR flow.

const { getValue } = ocr.access('status');

const status = getValue();

Re-attempt an image capture

The image may be low quality, a bad angle, or not contain the requested document, causing document detection to fail. In this case the the input_required event may be called multiple times with the same info argument so that the user has an opportunity to try and capture the image again.

The following example uses the status argument to determine whether to prompt the user to try again.

ocr.on("input_required", (info, status, provideFile) => {
  
  let message = "";
  if (status === oneSdkOcr.statuses.DOCUMENTS_INVALID) {
    // IF OCR EXTRACT ISNT A VALID DOCUMENT TYPE
    message = `Oops, seems like that wasn't a ${info.documentType}, try again.`;
  } else if (status === oneSdkOcr.statuses.DOCUMENTS_UPLOAD_FAILED) {
    // IF OCR EXTRACT FAILED TO POOR IMAGE QUALITY
    message = `Oops, seems like that wasn't very clear, try again.`;
  } else {
    // WHEN EVERYTHING WORKS FINE
    message = info.documentType 
      ? `Alright, give us the ${info.side} of your ${info.documentType}`
      : "Alright, give us a scan of either your Passport or your Drivers Licence";
  }

  showDialog(message, provideFile);
});

Complete example

Use the component('ocr', options?) method to instantiate the OCR component.

// 1. Obtain the OCR component
const config = {
  dummy: true // Remove this in production
};
const oneSdk = await OneSdk(config);
const ocr = oneSdk.component("ocr");

// 2. Register event listeners

oneSdkOcr.on("input_required", (info, status, provideFile) => {
  dialog(`Please provide the ${info.side} of your ${info.documentType}`, (selectedFile) => {
    provideFile(selectedFile)
  });
});

oneSdkOcr.on("results", ({ document }) => {
  dialog(`Please confirm your information: ${document}`, (okOrNot) => {
    if (okOrNot) gotoNextPage();
    else oneSdkOcr.start() // restart flow
  })
});

oneSdkOcr.on("error", ({ message }) => {
  alert(`There was an issue (${message}). We'll skip OCR for now.`);
  gotoNextPage();
});

// 3. Start the OCR flow

oneSdkOcr.start();