iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0

我們專案的 REPO 是放在 GitHub 上面的,有寫個 GitHub Actions 去觸發當有新的 commit 推到 production 時,就會把部署的結果傳送到 Discord 頻道,而底下的流程是基於這個通知的延伸

本次主角是強大的自動化工具 n8n、GitHub、Discord,以及 AI 模型 Gemini

前置作業:Discord Bot

要讓 n8n 能監聽和發送 Discord 訊息,我們需要先建立一個專屬的 Bot

  • 前往「Discord Developer Portal」

    https://discord.com/developers/applications

  • 新增一個應用程式

    image 0.png

  • 到「Bot」分頁點選「Reset Token」就會出現新的金鑰可以複製

    image 1.png

  • 把「Privileged Gateway Intents」的設定都打開

    image 2.png

  • 接著到「OAuth2」的頁面的「OAuth2 URL Generator」把「bot」打勾

    image 3.png

  • 會出現「Bot Permissions」權限列表,把底下都打勾

    image 4.png

  • 接著複製最下方產生的網址

    image 5.png

  • 會彈出 Discord 可以把機器人加進伺服器

    image 6.png

    image 7.png

    image 8.png

  • 接著到 n8n 的設定介面

    image 9.png

  • 切換到「Community nodes」去安裝社群節點「n8n-nodes-discord-trigger

    image 10.png

workflow

1. Discord Trigger - 監聽部署通知

  • 來到儀表板,新增一個流程「Create Workflow」

    image 11.png

  • 初始節點選擇「Discord Trigger」

    image 12.png

  • 點選「Add to workflow」

    image 13.png

  • 設定新增憑證

    image 14.png

  • 「Client ID」在 Discord 機器人設定的「OAuth」頁面裡

    image 15.png

  • 到「Bot」分頁點選「Reset Token」就會出現新的金鑰可以複製

    image 1.png

  • n8n API key」可以到 n8n 的設定頁面生產一個

    image 16.png

  • 設定要監聽的頻道

    image 17.png

2. IF - 過濾特定訊息

  • 下個節點選擇「IF」來過濾訊息

    image 18.png

  • 欄位設定判斷訊息的作者是「Bot」

    {{ $json.author.username }}
    

    image 19.png

  • 另一個欄位選擇特定分支

    {{ $json.embeds[0].fields.find(f => f.name === 'Branch').value }}
    

3. Code (Get headSha) - 取得最新的 Commit SHA

  • 接續在「true」的路徑選擇「Code」節點

    image 20.png

  • 程式碼撰寫底下的內容來抓 commit 的 URL

    // 取得 'Commit' 欄位的內容,它是一個 Markdown 格式的連結
    // 格式為:[d1accfe](https://github.com/...)
    const fields = $json.embeds[0].fields;
    const commitField = fields.find((f) => f.name === "Commit");
    
    if (!commitField) {
      // 如果找不到 Commit 欄位,就回傳空值
      return { headSha: null };
    }
    
    // 使用正規表示式從 Markdown 連結中提取 URL
    const markdownLink = commitField.value;
    const urlRegex = /\(([^)]+)\)/; // 符合括號內的內容
    const match = markdownLink.match(urlRegex);
    
    if (!match || !match[1]) {
      // 如果沒抓到 URL,回傳空值
      return { headSha: null };
    }
    
    const url = match[1];
    const headSha = url.split("/").pop();
    
    return { headSha: headSha };
    

4. Discord (Get many message) - 讀取歷史訊息

  • 下個節點選擇「Discord」的「Get many message」來讀取頻道歷史訊息

    image 21.png

  • 同樣要新增憑證

    image 22.png

  • 貼上 Bot Token

    image 23.png

  • 設定要抓的伺服器跟頻道,抓「10」筆就好

    image 24.png

