Initialization
- VanillaJS/Node
- Next.JS(TypeScript)
- React
- Angular
- Svelte
- Create
index.js
next to yourindex.html
- Import it to your
index.html
<script src="index.js" type="module"></script>
- Import SDK to your
index.js
import VeryfiLens from "./veryfi-lens-wasm/veryfi-lens.js"
- Set process url and your credentials from Authentification
const PROCESS_DOCUMENT_URL = "https://lens.veryfi.com/rest/process" or "https://lens-dev.veryfi.com/rest/process";
const CLIENT_ID = "YOUR_CLIENT_ID";
const API_KEY = "YOUR_API_KEY";
const USERNAME = "your.username";
- Add function to validate client and receive session token (it is necessary to initialize Lens)
async function validatePartner(clientId) {
const validateUrl = "https://lens.veryfi.com/rest/validate_partner";
try {
const requestOptions = {
method: "POST",
headers: { "CLIENT-ID": clientId },
};
const response = await fetch(validateUrl, requestOptions);
const data = await response.json();
return data.session;
} catch (error) {
console.error("Error validating partner:", error);
return null;
}
}
Call it
const sessionToken = validatePartner(CLIENT_ID)
Call
const deviceData = await VeryfiLens.getDeviceData()
(Is reqiured to send an image to our backend)
- Add Drag and Drop area to your
index.html
<div id="upload-area"
class="upload-area"
ondrop="drop(event)"
ondragover="dragOver(event)"
ondragleave="dragLeave(event)"
onclick="triggerInput()">
Drag and Drop or Click here to upload receipt
<input
id="file-input"
type="file"
accept="image/*"
onchange="handleImageChange(event)"
class="hidden"
/>
</div>
- Add functions to take care of user's actions
let imageFile
let base64Image
window.dragOver = (event) => {
event.preventDefault();
event.stopPropagation();
};
window.dragLeave = (event) => {
event.preventDefault();
event.stopPropagation();
};
window.drop = (event) => {
event.preventDefault();
event.stopPropagation();
const files = event.dataTransfer.files;
if (files.length > 0) {
processFile(files[0]);
}
};
window.triggerInput = () => {
document.getElementById("file-input").click();
};
window.handleImageChange = (event) => {
const file = event.target.files[0];
imageFile = file;
if (file) {
processFile(file);
}
};
function processFile(file) {
const reader = new FileReader();
reader.onload = (e) => {
const imgData = e.target.result;
base64Image = imgData;
document.getElementById("upload-image").src = base64Image; //Add <img id="upload-image" /> to your html to show users document
};
reader.onerror = (error) => {
console.error("Error reading file:", error);
};
reader.readAsDataURL(file);
}
Add crop function
const data = await VeryfiLens.captureUploaded(imageFile)
(Pass it a blob with users image, it will return cropped image in base64)Call
await VeryfiLens.initUploadWasm(sessionToken, CLIENT_ID)
- Create
.env
file - Store your credentials from Authentification in
.env
file
NEXT_PUBLIC_PROCESS_DOCUMENT_URL = https://lens.veryfi.com/rest/process or https://lens-dev.veryfi.com/rest/process
NEXT_PUBLIC_CLIENT_ID=YOUR_CLIENT_ID
NEXT_PUBLIC_API_KEY=YOUR_API_KEY
NEXT_PUBLIC_USERNAME=YOUR_USERNAME
They are required for initialization of Lens For Web and for processing of resulting image
- Import SDK
import VeryfiLens from 'veryfi-lens-wasm'
const VeryfiLens = require('veryfi-lens-wasm').default
- Add a function to validate partner and receive session token (it is necessary to initialize Lens)
const validatePartner = async (clientId: string): Promise<any> => {
const validateUrl = 'https://lens.veryfi.com/rest/validate_partner';
const requestOptions = {
method: 'POST',
headers: {
'CLIENT-ID': clientId,
},
};
return fetch(validateUrl, requestOptions)
.then((response) => response.json())
.then((data) => {
return data.session;
})
.catch((error) => {
return error;
});
};
- Initialize Lens
const [imageData, setImageData] = useState("");
const fileInputRef = useRef(null);
const [veryfiLens, setVeryfiLens] = useState<{
getDeviceData: () => string;
setUserAgent: (arg0: string) => void;
initUploadWasm: (arg0: string, arg1: string) => void;
captureUploaded: (arg0: Blob) => Promise<string>;
} | null>(null);
const CLIENT_ID = process.env.NEXT_PUBLIC_CLIENT_ID;
useEffect(() => {
const startWasm = async () => {
if (typeof window !== "undefined") {
const lens = require("veryfi-lens-wasm").default;
lens.setUserAgent(navigator.userAgent);
setDeviceData(lens.getDeviceData());
await lens.initUploadWasm(sessionToken, CLIENT_ID);
setVeryfiLens(lens);
}
};
startWasm();
}, []);
- Add functions to handle user's actions with drag and drop area
const processFile = (file: any) => {
setImageFile(file);
const reader = new FileReader();
reader.onload = async (e) => {
const imageData = e.target?.result as string;
setImageData(imageData);
const finalImage = imageData.split(",")[1];
setImage(finalImage);
};
reader.readAsDataURL(file);
};
const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log("Handling");
const file = e.target.files && e.target.files[0];
if (file) {
processFile(file);
}
};
const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
};
const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
const files = e.dataTransfer.files;
if (files && files.length > 0) {
processFile(files[0]);
e.dataTransfer.clearData();
}
};
const handleAreaClick = () => {
// @ts-ignore
fileInputRef.current.click();
};
Pass your image from input or drag and drop to captureUploaded()
as blob
const handleCrop = async () => {
const data = await veryfiLens?.captureUploaded(imageFile as unknown as Blob);
setImage(data);
setIsEditing(true);
};
- Add drag and drop area to your component
return (
<div className="relative flex flex-col justify-center items-center h-full w-full">
<div className="absolute right-5 top-0">
<GoHomeButton setter={setIsUpload} />
</div>
{image && (
<div className="absolute top-5 flex flex-col h-full">
<img
className="rounded-md bg-slate-200 shadow-md p-4 m-2 max-h-[65vh] max-w-[400px] overflow-auto"
src={imageData}
alt="Receipt"
/>
<button
className="submitButton text-white font-bold p-1 m-1 z-50 rounded-sm"
onClick={handleCrop}
>
Submit
</button>
</div>
)}
<div className="absolute bottom-28 flex bg-slate-200 rounded-md shadow-md p-4 m-2 gap-1 justify-center items-center h-[70px] mt-4 border-dashed border-[2px] border-green-500">
<div
onDragOver={handleDragOver}
onDrop={handleDrop}
onClick={handleAreaClick}
className="drop-area p-4 m-2 text-center cursor-pointer"
>
<p>Drag and drop your image here, or click to select a file</p>
<input
ref={fileInputRef}
type="file"
accept="image/*"
onChange={handleImageChange}
className="hidden"
/>
</div>
</div>
</div>
);
- Add your credentials from Authentification to your component (Recommended to use
.env
file to store sensetive data)
const PROCESS_DOCUMENT_URL = "https://lens.veryfi.com/rest/process"; or "https://lens-dev.veryfi.com/rest/process";
const CLIENT_ID = "YOUR_CLIENT_ID";
const API_KEY = "YOUR_API_KEY";
const USERNAME = "your.username";
They are required for initialization of Lens For Web and for processing of resulting image
- Import SDK
import VeryfiLens from 'veryfi-lens-wasm'
const VeryfiLens = require('veryfi-lens-wasm').default
- Add a function to validate partner and receive session token (it is necessary to initialize Lens)
async function validatePartner(clientId) {
const validateUrl = "https://lens.veryfi.com/rest/validate_partner";
try {
const requestOptions = {
method: "POST",
headers: { "CLIENT-ID": clientId },
};
const response = await fetch(validateUrl, requestOptions);
const data = await response.json();
return data.session;
} catch (error) {
console.error("Error validating partner:", error);
return null;
}
}
- Initialize Lens
const [VeryfiLens, setVeryfiLens] = useState(null);
const [imageData, setImageData] = useState("");
const fileInputRef = useRef(null);
const CLIENT_ID = process.env.NEXT_PUBLIC_CLIENT_ID;
useEffect(() => {
const startWasm = async () => {
if (typeof window !== "undefined") {
const lens = require("veryfi-lens-wasm").default;
lens.setUserAgent(navigator.userAgent);
setDeviceData(lens.getDeviceData());
await lens.initUploadWasm(sessionToken, CLIENT_ID);
setVeryfiLens(lens);
}
};
startWasm();
}, []);
- Add functions to handle user's actions with drag and drop area
const processFile = (file: any) => {
setImageFile(file);
const reader = new FileReader();
reader.onload = async (e) => {
const imageData = e.target.result as string;
setImageData(imageData);
const finalImage = imageData.split(",")[1];
setImage(finalImage);
};
reader.readAsDataURL(file);
};
const handleImageChange = (e) => {
console.log("Handling");
const file = e.target.files && e.target.files[0];
if (file) {
processFile(file);
}
};
const handleDragOver = (e) => {
e.preventDefault();
e.stopPropagation();
};
const handleDrop = (e) => {
e.preventDefault();
e.stopPropagation();
const files = e.dataTransfer.files;
if (files && files.length > 0) {
processFile(files[0]);
e.dataTransfer.clearData();
}
};
const handleAreaClick = () => {
fileInputRef.current.click();
};
Pass your image from input or drag and drop to captureUploaded()
as blob
const handleCrop = async () => {
const data = await VeryfiLens.captureUploaded(imageFile);
setImage(data);
setIsEditing(true);
};
- Add drag and drop area to your component
return (
<div className="relative flex flex-col justify-center items-center h-full w-full">
<div className="absolute right-5 top-0">
<GoHomeButton setter={setIsUpload} />
</div>
{image && (
<div className="absolute top-5 flex flex-col h-full">
<img
className="rounded-md bg-slate-200 shadow-md p-4 m-2 max-h-[65vh] max-w-[400px] overflow-auto"
src={imageData}
alt="Receipt"
/>
<button
className="submitButton text-white font-bold p-1 m-1 z-50 rounded-sm"
onClick={handleCrop}
>
Submit
</button>
</div>
)}
<div className="absolute bottom-28 flex bg-slate-200 rounded-md shadow-md p-4 m-2 gap-1 justify-center items-center h-[70px] mt-4 border-dashed border-[2px] border-green-500">
<div
onDragOver={handleDragOver}
onDrop={handleDrop}
onClick={handleAreaClick}
className="drop-area p-4 m-2 text-center cursor-pointer"
>
<p>Drag and drop your image here, or click to select a file</p>
<input
ref={fileInputRef}
type="file"
accept="image/*"
onChange={handleImageChange}
className="hidden"
/>
</div>
</div>
</div>
);
};
- Import Lens to your app.component.ts
import VeryfiLens from 'veryfi-lens-wasm'
- Add your credentials
const PROCESS_DOCUMENT_URL = "https://lens.veryfi.com/rest/process"; or "https://lens-dev.veryfi.com/rest/process";
CLIENT_ID = "YOUR_CLIENT_ID";
API_KEY = "YOUR_API_KEY";
USERNAME = "your.username"
- Add function to validate client and receive session token (it is necessary to initialize Lens)
async getVeryfiSession(CLIENT_ID: string) {
return await axios
.post(
this.VALIDATE_URL,
{},
{
headers: {
'CLIENT-ID': CLIENT_ID,
},
}
)
.then((response) => {
console.log(response.data.session);
this.session = response.data.session;
})
.catch((error) => error);
}
- You can call it in
ngOnInit
lifecycle hook (together withgetDeviceData()
which is required to send an image to our backend)
async ngOnInit() {
this.getVeryfiSession(this.CLIENT_ID);
this.deviceData = await VeryfiLens.getDeviceData();
}
- Add drag and drop area to your app.component.html
//TailwindCSS styles, you can use your own
<div *ngIf="isUpload && !base64Image"
class="absolute bottom-28 left-[35vw] w-[30vw] flex bg-slate-200 rounded-md shadow-md p-4 m-2 gap-1 justify-center items-center h-[70px] mt-4 border-dashed border-[2px] border-green-500"
(drop)="onDrop($event)"
(dragover)="onDragOver($event)"
(dragleave)="onDragLeave($event)"
(click)="triggerInput(fileInput)"
>
Drag and Drop or Click to Upload
<input
#fileInput
type="file"
accept="image/*"
(change)=handleImageChange($event)
class="hidden"
/>
</div>
- Initialize Lens
async initDragAndDrop(): Promise<void> {
setTimeout(() => { //use if Lens load before your layout renders (ERROR TypeError: Cannot read properties of null (reading 'appendChild'))
await VeryfiLens.initUploadWasm(this.session, this.CLIENT_ID);
}, 1000)
}
- Add functions to handle user's actions with drag and drop area
onDragOver(event: DragEvent): void {
event.preventDefault();
event.stopPropagation();
}
onDragLeave(event: DragEvent): void {
event.preventDefault();
event.stopPropagation();
}
onDrop(event: DragEvent): void {
event.preventDefault();
event.stopPropagation();
const files = event.dataTransfer?.files;
if (files && files.length > 0) {
this.handleFile(files[0]);
}
}
triggerInput(fileInput: HTMLInputElement): void {
fileInput.click();
}
handleFile(file: File): void {
const reader = new FileReader();
reader.onload = (e: any) => {
this.base64Image = e.target.result;
};
reader.readAsDataURL(file);
}
processFile = (file: any) => {
this.imageFile = file
const reader = new FileReader();
reader.onload = async (e) => {
let imgData = e.target?.result as string;
this.imageData = imgData;
const finalImage = this.imageData.split(",")[1];
this.base64Image = finalImage;
};
reader.readAsDataURL(file);
};
handleImageChange = (e: any) => {
console.log("Handling");
const file = e.target.files && e.target.files[0];
console.log(file, 'file')
if (file) {
this.processFile(file);
}
};
Pass your image from input or drag and drop area to captureUploaded()
as blob
handleUploadCrop = async () => {
const data = await VeryfiLens.captureUploaded(
this.imageFile as unknown as Blob
);
this.setImage(data);
this.setIsEditing(true);
this.croppedImage = data;
};
- Set process url and your credentials from Authentification in your component or in your
.env
file
const PROCESS_DOCUMENT_URL = "https://lens.veryfi.com/rest/process"; or "https://lens-dev.veryfi.com/rest/process";
const CLIENT_ID = "YOUR_CLIENT_ID";
const API_KEY = "YOUR_API_KEY";
const USERNAME = "your.username";
- Add function to validate client and receive session token (it is necessary to initialize Lens)
async function validatePartner(clientId) {
const validateUrl = "https://lens.veryfi.com/rest/validate_partner";
try {
const requestOptions = {
method: "POST",
headers: { "CLIENT-ID": clientId },
};
const response = await fetch(validateUrl, requestOptions);
const data = await response.json();
return data.session;
} catch (error) {
console.error("Error validating partner:", error);
return null;
}
}
Call it
const sessionToken = validatePartner(CLIENT_ID)
Import Lens to your component inside
onMount
onMount(async () => {
const module = await import('veryfi-lens-wasm');
VeryfiLens = module.default;
})
Call
const deviceData = await VeryfiLens.getDeviceData()
(Is reqiured to send an image to our backend)Choose one of the Lens Flavors and Initialize (Pass your
sessionToken
andCLIENT_ID
)
- Add Drag and Drop area to your component (Styles in example are in TailwindCSS, you can use your own)
<div
bind:this={dropArea}
role="button"
aria-label="Upload image area, click or drop an image here"
tabindex="0"
class="absolute bottom-28 flex bg-slate-200 rounded-md shadow-md p-4 m-2 gap-1 justify-center items-center h-[70px] mt-4 border-dashed border-[2px] border-green-500"
on:dragover={handleDragOver}
on:drop={handleDrop}
on:keydown={handleKeyPress}
on:click={handleAreaClick}
>
<div class="drop-area p-4 m-2 text-center cursor-pointer">
<p>Drag and drop your image here, or click to select a file</p>
<input
bind:this={fileInput}
class="absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer"
type="file"
accept="image/*"
on:change={handleImageChange}
on:click={handleFileInputClick}
/>
</div>
- Initialize Lens and add event listeners to drag and drop area (You can do it in
onMount
right after import)
onMount(async () => {
VeryfiLens.initUploadWasm(sessionToken.session, CLIENT_ID);
// Drag and Drop Events
dropArea.addEventListener("dragover", handleDragOver);
dropArea.addEventListener("drop", handleDrop);
});
- Add functions to take care of user's actions
const handleImageChange = (event) => {
processFile(event.target.files[0]);
};
const handleAreaClick = () => {
fileInput.click();
};
const processFile = (file) => {
if (file) {
imageFile = file;
const reader = new FileReader();
reader.onload = async (e) => {
imageData = e.target.result;
const finalImage = imageData.split(",")[1];
image = finalImage;
};
reader.readAsDataURL(file);
}
};
const handleDragOver = (e) => {
e.preventDefault();
e.stopPropagation();
};
const handleDrop = (e) => {
e.preventDefault();
e.stopPropagation();
const files = e.dataTransfer.files;
if (files && files.length > 0) {
processFile(files[0]);
e.dataTransfer.clearData();
}
};
const handleKeyPress = (e) => {
if (e.key === "Enter") {
handleCrop();
}
};
const handleFileInputClick = (event) => {
event.stopPropagation(); // Prevent the click from bubbling up
};
- Add crop function (Pass it a blob with users image, it will return cropped image in base64)
const handleCrop = async () => {
const data = await VeryfiLens?.captureUploaded(imageFile);
image = data;
imageData = `data:image/png;base64,${data}`;
};