fix: send Teams adaptive card as string in webhook payload (card) to satisfy flowbot parser

This commit is contained in:
2025-12-20 05:54:17 +00:00
parent b8bd3debe0
commit def6f323df
+50 -5
View File
@@ -54,6 +54,43 @@ async function logError(context: string, error: any, additionalData?: any) {
// TEAMS WEBHOOK NOTIFICATION (Power Automate)
// ============================================================================
function buildAdaptiveCard(jobData: any, jobFolderLink: string) {
const jobName = jobData.Job_Name || '';
const jobNumber = jobData.Job_Number || '';
const jobAddress = jobData.Job_Address || '';
const companyClient = jobData.Company_Client || '';
const jobDivision = jobData.Job_Division || '';
const jobType = jobData.Job_Type || '';
const contactPerson = jobData.Contact_Person || '';
const phoneNumber = jobData.Phone_Number || '';
// Valid Adaptive Card (Teams flowbot expects type: AdaptiveCard)
return {
type: 'AdaptiveCard',
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
version: '1.5',
body: [
{ type: 'TextBlock', text: 'New Job!', weight: 'Bolder', size: 'Large' },
{ type: 'TextBlock', text: `${jobNumber} - ${jobName}`, wrap: true },
{
type: 'FactSet',
facts: [
{ title: 'Number', value: jobNumber || 'N/A' },
{ title: 'Name', value: jobName || 'N/A' },
{ title: 'Address', value: jobAddress || 'N/A' },
{ title: 'Client', value: companyClient || 'N/A' },
{ title: 'Division', value: jobDivision || 'N/A' },
{ title: 'Type', value: jobType || 'N/A' },
{ title: 'Contact', value: (contactPerson && phoneNumber) ? `${contactPerson} - ${phoneNumber}` : (contactPerson || 'N/A') }
]
}
],
actions: jobFolderLink ? [
{ type: 'Action.OpenUrl', title: 'Open Folder', url: jobFolderLink }
] : []
};
}
async function notifyTeamsChannel(jobData: any, jobFolderLink: string) {
const webhook = process.env.POWER_AUTOMATE_WEBHOOK_URL || process.env.TEAMS_WEBHOOK_URL;
@@ -73,8 +110,10 @@ async function notifyTeamsChannel(jobData: any, jobFolderLink: string) {
const contactPerson = jobData.Contact_Person || '';
const phoneNumber = jobData.Phone_Number || '';
// Build payload for Power Automate
// Build Adaptive Card and payload for Power Automate
const adaptiveCard = buildAdaptiveCard(jobData, jobFolderLink);
const payload = {
// raw fields, in case the flow maps them directly
jobNumber,
jobName,
jobAddress,
@@ -83,9 +122,14 @@ async function notifyTeamsChannel(jobData: any, jobFolderLink: string) {
jobType,
contactPerson,
phoneNumber,
jobFolderLink
jobFolderLink,
// Provide card in common parameter names used by PA templates
card: JSON.stringify(adaptiveCard),
adaptiveCard
};
console.log(`[Power Automate] Sending webhook for Job ${jobNumber}:`, JSON.stringify(payload, null, 2));
const response = await fetch(webhook, {
method: 'POST',
headers: {
@@ -96,12 +140,13 @@ async function notifyTeamsChannel(jobData: any, jobFolderLink: string) {
if (!response.ok) {
const text = await response.text();
console.warn(`⚠️ Power Automate notification failed: ${response.status} ${text}`);
console.warn(`⚠️ Power Automate notification failed: ${response.status} ${response.statusText}`);
console.warn(` Response: ${text}`);
} else {
console.log(`✓ Power Automate notification sent for Job ${jobNumber}`);
console.log(`✓ Power Automate notification sent for Job ${jobNumber} (${response.status})`);
}
} catch (error: any) {
console.error('⚠️ Failed to send Power Automate notification:', error);
console.error('⚠️ Failed to send Power Automate notification:', error.message);
// Don't fail the job creation if notification fails
}
}