O Sertão será Cloud

TimerTrigger no Azure Functions App V3 com TypeScript

No mundo das aplicações modernas, a capacidade de executar tarefas agendadas é crucial para manter sistemas operacionais eficientes e sem interrupções. O Azure Functions App oferece uma solução poderosa e flexível para isso através do TimerTrigger. Neste artigo, vamos explorar como o TimerTrigger funciona no Azure Functions App utilizando TypeScript e como você pode aplicá-lo para resolver problemas do dia a dia com exemplos práticos.

O Que São Triggers?

Triggers são componentes integrados do Azure Functions que escutam eventos ou condições específicos. Quando esses eventos ou condições são atendidos, o trigger é ativado e a função associada é executada. O Azure Functions suporta uma variedade de triggers, permitindo que você responda a diferentes tipos de eventos.

Tipos de Triggers

  1. HTTP Trigger: Executa uma função em resposta a uma solicitação HTTP. Útil para criar APIs ou webhooks.
  2. Timer Trigger: Executa uma função em um horário ou intervalo agendado. Ideal para tarefas periódicas como limpeza de dados ou relatórios agendados.
  3. Blob Trigger: Executa uma função quando um novo blob é detectado ou um blob existente é atualizado no Azure Blob Storage. Útil para processar arquivos à medida que são enviados.
  4. Queue Trigger: Executa uma função quando uma nova mensagem é adicionada a uma fila do Azure Storage. Útil para processar tarefas em segundo plano ou mensagens.
  5. Event Grid Trigger: Executa uma função em resposta a eventos publicados em um Azure Event Grid. Útil para lidar com eventos de vários serviços Azure ou eventos personalizados.
  6. Service Bus Trigger: Executa uma função quando uma nova mensagem é recebida em uma fila ou tópico do Azure Service Bus. Útil para aplicativos baseados em mensagens.

Cada tipo de trigger tem seus casos de uso e configurações específicos, permitindo que você adapte suas funções para responder a vários eventos de forma eficiente.

O que é o TimerTrigger detalhadamente?

O TimerTrigger é um tipo de gatilho que permite que você execute funções em intervalos regulares ou em horários específicos. É ideal para tarefas que precisam ser executadas periodicamente, como limpeza de dados, envio de relatórios, ou atualizações de cache.

Ao usar o TimerTrigger, você define uma expressão CRON para agendar a execução da função. O Azure Functions App interpreta essa expressão e aciona a função conforme a programação estabelecida.

Configurando o TimerTrigger

Para começar, você precisa ter um projeto Azure Functions configurado para TypeScript. Vamos passar pelos passos básicos para configurar.

1. Criando um Novo Projeto

Primeiro, crie um novo projeto Azure Functions com suporte para TypeScript:

func init MyFunctionApp --typescript
cd MyFunctionApp
func new --template "TimerTrigger" --name MyTimerFunction

Isso criará um novo projeto com uma função TimerTrigger básica.

2. Configurando a Função

No arquivo function.json da função criada, você encontrará a configuração básica do TimerTrigger:


{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */5 * * * *"
}
]
}

A expressão 0 */5 * * * * indica que a função será executada a cada 5 minutos.

3. Implementando a Função em TypeScript

No arquivo index.ts, você encontrará um exemplo básico de implementação:

import { AzureFunction, Context } from "@azure/functions";

const timerTrigger: AzureFunction = async function (context: Context, myTimer: any): Promise<void> {
const currentTime = new Date().toISOString();
context.log(`Timer trigger function ran at ${currentTime}`);
};

export default timerTrigger;

Esse código loga a hora em que a função é executada.

Exemplos de Uso

Aqui estão cinco exemplos de como você pode usar o TimerTrigger para diferentes tarefas, aplicando boas práticas de codificação:

1. Limpeza de Dados Antigos

Este exemplo realiza a limpeza de dados antigos de uma tabela em um banco de dados. Vamos supor que você está utilizando o MongoDB e deseja remover documentos mais antigos que 30 dias.

import { AzureFunction, Context } from "@azure/functions";
import { MongoClient } from "mongodb";

const uri = process.env["MONGO_DB_CONNECTION_STRING"];
const client = new MongoClient(uri);

/**
* Cleans up old documents from a MongoDB collection.
*
* @param context - The Azure Function context.
* @param myTimer - The timer object provided by the TimerTrigger.
*/
const timerTrigger: AzureFunction = async function (context: Context, myTimer: any): Promise<void> {
const currentTime = new Date();
const cutoffDate = new Date(currentTime.setDate(currentTime.getDate() - 30));

try {
await client.connect();
const database = client.db("mydatabase");
const collection = database.collection("mycollection");

const result = await collection.deleteMany({ createdAt: { $lt: cutoffDate } });
context.log(`Deleted ${result.deletedCount} old documents.`);
} catch (err) {
context.log(`Error cleaning old data: ${err.message}`);
} finally {
await client.close();
}
};

