Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make public process_document_buffer and improve error handling #33

Merged
merged 8 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 63 additions & 15 deletions lib/main.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const {createHmac} = require('crypto');
const axios = require('axios').default;
const path = require('path');
const FormData = require('form-data');
const fs = require('fs');
const {promisify} = require("util");

/**
* Create instance of a Client
Expand All @@ -21,12 +23,13 @@ function Client(
api_key,
base_url = "https://api.veryfi.com/",
api_version = "v8",
timeout = 120,) {
timeout = 120) {
this.client_id = client_id;
this.client_secret = client_secret;
this.username = username;
this.api_key = api_key;
this.base_url = base_url;
this.timeout = timeout;
this.api_version = api_version;
this.CATEGORIES = [
"Advertising & Marketing",
Expand Down Expand Up @@ -64,7 +67,7 @@ Client.prototype._check_w2_version = function () {
*/
Client.prototype._get_headers = function (has_files = false) {
let final_headers = {
"User-Agent": "Node.js Veryfi-Nodejs/1.2.3",
"User-Agent": "Node.js Veryfi-Nodejs/1.2.4",
"Accept": "application/json",
"Content-Type": "application/json",
"Client-Id": this.client_id,
Expand Down Expand Up @@ -117,11 +120,10 @@ Client.prototype._generate_signature = function (payload_params, timestamp) {
* @param {string} endpoint_name Endpoint name such as 'documents', 'users', etc.
* @param {{}} request_arguments JSON payload to send to Veryfi
* @param params {{}} query params.
* @param file_stream file stream of the document
* @param {Boolean} has_files Are there any files to be submitted as binary
* @returns {JSON} A JSON of the response data.
*/
Client.prototype._request = async function (http_verb, endpoint_name, request_arguments, params = {}, file_stream = null) {
let has_files = (Boolean(file_stream));
Client.prototype._request = async function (http_verb, endpoint_name, request_arguments, params = {}, has_files = false) {
let headers = this._get_headers(has_files);
let api_url = `${this._get_url()}/partner${endpoint_name}`;

Expand All @@ -134,12 +136,21 @@ Client.prototype._request = async function (http_verb, endpoint_name, request_ar
});
}

if (has_files === false) {
request_arguments = JSON.stringify(request_arguments);
if (has_files) {
const formData = new FormData();
for (const key in request_arguments) {
if (request_arguments.hasOwnProperty(key)) {
const value = request_arguments[key];
formData.append(key, value);
}
}
headers = Object.assign(headers, formData.getHeaders());
const getLength = promisify(formData.getLength).bind(formData);
headers['Content-Length'] = await getLength()
request_arguments = formData;
} else {
Object.assign(headers, {...request_arguments});
request_arguments = JSON.stringify(request_arguments);
}

try {
return await axios.request({
method: http_verb,
Expand All @@ -150,9 +161,10 @@ Client.prototype._request = async function (http_verb, endpoint_name, request_ar
params: params
});
} catch (response) {
let errorStatus = response['response']['status'];
let errorInfo = response['response']['data']['error'];
throw new Error(errorStatus + errorInfo);
let errorStatus = response?.response?.status;
let errorInfo = response?.response?.data?.error;
let message = response?.message;
throw new Error(`Error: ${errorStatus} ${errorInfo} ${message}`);
}
}

Expand Down Expand Up @@ -228,21 +240,57 @@ Client.prototype.process_document = async function (
/**
* Process a document and extract all the fields from it
* @example
* veryfi_client.process_document_buffer('base64_encoded_string',
* veryfi_client.process_document_stream('ReadStream',
* 'receipt.png',
* ['Entertainment','Food'],
* true,
* {'extra': 'parameters'})
*
* @memberof Client
* @param {ReadStream} file ReadStream of a file to submit for data extraction
* @param {String} file_name The file name including the extension
* @param {Array} categories List of categories Veryfi can use to categorize the document
* @param {Boolean} delete_after_processing Delete this document from Veryfi after data has been extracted
* @param {Object} kwargs Additional request parameters
* @returns {JSON} Data extracted from the document
*/
Client.prototype.process_document_stream = async function (
file,
file_name,
delete_after_processing = false,
{...kwargs} = {}
) {

let endpoint_name = "/documents/";

let request_arguments = {
"file_name": file_name,
"file": file,
"auto_delete": delete_after_processing.toString(),
};
request_arguments = Object.assign(request_arguments, kwargs);
let document = await this._request("POST", endpoint_name, request_arguments, {}, true);
return document['data'];
}

/**
* Process a document and extract all the fields from it
* @example
* veryfi_client.process_document_base64string('base64_encoded_string',
* 'receipt.png',
* ['Entertainment','Food'],
* true,
* {'extra': 'parameters'})
*
* @memberof Client
* @param {String} base64_encoded_string Buffer of a file to submit for data extraction
* @param {String} base64_encoded_string Buffer string of a file to submit for data extraction
* @param {String} file_name The file name including the extension
* @param {Array} categories List of categories Veryfi can use to categorize the document
* @param {Boolean} delete_after_processing Delete this document from Veryfi after data has been extracted
* @param {Object} kwargs Additional request parameters
* @returns {JSON} Data extracted from the document
*/
Client.prototype.process_document_buffer = async function (
Client.prototype.process_document_base64string = async function (
base64_encoded_string,
file_name,
categories = null,
Expand Down
53 changes: 53 additions & 0 deletions lib/types/main.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import fs from "fs";

/**
* Additional request parameters type
*/
Expand Down Expand Up @@ -44,6 +46,7 @@ export declare type VeryfiDocument = {
payment_display_name?: null | string;
payment_terms?: null | string;
payment_type?: null | string;
pdf_url?: null | string;
phone_number?: null | string;
purchase_order_number?: null | string;
rounding?: null | number;
Expand Down Expand Up @@ -186,6 +189,56 @@ export declare class Client {
*/
public get_document(document_id: string): Promise<VeryfiDocument>;

/**
* Process a document and extract all the fields from it
* @example
* veryfi_client.process_document_buffer('buffer',
* 'receipt.png',
* ['Entertainment','Food'],
* true,
* {'extra': 'parameters'})
*
* @memberof Client
* @param {ReadStream} file ReadStream of a file to submit for data extraction
* @param {String} file_name The file name including the extension
* @param {Array} categories List of categories Veryfi can use to categorize the document
* @param {Boolean} delete_after_processing Delete this document from Veryfi after data has been extracted
* @param {Object} kwargs Additional request parameters
* @returns {JSON} Data extracted from the document
*/
public process_document_stream(
file: fs.ReadStream,
file_name: string,
categories?: string[],
delete_after_processing?: boolean,
{ ...kwargs }?: VeryfiExtraArgs
): Promise<VeryfiDocument>;

/**
* Process a document and extract all the fields from it
* @example
* veryfi_client.process_document_buffer_string('base64_encoded_string',
* 'receipt.png',
* ['Entertainment','Food'],
* true,
* {'extra': 'parameters'})
*
* @memberof Client
* @param {String} base64_encoded_string Buffer string of a file to submit for data extraction
* @param {String} file_name The file name including the extension
* @param {Array} categories List of categories Veryfi can use to categorize the document
* @param {Boolean} delete_after_processing Delete this document from Veryfi after data has been extracted
* @param {Object} kwargs Additional request parameters
* @returns {JSON} Data extracted from the document
*/
public process_document_base64string(
base64_encoded_string: string,
file_name: string,
categories?: string[],
delete_after_processing?: boolean,
{ ...kwargs }?: VeryfiExtraArgs
): Promise<VeryfiDocument>;

/**
* Process a document and extract all the fields from it
* @example
Expand Down
Loading
Loading