5. Code - 找出上次的 Commit SHA

  • 下個節點再選擇「Code」

    image 25.png

  • 程式碼撰寫如下來找出上次 commit 的 SHA

    const messages = $("Discord").item.json;
    const triggerMessageId = $("Discord Trigger").item.json.id;
    
    for (const msg of messages) {
      // 跳過觸發本次流程的訊息本身,從下一則開始才是歷史紀錄
      if (msg.id === triggerMessageId) {
        continue;
      }
    
      // 確保找到的是來自 GitHub Bot 且格式正確的訊息
      if (
        msg.author.username === "GitHub" &&
        msg.embeds &&
        msg.embeds.length > 0 &&
        msg.embeds[0].url
      ) {
        const url = msg.embeds[0].url;
        const baseSha = url.split("/").pop();
        // 找到第一筆符合的就回傳並結束
        return { baseSha: baseSha };
      }
    }
    
    // 安全機制:如果沒找到,回傳一個空值
    return { baseSha: null };
    

6. HTTP Request - 呼叫 GitHub API 比對差異

  • 下個節點選擇「HTTP Request」

    image 26.png

  • 權限選擇「Header Auth」

    image 27.png

  • 填上底下的內容,「YOUR_GITHUB_PAT」要改成自己的權杖

    Bearer YOUR_GITHUB_PAT
    

    image 28.png

  • 請求的 URL 填上

    https://api.github.com/repos/{{ $('Discord Trigger').item.json.embeds[0].author.name.split('/')[0] }}/{{ $('Discord Trigger').item.json.embeds[0].author.name.split('/')[1] }}/compare/{{ $('Code').item.json.baseSha }}...{{ $('Get headSha').item.json.headSha }}
    
  • 接著「Send Headers」打開,加上底下的欄位

    • Name: Accept

      Value: application/vnd.github.v3+json

    • Name: X-GitHub-Api-Version

      Value: 2022-11-28

    image 29.png

7. Gemini - 召喚 AI 撰寫日誌

  • 下個節點來選「Gemini」把 commit 紀錄丟過去,讓他幫我們產 CHANGELOG

    image 30.png

  • 同樣要新增設定憑證

    image 31.png

  • 前往底下的網址

    ai.dev

  • 點選「Get API key」,選擇「Create API key」

    image 32.png

  • 選個快速的模型

    image 33.png

  • Prompt 設定如下

    你是一位資深的軟體工程師與技術寫作專家,擅長將零散的技術 commit log 彙整成清晰易懂、適合團隊內部溝通的 changelog。
    
    請根據以下提供的 raw commit messages,幫我完成一份專業的「新功能部署日誌」。
    
    撰寫要求:
    
    1.  使用台灣用語的正體中文。技術名詞若無通用翻譯可保留英文。
    2.  根據 commit 內容,將變更分類為【✨ 新功能】、【🐛 錯誤修正】、【🔧 最佳化改善】、【📄 文件】等。如果分類不明顯,可以都放在【🔧 最佳化改善】下。
    3.  語氣應專業且帶點輕鬆,讓團隊成員能快速掌握重點。
    4.  移除 commit message 中的 issue numbers 或無關的標籤。
    5.  最終結果直接以 Markdown 格式輸出,不要有額外的開頭或結尾問候語。
    
    --- Raw Commits ---
    {{ $('HTTP Request').item.json.commits.map(c => `- ${c.commit.message.split('\n')[0]}`).join('\n') }}
    --- End of Raw Commits ---
    

8. Discord - 發送最終成果

  • 接著選擇「Discord」來發送訊息

    image 34.png

  • 「Connection Type」選擇「Webhook」,憑證的串接在之前的文章有撰寫過,這邊就不重複惹

    image 35.png

  • Message 設定如下

    {
      {
        $json.text;
      }
    }
    

    image 36.png

  • 記得在最上方點選啟用「Active」

    image 37.png

現在,當下一次部署完成時,我們的團隊就會收到由 AI 自動產生的精美更新日誌惹


上一篇
[Day14]_專案錯誤通知器
下一篇
[Day16]_CodePen RSS 通知
系列文
告別重複瑣事: n8n workflow 自動化工作實踐17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言