export default timerTrigger;

2. Envio de Relatórios Diários

Neste exemplo, vamos enviar um relatório diário por e-mail. Utilizaremos a biblioteca nodemailer para o envio de e-mails.

import { AzureFunction, Context } from "@azure/functions";
import nodemailer from "nodemailer";

const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env["EMAIL_USER"],
pass: process.env["EMAIL_PASS"],
},
});

/**
* Sends a daily report via email.
*
* @param context - The Azure Function context.
* @param myTimer - The timer object provided by the TimerTrigger.
*/
const timerTrigger: AzureFunction = async function (context: Context, myTimer: any): Promise<void> {
const mailOptions = {
from: process.env["EMAIL_USER"],
to: "recipient@example.com",
subject: "Daily Report",
text: "Here is your daily report...",
};

try {
await transporter.sendMail(mailOptions);
context.log("Daily report sent successfully.");
} catch (err) {
context.log(`Error sending daily report: ${err.message}`);
}
};

export default timerTrigger;

3. Atualização de Cache

Aqui, vamos atualizar o cache de uma aplicação, simulando a atualização de uma chave de cache em um serviço Redis.

import { AzureFunction, Context } from "@azure/functions";
import redis from "redis";

const client = redis.createClient({ url: process.env["REDIS_URL"] });

/**
* Updates a cache key in a Redis service.
*
* @param context - The Azure Function context.
* @param myTimer - The timer object provided by the TimerTrigger.
*/
const timerTrigger: AzureFunction = async function (context: Context, myTimer: any): Promise<void> {
const cacheKey = "myCacheKey";
const cacheValue = "Updated cache value";

try {
await new Promise((resolve, reject) => {
client.set(cacheKey, cacheValue, (err) => {
if (err) reject(err);
resolve("Cache updated");
});
});
context.log("Cache updated successfully.");
} catch (err) {
context.log(`Error updating cache: ${err.message}`);
}
};

export default timerTrigger;

4. Backup de Dados

Este exemplo realiza um backup de dados de um banco de dados para um serviço de armazenamento, como o Azure Blob Storage.

import { AzureFunction, Context } from "@azure/functions";
import { BlobServiceClient } from "@azure/storage-blob";
import { MongoClient } from "mongodb";

const mongoUri = process.env["MONGO_DB_CONNECTION_STRING"];
const blobServiceClient = BlobServiceClient.fromConnectionString(process.env["AZURE_STORAGE_CONNECTION_STRING"]);

const client = new MongoClient(mongoUri);

/**
* Backs up data from a MongoDB collection to Azure Blob Storage.
*
* @param context - The Azure Function context.
* @param myTimer - The timer object provided by the TimerTrigger.
*/
const backupData: AzureFunction = async function (context: Context, myTimer: any): Promise<void> {
const currentTime = new Date().toISOString();
const containerClient = blobServiceClient.getContainerClient("backups");
const blobClient = containerClient.getBlockBlobClient(`backup-${currentTime}.json`);

try {
await client.connect();
const database = client.db("mydatabase");
const collection = database.collection("mycollection");
const data = await collection.find({}).toArray();

await blobClient.upload(JSON.stringify(data), Buffer.byteLength(JSON.stringify(data)));
context.log("Backup completed successfully.");
} catch (err) {
context.log(`Error during backup: ${err.message}`);
} finally {
await client.close();
}
};

export default backupData;

5. Verificação de Status do Sistema

Neste exemplo, vamos verificar o status de um serviço de API e logar o resultado.

import { AzureFunction, Context } from "@azure/functions";
import axios from "axios";

/**
* Checks the status of an API service and logs the result.
*
* @param context - The Azure Function context.
* @param myTimer - The timer object provided by the TimerTrigger.
*/
const checkSystemStatus: AzureFunction = async function (context: Context, myTimer: any): Promise<void> {
const apiUrl = "https://api.example.com/health";

try {
const response = await axios.get(apiUrl);
if (response.status === 200) {
context.log("System is up and running.");
} else {
context.log(`System returned status code ${response.status}.`);
}
} catch (err) {
context.log(`Error checking system status: ${err.message}`);
}
};

export default checkSystemStatus;

Conclusão

Os exemplos acima ilustram como o TimerTrigger do Azure Functions App pode ser utilizado em diversas situações do dia a dia, desde a limpeza de dados antigos até o envio de relatórios e backups. Cada exemplo é projetado para ser claro e direto, mantendo o código eficiente e fácil de manter. Ao implementar essas funções, você pode automatizar tarefas importantes e garantir que seu sistema opere de forma contínua e eficiente.