Sunday, November 22, 2020

Google Document AI

Summary

This post is a continuation of the previous on Google Cloud Functions and intake of attachments in email.  In this post, I'll extend what was done previously with the Document AI and Natural Language (NL)APIs.  In particular, I'll be parsing a notional Return Merchandise Authorization (RMA) pdf with the Document AI to find a field that will determine what the appropriate human skill set is necessary for further processing.  Additionally, I'll use the Sentiment function within NL to determine if the RMA requires special processing - i.e., an unhappy customer that requires special handling.

Part 2:  Google Document AI

Architecture



Example Form Input

This is a screen-shot of the PDF that is used for the input for this example.

Code Snippet - GCF Storage Trigger

This code gets called when the PDF is uploaded to Cloud Storage by the email handling GCF discussed in the previous post.
exports.processRma = async (event, context, callback) => {
  try {
    await processForm(event); 
  }
  catch(err) {
    console.error(err);
  }
  finally {
    callback();
  }
};

Code Snippet - Main Function (processForm)

    const formFields = await parseForm(file);
    let disposition = {};
    let choice;
    let sentiment;

    for (const field of formFields) {
        const fieldName = field.fieldName.trim();
        switch(fieldName) {
            case 'Credit or Replace:':
                choice = field.fieldValue.trim().toLowerCase(); 
                console.log(`choice: ${choice}`);
                break;
            case 'Comments:':
                sentiment = await getSentiment(field.fieldValue.trim());
                console.log(`sentiment: ${sentiment}`);
                break;
            default:
                ;
                break;
        } 
    }
    if (sentiment < 0) {
        disposition.skill = 'ADVOCATE';
    }
    else if (choice === 'replace') {
        disposition.skill = 'REPLACE';
    }
    else {
        disposition.skill = 'CREDIT';
    }
    
    const folder = file.name.split('/')[0];
    disposition.signedUrl = await moveFile(gcsObj.bucket, folder, file);
    disposition.timestamp = await routeDisposition(disposition);
    await writeDisposition(folder, disposition);
    return disposition;

Results

Cloud Log

Note that Document AI parsed out that this was a credit request.  Also, note the negative sentiment calculated on the Comments field.




Cloud Storage End State




Disposition JSON File

Note the required skill was updated to 'ADVOCATE' from 'CREDIT' due to the negative comments.
{
"skill":"ADVOCATE",
"signedUrl":"https://storage.googleapis.com/rma-processed/501289c9-f39a-4b51-a60e-2246..",
"timestamp":"Mon, 23 Nov 2020 15:18:29 GMT"
}

Copyright ©1993-2024 Joey E Whelan, All rights reserved.