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 os Serviços Cognitivos do Azure
Os Serviços Cognitivos do Azure são 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 abrangerá a ligação aos Serviços Cognitivos do Azure 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 a API do serviço de Inteligência de Documentos dos Serviços Cognitivos do Azure. Terá de criar um recurso de IA do 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 a API do serviço de Inteligência de Documentos dos Serviços Cognitivos do Azure
Para utilizar as APIs de Inteligência de Documentos dos Serviços Cognitivos do Azure, tem de criar um recurso Multi-Service ou Document Intelligence para o Serviço de IA do Azure. Veja os seguintes tutoriais para criar o recurso:
- Início Rápido: Criar um recurso multiserviços para serviços de IA do Azure
- 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 dos Serviços Cognitivos do Azure. 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 na resposta dos Serviços Cognitivos do Azure:
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.