Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Utilizar Azure Serviços Cognitivos
Azure Serviços Cognitivos é um conjunto de APIs baseadas na cloud que pode utilizar em aplicações de IA e fluxos de dados. Fornece modelos pré-preparados que estão prontos a utilizar nas suas aplicações, sem necessidade de dados e sem preparação de modelos da sua parte. Podem ser facilmente integradas em aplicações através de interfaces REST HTTP.
Já aprendeu a utilizar webhooks com a aplicação para receber uma notificação sempre que um ficheiro existente é atualizado ou um novo ficheiro é carregado no tutorial Utilizar Webhooks. Este tutorial abordará a ligação com Azure Serviços Cognitivos para extrair dados de faturas.
Para configurar o processamento automático de IA com a sua aplicação do SharePoint atual após uma alteração no contentor, tem de seguir Utilizar Webhooks e, em seguida:
- Obtenha as alterações delta do contentor. Atualmente, pode receber a notificação sempre que houver alguma alteração no nosso contentor e irá agora obter os ficheiros que são adicionados ou atualizados.
- Chame Azure API do serviço de Inteligência de Documentos dos Serviços Cognitivos. Terá de criar um recurso de IA Azure para utilizar a API para extrair os campos de uma imagem e obter os ficheiros extraídos. Pode armazená-los conforme mostrado neste tutorial ou pode processá-los conforme quiser.
Dica
Para saber mais sobre as APIs do Microsoft Graph utilizadas neste tutorial, veja Registar alterações para uma Unidade, Obter um recurso DriveItem e Carregar ou substituir os conteúdos de um DriveItem.
Obter as alterações delta de um contentor
Abra GraphProvider.ts e implemente o método getDriveChanges para obter a lista de itens alterados:
public static async getDriveChanges(driveId: string): Promise<any[]> {
let changedItems: any[] = [];
const driveDeltaBasePath: string = `/drives/${driveId}/items/root/delta`;
let driveDeltaTokenParams: string = "";
let hasMoreChanges: boolean = true;
try{
do {
if (this.changeTokens.has(driveId)) {
driveDeltaTokenParams = `?token=${this.changeTokens.get(driveId)}`
}
const response = await this.graphClient.api(driveDeltaBasePath + driveDeltaTokenParams).get();
changedItems.push(...response.value);
if (response['@odata.nextLink']) {
const token = new URL(response['@odata.nextLink']).searchParams.get('token');
this.changeTokens.set(driveId, token);
} else {
hasMoreChanges = false;
const token = new URL(response['@odata.deltaLink']).searchParams.get('token');
this.changeTokens.set(driveId, token);
}
console.log(this.changeTokens.get(driveId));
} while (hasMoreChanges);
}
catch(err){
console.log(err);
}
return changedItems;
}
Implemente o método getDriveItem para obter um ficheiro a partir de um contentor:
public static async getDriveItem(driveId: string, itemId: string): Promise<any> {
return await this.graphClient.api(`/drives/${driveId}/items/${itemId}`).get();
}
Crie um novo ficheiro ReceiptProcessor.ts e implemente um método processDrive:
export abstract class ReceiptProcessor {
public static async processDrive(driveId: string): Promise<void> {
const changedItems = await GraphProvider.getDriveChanges(driveId);
for (const changedItem of changedItems) {
try {
const item = await GraphProvider.getDriveItem(driveId, changedItem.id);
const extension = this.getFileExtension(item.name);
if (this.SUPPORTED_FILE_EXTENSIONS.includes(extension.toLowerCase())) {
console.log(item.name);
const url = item["@microsoft.graph.downloadUrl"];
const receipt = await this.analyzeReceiptStream(await this.getDriveItemStream(url));
const receiptString = JSON.stringify(receipt, null, 2)
const fileName = this.getFileDisplayName(item.name) + "-extracted-fields.json";
const parentId = item.parentReference.id;
await GraphProvider.addDriveItem(driveId, parentId, fileName, receiptString);
}
} catch (error) {
console.log(error);
}
}
}
}
Neste momento, se reiniciar a aplicação juntamente com o túnel e a subscrição, deverá ver os ficheiros recentemente adicionados/atualizados listados na consola do .
Chamar Azure API do serviço de Inteligência de Documentos dos Serviços Cognitivos
Para utilizar o Azure APIs de Inteligência de Documentos dos Serviços Cognitivos, tem de criar um recurso multiserviços ou do Document Intelligence para Azure Serviço de IA. Veja os seguintes tutoriais para criar o recurso:
- Início Rápido: Criar um recurso de vários serviços para Azure serviços de IA
- Introdução ao Document Intelligence
Após este passo, deverá ter um ponto final e uma chave prontos a utilizar.
Agora, abra ReceiptProcessor.ts para criar o método dac para armazenar as credenciais dos Serviços Cognitivos do Azure:
private static dac = new DocumentAnalysisClient(
`${process.env["DAC_RESOURCE_ENDPOINT"]}`,
new AzureKeyCredential(`${process.env["DAC_RESOURCE_KEY"]}`)
);
Criar método getDriveItemStream.
private static async getDriveItemStream(url: string): Promise<Readable> {
const token = GraphProvider.graphAccessToken;
const config: AxiosRequestConfig = {
method: "get",
url: url,
headers: {
"Authorization": `Bearer ${token}`
},
responseType: 'stream'
};
const response = await axios.get<Readable>(url, config);
return response.data;
}
Crie um método analyzeReceiptStream para obter os campos OCR através do processamento Azure Serviços Cognitivos. Aqui estamos a utilizar o prebuilt-invoice modelo, mas podem ser escolhidos outros modelos:
private static async analyzeReceiptStream(stream: Readable): Promise<any> {
const poller = await this.dac.beginAnalyzeDocument("prebuilt-invoice", stream, {
onProgress: ({ status }) => {
console.log(`status: ${status}`);
},
});
const {
documents: [result] = [],
} = await poller.pollUntilDone();
const fields = result?.fields;
this.removeUnwantedFields(fields);
return fields;
}
Crie um método removeUnwantedFields para remover os campos indesejáveis no Azure resposta dos Serviços Cognitivos:
private static removeUnwantedFields(fields: any) {
for (const prop in fields) {
if (prop === 'boundingRegions' || prop === 'content' || prop === 'spans') {
delete fields[prop];
}
if (typeof fields[prop] === 'object') {
this.removeUnwantedFields(fields[prop]);
}
}
}
Por fim, abra GraphProvider.ts para adicionar o addDriveItem método no final da GraphProvider classe.
public static async addDriveItem(driveId: string, parentId: any, fileName: string, receiptString: string) {
await this.graphClient.api(`/drives/${driveId}/items/${parentId}:/${fileName}:/content`).put(receiptString);
}
Agora, reinicie a aplicação de demonstração e configure novamente o túnel com a subscrição ngrok e delta change no contentor.
Se adicionar/atualizar qualquer ficheiro (formatos suportados: JPEG, JPG, PNG, BMP, TIFF, PDF) neste contentor, deverá ver um novo ficheiro JSON criado e que contém os campos extraídos do ficheiro.