This workflow follows the HTTP Request → OpenAI recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Radar MB - Relat\u00f3rio Di\u00e1rio e PDF (22h)",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 22
}
]
}
},
"id": "schedule-22h",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT titulo_normalizado, veiculo, tipo_midia, texto_extraido, remote_jid \nFROM news_items \nWHERE data_hora_coleta >= CURRENT_DATE \nAND ignorar_contabilidade = false;",
"options": {}
},
"id": "db-buscar-materias",
"name": "Buscando as mat\u00e9rias do dia",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.4,
"position": [
200,
0
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const materias = $input.all();\n\nif (materias.length === 0) {\n return [{ json: { total: 0, publicadas: 0, nao_publicadas: 0, compilado_dia: \"Nenhuma mat\u00e9ria registrada hoje.\" } }];\n}\n\nlet compilado = \"\";\nlet countRadar = 0;\nlet countColeta = 0;\n\nconst idRadar = \"556195599538-1597070893@g.us\";\nconst idColeta = \"556191047689-1555547406@g.us\";\n\nmaterias.forEach((m, i) => {\n const jid = m.json.remote_jid;\n if (jid === idRadar) {\n countRadar++;\n } else if (jid === idColeta) {\n countColeta++;\n }\n \n compilado += `\\n[MAT\u00c9RIA ${i + 1}] Ve\u00edculo: ${m.json.veiculo} | T\u00edtulo: ${m.json.titulo_normalizado}\\nTexto: ${m.json.texto_extraido}\\n`;\n});\n\nreturn [{\n json: {\n total: materias.length,\n publicadas: countRadar,\n nao_publicadas: countColeta,\n compilado_dia: compilado\n }\n}];"
},
"id": "code-agrupador",
"name": "O Agrupador (Contador Exato)",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
400,
0
]
},
{
"parameters": {
"resource": "chat",
"model": "gpt-4o",
"options": {
"responseFormat": "json_object"
},
"prompt": {
"messages": [
{
"role": "system",
"content": "Voc\u00ea \u00e9 o Redator-Chefe de Intelig\u00eancia de M\u00eddia da Marinha do Brasil.\nLeia as mat\u00e9rias do dia e gere APENAS um objeto JSON estrito com os dados para o Relat\u00f3rio em PDF.\n\nRegras:\n1. Use exatamente os n\u00fameros de 'publicadas' e 'nao_publicadas' que o sistema informar. N\u00e3o altere.\n2. Para 'categorias', some as mat\u00e9rias lidas e divida nos valores (md_fa, sta, mb, outras, economia, internacional).\n3. O JSON deve ter exatamente este formato:\n\n{\n \"total_publicadas\": 0,\n \"total_nao_publicadas\": 0,\n \"categorias\": {\n \"md_fa\": 0,\n \"sta\": 0,\n \"mb\": 0,\n \"outras\": 0,\n \"economia\": 0,\n \"internacional\": 0\n },\n \"assunto_mais_pautado\": \"Tema dominante...\",\n \"sintese_nacional\": \"Dois par\u00e1grafos resumindo o cen\u00e1rio pol\u00edtico, defesa e economia do Brasil.\",\n \"sintese_internacional\": \"Dois par\u00e1grafos resumindo geopol\u00edtica e defesa no mundo.\",\n \"sintese_mb\": \"Um par\u00e1grafo avaliando se as men\u00e7\u00f5es \u00e0 MB foram positivas, neutras ou negativas.\",\n \"demandas\": [\n {\"assunto\": \"Tema da demanda\", \"veiculo\": \"Nome do ve\u00edculo\", \"jornalista\": \"Nome do jornalista (ou N/A)\"}\n ]\n}"
},
{
"role": "user",
"content": "=M\u00c9TRICAS EXATAS DO BANCO DE DADOS:\n- Total Publicadas (Radar): {{ $json.publicadas }}\n- Total N\u00e3o Publicadas (Coleta): {{ $json.nao_publicadas }}\n\nTEXTOS DO DIA:\n{{ $json.compilado_dia }}"
}
]
}
},
"id": "openai-json",
"name": "Criar Dados do PDF (IA)",
"type": "n8n-nodes-base.openAi",
"typeVersion": 1,
"position": [
600,
0
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const data = JSON.parse($input.item.json.message.content.replace(/\\x60\\x60\\x60json/g, '').replace(/\\x60\\x60\\x60/g, ''));\n\n// 1. Gera os gr\u00e1ficos via QuickChart.io\nconst chart1 = `https://quickchart.io/chart?c={type:'pie',data:{labels:['Publicadas','N\u00e3o Publicadas'],datasets:[{data:[${data.total_publicadas},${data.total_nao_publicadas}],backgroundColor:['%2300BFFF','%23FF0000']}]}}`;\nconst chart2 = `https://quickchart.io/chart?c={type:'pie',data:{labels:['MD/FA','STA','MB','OUTRAS','ECONOMIA','INTERNACIONAL'],datasets:[{data:[${data.categorias.md_fa || 0},${data.categorias.sta || 0},${data.categorias.mb || 0},${data.categorias.outras || 0},${data.categorias.economia || 0},${data.categorias.internacional || 0}],backgroundColor:['%23FFFF00','%2390EE90','%2300BFFF','%2332CD32','%23FF0000','%23800080']}]}}`;\n\n// 2. Monta a Tabela de Demandas\nlet tabelaS = '';\nif(data.demandas && data.demandas.length > 0) {\n tabelaS = data.demandas.map(d => `<tr><td style=\"border: 1px solid #ddd; padding: 8px;\">${d.assunto}</td><td style=\"border: 1px solid #ddd; padding: 8px;\">${d.veiculo}</td><td style=\"border: 1px solid #ddd; padding: 8px;\">${d.jornalista || '-'}</td></tr>`).join('');\n} else {\n tabelaS = '<tr><td colspan=\"3\" style=\"border: 1px solid #ddd; padding: 8px; text-align:center;\">Nenhuma demanda registrada hoje</td></tr>';\n}\n\n// 3. Estrutura o HTML id\u00eantico ao modelo\nconst html = `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <style>\n body { font-family: 'Arial', sans-serif; color: #333; line-height: 1.6; margin: 40px; }\n h1 { color: #003366; text-align: center; border-bottom: 2px solid #003366; padding-bottom: 10px; }\n h2 { color: #004080; margin-top: 30px; border-left: 5px solid #004080; padding-left: 10px; }\n .page-break { page-break-before: always; }\n table { width: 100%; border-collapse: collapse; margin-top: 20px; font-size: 14px; }\n th { background-color: #003366; color: white; padding: 10px; text-align: left; }\n .charts { text-align: center; margin-top: 40px; }\n img { max-width: 400px; height: auto; }\n .box { background-color: #f4f4f4; padding: 15px; border-radius: 5px; margin-bottom: 20px; }\n </style>\n</head>\n<body>\n <h1>RADAR DE NOT\u00cdCIAS</h1>\n <p style=\"text-align: center;\"><strong>Relat\u00f3rio Di\u00e1rio de Monitoramento de M\u00eddia</strong></p>\n <hr>\n \n <h2>1. Demandas para Acompanhamento</h2>\n <table>\n <tr><th>Assunto</th><th>Ve\u00edculo</th><th>Jornalista</th></tr>\n ${tabelaS}\n </table>\n\n <div class=\"page-break\"></div>\n\n <h2>2. Comparativos Di\u00e1rios</h2>\n <div class=\"charts\">\n <h3>Mat\u00e9rias Publicadas e N\u00e3o Publicadas</h3>\n <img src=\"${chart1}\" />\n <p><strong>Total Publicadas:</strong> ${data.total_publicadas} | <strong>Total N\u00e3o Publicadas:</strong> ${data.total_nao_publicadas}</p>\n </div>\n \n <div class=\"charts\">\n <h3>Publicadas e N\u00e3o Publicadas por Categoria</h3>\n <img src=\"${chart2}\" />\n </div>\n\n <div class=\"page-break\"></div>\n\n <h2>3. Considera\u00e7\u00f5es do Dia</h2>\n <div class=\"box\">\n <p><strong>Assunto mais pautado:</strong> ${data.assunto_mais_pautado}</p>\n </div>\n \n <h3>Nacionais</h3>\n <p>${data.sintese_nacional.replace(/\\n/g, '<br>')}</p>\n\n <h3>Internacionais</h3>\n <p>${data.sintese_internacional.replace(/\\n/g, '<br>')}</p>\n\n <h3>Marinha do Brasil</h3>\n <p>${data.sintese_mb.replace(/\\n/g, '<br>')}</p>\n</body>\n</html>\n`;\n\nreturn [{\n json: { success: true },\n binary: {\n data: {\n data: Buffer.from(html).toString('base64'),\n mimeType: 'text/html',\n fileName: 'Radar_Noticias.html'\n }\n }\n}];"
},
"id": "code-html-builder",
"name": "Gerador de HTML",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
800,
0
]
},
{
"parameters": {
"method": "POST",
"url": "http://mb_stirling_pdf:8080/api/v1/convert/html/pdf",
"sendBody": true,
"contentType": "multipart-form-data",
"bodyParameters": {
"parameters": [
{
"parameterType": "formBinaryData",
"name": "fileInput",
"inputDataFieldName": "data"
}
]
},
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"id": "stirling-html-pdf",
"name": "Stirling-PDF (Criar PDF)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
1000,
0
]
},
{
"parameters": {
"method": "POST",
"url": "={{ $env.EVOLUTION_SERVER_URL }}/message/sendMedia/coleta_mb",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.EVOLUTION_GLOBAL_KEY }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"number\": \"{{ $env.WHATSAPP_NUMERO_OFM }}\",\n \"mediatype\": \"document\",\n \"mimetype\": \"application/pdf\",\n \"fileName\": \"Radar_Noticias_Fechamento.pdf\",\n \"caption\": \"\ud83d\udcca *Radar de Not\u00edcias - Fechamento Di\u00e1rio*\\n\\nO relat\u00f3rio consolidado de hoje foi gerado com sucesso pelo sistema e segue em anexo em formato PDF.\\n\\n\u2693 _Automa\u00e7\u00e3o CCEM_\",\n \"media\": \"{{ $binary.data.data }}\"\n}",
"options": {}
},
"id": "evolution-send-pdf",
"name": "Enviar PDF (WhatsApp)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
1200,
0
]
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Buscando as mat\u00e9rias do dia",
"type": "main",
"index": 0
}
]
]
},
"Buscando as mat\u00e9rias do dia": {
"main": [
[
{
"node": "O Agrupador (Contador Exato)",
"type": "main",
"index": 0
}
]
]
},
"O Agrupador (Contador Exato)": {
"main": [
[
{
"node": "Criar Dados do PDF (IA)",
"type": "main",
"index": 0
}
]
]
},
"Criar Dados do PDF (IA)": {
"main": [
[
{
"node": "Gerador de HTML",
"type": "main",
"index": 0
}
]
]
},
"Gerador de HTML": {
"main": [
[
{
"node": "Stirling-PDF (Criar PDF)",
"type": "main",
"index": 0
}
]
]
},
"Stirling-PDF (Criar PDF)": {
"main": [
[
{
"node": "Enviar PDF (WhatsApp)",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"timezone": "America/Sao_Paulo",
"saveExecutionProgress": true,
"saveManualExecutions": true
},
"versionId": "e48bd9cd-e2bd-43b9-b13e-3eda0a13538b",
"id": "L3ayXP4efuneAzgs",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
openAiApipostgres
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Radar MB - Relatório Diário e PDF (22h). Uses postgres, openAi, httpRequest. Scheduled trigger; 7 nodes.
Source: https://github.com/carlosanders/monitora-radar-noticias/blob/b0451715dd46ddfdc7a97186bc4347b3c4a45168/wiki/radar_mb_relat_rio_di_rio_e_pdf_22h.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
A scheduled process aggregates content from eight distinct data sources and standardizes all inputs into a unified format. AI models perform sentiment scoring, detect conspiracy or misinformation sign
News Automation - Main Workflow. Uses rssFeedRead, postgres, openAi, httpRequest. Scheduled trigger; 28 nodes.
This n8n workflow automates the monitoring of warehouse inventory and sales velocity to predict demand, generate purchase orders automatically, send them to suppliers, and record all transactions in E
VenueDesk — AI Lead Generator (Daily). Uses postgres, httpRequest, openAi, emailSend. Scheduled trigger; 17 nodes.
AI Institutional Stock Valuation Engine with Risk Scoring & Scenario Targets