昨天我的 M2A Agent 已經成功寄送了任務通知信,但我還希望可以再做一點進化,因此今天的目標就是為通知郵件加入一個直達 Notion 的按鈕,讓夥伴能一鍵查看任務;同時,我也會強化 n8n 的工作流程,確保單一的寄信失敗不會導致整個自動化流程崩潰。
雖然這個步驟是今天最簡單的設定,但也是最重要的一個步驟,因為目前的迴圈機制,就像是一串串起來的鞭炮,只要中間有一顆受潮點不著(像是只要 Email 發生問題),後面的所有鞭炮就都停止了,我要做的,就是讓它們變成獨立的煙火,一顆失敗,不影響下一顆的綻放。
這個小小的設定,賦予了我們工作流程極大的韌性。現在即使迴圈中有一個人的 Email 無效導致寄信失敗,n8n 也會記錄下這個錯誤,然後繼續處理下一個人的郵件,確保多數人能順利收到通知。
光有任務列表還不夠,最貼心的助理,會直接幫你把門打開。我們要在郵件的結尾,加上一個醒目的按鈕,讓收到信的夥伴能直接點擊,跳轉到 Notion 的任務看板頁面。
htmlContent
中,加入按鈕的 HTML 語法const assigneeInfo = $input.item.json;
const meetingInfo = $('提取結構化任務').first().json.meeting_info;
const meetingAttributes = $('提取結構化任務').first().json.meeting_attributes;
const assigneeName = assigneeInfo.name || '夥伴';
const projectName = meetingInfo.project_name || '未指定專案';
const taskCount = assigneeInfo.tasks.length;
const summary = meetingAttributes.summary || '暫無摘要';
const deadlineDate = meetingInfo.deadline_date || '未設定';
let tasksHtml = '';
for (let i = 0; i < assigneeInfo.tasks.length; i++) {
const task = assigneeInfo.tasks[i];
const taskNum = i + 1;
const title = task.title || '未命名任務';
const desc = task.description || '';
const timeExpr = task.time_expression || '';
const priority = task.priority || '';
const priBg = priority === '高' ? '#e74c3c' : '#f39c12';
const priBadge = priority ?
`<span style="background-color: ${priBg}; color: white; font-size: 11px; padding: 3px 8px; border-radius: 10px; margin-left: 5px;">${priority}優先</span>` :
'';
tasksHtml += `
<div style="background-color: #fff; border: 2px solid #e3e8ef; border-left: 5px solid #667eea; padding: 18px; margin-bottom: 15px; border-radius: 6px;">
<div style="margin-bottom: 10px;">
<span style="background-color: #667eea; color: white; font-size: 12px; font-weight: bold; padding: 4px 10px; border-radius: 12px;">任務 ${taskNum}</span>
${priBadge}
</div>
<h4 style="margin: 0 0 12px 0; color: #2c3e50; font-size: 16px; font-weight: bold;">${title}</h4>
<p style="margin: 8px 0; color: #666; font-size: 13px;">${desc}</p>
<p style="margin: 12px 0 0 0; color: #555; font-size: 14px;">
<strong>📅 預計完成期限:</strong>
<span style="color: #e74c3c; font-weight: bold;">${deadlineDate}</span>`;
if (timeExpr) {
tasksHtml += ` <span style="color: #999; font-size: 13px;">(${timeExpr})</span>`;
}
tasksHtml += `
</p>
</div>`;
}
// link 替換為要導至的網址
const notionProjectUrl = '<link>';
const htmlContent = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body style="margin: 0; padding: 0; background-color: #f4f4f4; font-family: Arial, sans-serif;">
<div style="max-width: 600px; margin: 20px auto; background-color: #fff; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 12px rgba(0,0,0,0.15);">
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px 20px; text-align: center;">
<h1 style="margin: 0; font-size: 24px; font-weight: bold;">M2A Agent 任務指派通知</h1>
<p style="margin: 10px 0 0 0; font-size: 14px; opacity: 0.9;">您有新的任務等待處理</p>
</div>
<div style="padding: 30px 25px;">
<p style="font-size: 16px; color: #333; margin: 0 0 20px 0;">Hi <strong>${assigneeName}</strong>,</p>
<div style="background-color: #f8f9fa; border-left: 4px solid #667eea; padding: 15px; margin-bottom: 25px; border-radius: 4px;">
<p style="margin: 0; color: #555; font-size: 14px;">在剛剛的「<strong style="color: #667eea;">${projectName}</strong>」會議中,您被指派了 <strong style="color: #e74c3c;">${taskCount}</strong> 項新任務,請查收:</p>
</div>
<div style="margin-bottom: 30px;">
${tasksHtml}
</div>
<div style="text-align: center; margin-bottom: 30px;">
<a href="${notionProjectUrl}" target="_blank" style="background-color: #5a67d8; color: white; padding: 12px 25px; text-decoration: none; border-radius: 8px; font-weight: bold; font-size: 14px; display: inline-block;">
前往 Notion 查看會議記錄
</a>
</div>
<hr style="border: 0; border-top: 1px solid #e0e0e0; margin: 30px 0;">
<div>
<h3 style="color: #667eea; font-size: 18px; margin: 0 0 15px 0; border-bottom: 2px solid #667eea; padding-bottom: 8px;">相關會議摘要</h3>
<div style="background-color: #f9f9f9; padding: 15px; border-radius: 6px; border: 1px solid #e8e8e8;">
<p style="margin: 0; color: #555; font-size: 14px; line-height: 1.6;">${summary}</p>
</div>
</div>
</div>
<div style="background-color: #f8f9fa; text-align: center; padding: 20px; border-top: 1px solid #e0e0e0;">
<p style="margin: 0; font-size: 12px; color: #999;">這是一封由 M2A Agent 自動發送的通知郵件</p>
<p style="margin: 8px 0 0 0; font-size: 11px; color: #bbb;">請勿直接回覆此郵件</p>
</div>
</div>
</body>
</html>`;
return {
email: assigneeInfo.email,
name: assigneeName,
projectName: projectName,
taskCount: taskCount,
htmlContent: htmlContent
};
修改完成後,進行端到端的測試,確保一切正常運作。
看著信中出現了這個好用的按鈕,代表我們今天的任務順利完成了!
✅ 完成項目
今天的工作證明了,有時候最有價值的更新,並不一定是那些驚天動地的大功能,而是在細節處的打磨。
一個小小的按鈕,讓整個使用者體驗又提升了;一個簡單選項,讓系統的可靠性也提升了一個檔次,這正是打造一個成熟作品的必經之路。
🎯 明天計劃
全面強化 Gradio 介面,加入歷史會議列表與進度條,讓使用者能追溯紀錄並掌握即時處理狀態。