OUTLOOK - Email e Calendário Microsoft
O que é este Node?
O OUTLOOK é o node responsável por integrar com o Microsoft Outlook permitindo enviar emails, buscar mensagens e criar eventos de calendário diretamente dos seus flows.
Por que este Node existe?
Automatizar comunicação por email é essencial para produtividade. O OUTLOOK existe para:
- Email automático: Enviar emails de confirmação, notificações e follow-ups
- Leitura de emails: Buscar e processar emails recebidos
- Agendamento: Criar eventos de calendário automaticamente
- Notificações de equipe: Avisar colaboradores sobre eventos importantes
- Integração corporativa: Conectar WhatsApp com ambiente Microsoft 365
Como funciona internamente?
Quando o OUTLOOK é executado, o sistema:
- Autentica usando access token do Microsoft Graph API
- Identifica operação (sendMail, getMails, createEvent)
- Conecta à API do Microsoft Graph v1.0
- Executa operação com os dados fornecidos
- Retorna resultado com confirmação ou dados
- Se erro: Loga e lança exceção
Código interno (productivity-executors.service.ts:253-356):
async executeOutlook(data: any, variables: Record<string, any>): Promise<any> {
try {
this.logger.log('📧 [OUTLOOK] Executing operation');
const graphApiUrl = 'https://graph.microsoft.com/v1.0';
const headers = {
Authorization: `Bearer ${data.accessToken}`,
'Content-Type': 'application/json',
};
switch (data.operation) {
case 'sendMail':
const sendMailUrl = `${graphApiUrl}/me/sendMail`;
await firstValueFrom(
this.httpService.post(sendMailUrl,
{
message: {
subject: data.subject,
body: {
contentType: data.bodyType || 'Text',
content: data.body,
},
toRecipients: data.to.map((email: string) => ({
emailAddress: { address: email },
})),
ccRecipients: data.cc?.map((email: string) => ({
emailAddress: { address: email },
})) || [],
attachments: data.attachments?.map((att: any) => ({
'@odata.type': '#microsoft.graph.fileAttachment',
name: att.name,
contentType: att.contentType,
contentBytes: att.content,
})) || [],
},
},
{ headers }
)
);
return {
success: true,
message: 'Email sent successfully',
};
case 'getMails':
const getMailsUrl = `${graphApiUrl}/me/messages?$top=${data.limit || 10}&$orderby=receivedDateTime desc`;
const getMailsResponse = await firstValueFrom(
this.httpService.get(getMailsUrl, { headers })
);
return {
success: true,
emails: getMailsResponse.data.value.map((email: any) => ({
id: email.id,
subject: email.subject,
from: email.from?.emailAddress?.address,
receivedDateTime: email.receivedDateTime,
bodyPreview: email.bodyPreview,
hasAttachments: email.hasAttachments,
})),
};
case 'createEvent':
const createEventUrl = `${graphApiUrl}/me/events`;
const createEventResponse = await firstValueFrom(
this.httpService.post(createEventUrl,
{
subject: data.subject,
body: {
contentType: 'HTML',
content: data.body || '',
},
start: {
dateTime: data.startDateTime,
timeZone: data.timeZone || 'America/Sao_Paulo',
},
end: {
dateTime: data.endDateTime,
timeZone: data.timeZone || 'America/Sao_Paulo',
},
location: {
displayName: data.location,
},
attendees: data.attendees?.map((email: string) => ({
emailAddress: { address: email },
type: 'required',
})) || [],
},
{ headers }
)
);
return {
success: true,
eventId: createEventResponse.data.id,
webLink: createEventResponse.data.webLink,
};
default:
throw new Error(`Unknown Outlook operation: ${data.operation}`);
}
} catch (error) {
this.logger.error('Outlook execution error:', error);
throw error;
}
}
Quando você DEVE usar este Node?
Use OUTLOOK quando precisar automatizar email e agenda:
Casos de uso:
- Confirmação de pedido: Enviar email automático após compra
- Agendar reunião: Criar evento no calendário com convite
- Follow-up automático: Enviar lembretes por email
- Notificar equipe: Avisar sobre novos tickets ou tarefas
- Buscar mensagens: Verificar emails importantes automaticamente
- Anexar documentos: Enviar propostas e contratos por email
Quando NÃO usar OUTLOOK:
- Marketing em massa: Use MAILCHIMP ou similar
- Chat em tempo real: Use WhatsApp diretamente
- SMS: Use node específico de SMS
Parâmetros Detalhados
operation (string, obrigatório)
O que é: Define qual operação será executada no Outlook.
Valores possíveis:
- sendMail: Enviar email
- getMails: Buscar emails recebidos
- createEvent: Criar evento no calendário
accessToken (string, obrigatório)
O que é: Token de acesso do Microsoft Graph API.
Como obter: Configure aplicação no Azure AD e obtenha via OAuth2.
subject (string, obrigatório para sendMail/createEvent)
O que é: Assunto do email ou título do evento.
Flow completo para testar:
{
"name": "Teste OUTLOOK - Enviar Email",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Email Destinatário",
"parameters": {
"message": "Email do destinatário:",
"variable": "email_destino"
}
}
},
{
"id": "input_2",
"type": "input",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Mensagem",
"parameters": {
"message": "Digite a mensagem:",
"variable": "mensagem"
}
}
},
{
"id": "outlook_1",
"type": "outlook",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Enviar Email",
"parameters": {
"operation": "sendMail",
"to": ["{{email_destino}}"],
"subject": "Mensagem via Lumina Flow",
"body": "{{mensagem}}\n\nEnviado automaticamente pelo Lumina Flow Builder",
"bodyType": "Text",
"accessToken": "{{microsoft_access_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Email enviado para {{email_destino}}!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "input_2" },
{ "source": "input_2", "target": "outlook_1" },
{ "source": "outlook_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
to (array, obrigatório para sendMail)
O que é: Array com endereços de email dos destinatários.
Exemplo: ["cliente@empresa.com", "gestor@empresa.com"]
body (string, obrigatório para sendMail/createEvent)
O que é: Corpo do email ou descrição do evento.
bodyType (string, opcional)
O que é: Formato do corpo da mensagem.
Valores: "Text" ou "HTML" (padrão: Text)
cc (array, opcional)
O que é: Array com endereços de email para cópia (CC).
attachments (array, opcional)
O que é: Array de anexos do email.
Formato:
[
{
"name": "arquivo.pdf",
"contentType": "application/pdf",
"content": "base64_encoded_content"
}
]
startDateTime e endDateTime (string, obrigatório para createEvent)
O que é: Data/hora de início e fim do evento no formato ISO 8601.
Exemplo: "2025-01-20T14:00:00"
Flow completo para testar:
{
"name": "Teste OUTLOOK - Criar Evento",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Título da Reunião",
"parameters": {
"message": "Título da reunião:",
"variable": "titulo_reuniao"
}
}
},
{
"id": "date_1",
"type": "date",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Data",
"parameters": {
"message": "Data da reunião (DD/MM/YYYY):",
"variable": "data_reuniao"
}
}
},
{
"id": "outlook_1",
"type": "outlook",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Agendar Reunião",
"parameters": {
"operation": "createEvent",
"subject": "{{titulo_reuniao}}",
"body": "Reunião agendada via WhatsApp",
"startDateTime": "{{data_reuniao}}T14:00:00",
"endDateTime": "{{data_reuniao}}T15:00:00",
"timeZone": "America/Sao_Paulo",
"location": "Sala de Reuniões",
"attendees": ["equipe@empresa.com"],
"accessToken": "{{microsoft_access_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Reunião agendada!\n\n📅 {{titulo_reuniao}}\n🕐 {{data_reuniao}} às 14:00\n\n🔗 {{outlook_1.webLink}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "date_1" },
{ "source": "date_1", "target": "outlook_1" },
{ "source": "outlook_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
limit (number, opcional para getMails)
O que é: Número máximo de emails a retornar (padrão: 10).
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| operation | string | Sim | sendMail, getMails, createEvent |
| accessToken | string | Sim | Token Microsoft Graph API |
| to | array | Sim* | Destinatários (para sendMail) |
| subject | string | Sim* | Assunto/título (para sendMail, createEvent) |
| body | string | Sim* | Corpo do email/evento |
| bodyType | string | Não | Text ou HTML (padrão: Text) |
| cc | array | Não | Cópia (CC) |
| attachments | array | Não | Anexos do email |
| limit | number | Não | Limite de emails (padrão: 10) |
| startDateTime | string | Sim* | Início do evento (ISO 8601) |
| endDateTime | string | Sim* | Fim do evento (ISO 8601) |
| timeZone | string | Não | Fuso horário (padrão: America/Sao_Paulo) |
| location | string | Não | Local do evento |
| attendees | array | Não | Participantes do evento |
*Obrigatório dependendo da operação
Exemplo 1: Confirmação de Pedido por Email
Objetivo: Enviar email automático com detalhes do pedido após conclusão.
JSON para Importar
{
"name": "Confirmação de Pedido - Outlook",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Número do Pedido",
"parameters": {
"message": "Número do pedido:",
"variable": "numero_pedido"
}
}
},
{
"id": "email_1",
"type": "email",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Email Cliente",
"parameters": {
"message": "Email do cliente:",
"variable": "email_cliente"
}
}
},
{
"id": "number_1",
"type": "number",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Valor",
"parameters": {
"message": "Valor do pedido:",
"variable": "valor_pedido",
"decimals": 2
}
}
},
{
"id": "outlook_1",
"type": "outlook",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Enviar Confirmação",
"parameters": {
"operation": "sendMail",
"to": ["{{email_cliente}}"],
"cc": ["vendas@empresa.com"],
"subject": "Confirmação de Pedido #{{numero_pedido}}",
"bodyType": "HTML",
"body": "<h2>Pedido Confirmado!</h2><p>Olá,</p><p>Seu pedido foi recebido com sucesso:</p><ul><li><strong>Número:</strong> {{numero_pedido}}</li><li><strong>Valor:</strong> R$ {{valor_pedido}}</li><li><strong>Data:</strong> {{timestamp}}</li></ul><p>Entraremos em contato em breve.</p><p>Atenciosamente,<br>Equipe de Vendas</p>",
"accessToken": "{{microsoft_access_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Pedido #{{numero_pedido}} confirmado!\n\n📧 Email enviado para {{email_cliente}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1300, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "email_1" },
{ "source": "email_1", "target": "number_1" },
{ "source": "number_1", "target": "outlook_1" },
{ "source": "outlook_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Número do pedido:
Usuário: 12345
Sistema: Email do cliente:
Usuário: cliente@email.com
Sistema: Valor do pedido:
Usuário: 250.50
Sistema: ✅ Pedido #12345 confirmado!
📧 Email enviado para cliente@email.com
Exemplo 2: Agendar Reunião Automática
Objetivo: Criar evento no calendário com base em solicitação via WhatsApp.
JSON para Importar
{
"name": "Agendar Reunião - Outlook",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Boas-vindas",
"parameters": {
"message": "📅 Vamos agendar sua reunião!"
}
}
},
{
"id": "input_1",
"type": "input",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Assunto",
"parameters": {
"message": "Qual o assunto da reunião?",
"variable": "assunto"
}
}
},
{
"id": "date_1",
"type": "date",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Data",
"parameters": {
"message": "Qual a data? (DD/MM/YYYY)",
"variable": "data"
}
}
},
{
"id": "input_2",
"type": "input",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Horário",
"parameters": {
"message": "Qual o horário? (HH:MM)",
"variable": "horario"
}
}
},
{
"id": "outlook_1",
"type": "outlook",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Criar Evento",
"parameters": {
"operation": "createEvent",
"subject": "{{assunto}}",
"body": "Reunião agendada via WhatsApp com {{contact_name}}",
"startDateTime": "{{data}}T{{horario}}:00",
"endDateTime": "{{data}}T{{horario + 1}}:00",
"timeZone": "America/Sao_Paulo",
"location": "Online",
"attendees": ["{{contact_email}}", "equipe@empresa.com"],
"accessToken": "{{microsoft_access_token}}"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1300, "y": 100 },
"data": {
"label": "Confirmação",
"parameters": {
"message": "✅ Reunião agendada!\n\n📅 {{assunto}}\n🗓️ {{data}}\n🕐 {{horario}}\n📍 Online\n\n🔗 Link do evento:\n{{outlook_1.webLink}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1500, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "input_1" },
{ "source": "input_1", "target": "date_1" },
{ "source": "date_1", "target": "input_2" },
{ "source": "input_2", "target": "outlook_1" },
{ "source": "outlook_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: 📅 Vamos agendar sua reunião!
Sistema: Qual o assunto da reunião?
Usuário: Apresentação do Projeto
Sistema: Qual a data? (DD/MM/YYYY)
Usuário: 20/01/2025
Sistema: Qual o horário? (HH:MM)
Usuário: 14:00
Sistema: ✅ Reunião agendada!
📅 Apresentação do Projeto
🗓️ 20/01/2025
🕐 14:00
📍 Online
🔗 Link do evento:
https://outlook.office365.com/calendar/...
Resposta do Node
Operação SEND_MAIL:
{
"success": true,
"message": "Email sent successfully"
}
Operação GET_MAILS:
{
"success": true,
"emails": [
{
"id": "AAMkAGI2T...",
"subject": "Re: Proposta Comercial",
"from": "cliente@empresa.com",
"receivedDateTime": "2025-01-15T10:30:00Z",
"bodyPreview": "Olá, gostaria de mais informações...",
"hasAttachments": false
}
]
}
Operação CREATE_EVENT:
{
"success": true,
"eventId": "AAMkAGI2T...",
"webLink": "https://outlook.office365.com/calendar/deeplink/..."
}
Boas Práticas
✅ SIM: - Use HTML para emails mais ricos e profissionais - Sempre inclua informações claras no assunto - Adicione CC para manter equipe informada - Use timeZone correto para eventos - Valide emails antes de enviar
❌ NÃO: - Não envie spam ou emails não solicitados - Não exponha access token em logs - Não esqueça de tratar erros de envio - Não crie eventos sem confirmar disponibilidade
Dicas
💡 Templates HTML: Crie templates de email reutilizáveis para consistência
💡 Anexos: Converta arquivos para base64 antes de anexar
💡 Fuso horário: Use sempre America/Sao_Paulo ou ajuste conforme necessário
💡 Follow-up: Combine com DELAY para envios programados
💡 Integração: Use com GOOGLE SHEETS para registrar emails enviados
Próximo Node
→ GMAIL - Alternativa Google para emails → GOOGLE CALENDAR - Calendário do Google → MAILCHIMP - Email marketing