{
  "name": "GitHub Trending 自动技术简报",
  "version": "1.0.0",
  "description": "定时抓取 GitHub 每日热门开源项目，经 LLM 自动翻译总结项目亮点，并发送邮件与 Discord 提醒",
  "nodes": [
    {
      "id": "cron-trigger",
      "name": "Daily 8:00 AM Trigger",
      "type": "n8n-nodes-base.cron",
      "position": [240, 300],
      "parameters": {
        "triggerTimes": {
          "item": [
            {
              "mode": "everyDay",
              "hour": 8,
              "minute": 0
            }
          ]
        }
      }
    },
    {
      "id": "fetch-trending",
      "name": "Fetch GitHub Trending",
      "type": "n8n-nodes-base.httpRequest",
      "position": [500, 300],
      "parameters": {
        "requestMethod": "GET",
        "url": "https://api.github.com/search/repositories",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "stars:>100 created:>{{ $now.minus({days: 7}).toFormat('yyyy-MM-dd') }}"
            },
            {
              "name": "sort",
              "value": "stars"
            },
            {
              "name": "order",
              "value": "desc"
            },
            {
              "name": "per_page",
              "value": 10
            }
          ]
        },
        "authentication": "genericCredentialType",
        "credentials": {
          "generic": "githubApi"
        },
        "sendHeaders": true,
        "headers": {
          "Accept": "application/vnd.github.v3+json",
          "Authorization": "={{ 'Bearer ' + $credentials.token }}"
        },
        "options": {
          "timeout": 30000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "parse-repos",
      "name": "Parse Repositories",
      "type": "n8n-nodes-base.function",
      "position": [760, 300],
      "parameters": {
        "functionCode": "const repos = $input.first().json.items || [];\n\nconst parsed = repos.map((repo, index) => ({\n  rank: index + 1,\n  name: repo.full_name,\n  url: repo.html_url,\n  description: repo.description || '暂无描述',\n  stars: repo.stargazers_count,\n  starsToday: repo.stargazers_count,\n  forks: repo.forks_count,\n  language: repo.language || 'Unknown',\n  topics: repo.topics || [],\n  openIssues: repo.open_issues_count,\n  license: repo.license ? repo.license.spdx_id : 'No License',\n  createdAt: repo.created_at,\n  updatedAt: repo.updated_at\n}));\n\n// Group by language\nconst byLanguage = {};\nparsed.forEach(repo => {\n  const lang = repo.language;\n  if (!byLanguage[lang]) byLanguage[lang] = [];\n  byLanguage[lang].push(repo);\n});\n\nreturn {\n  repos: parsed,\n  byLanguage: byLanguage,\n  totalCount: parsed.length,\n  fetchDate: new Date().toISOString().split('T')[0]\n};"
      }
    },
    {
      "id": "ai-summarize",
      "name": "AI Summarize with DeepSeek",
      "type": "n8n-nodes-base.httpRequest",
      "position": [1020, 300],
      "parameters": {
        "requestMethod": "POST",
        "url": "https://api.deepseek.com/v1/chat/completions",
        "authentication": "genericCredentialType",
        "credentials": {
          "generic": "deepseekApi"
        },
        "sendHeaders": true,
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "={{ 'Bearer ' + $credentials.apiKey }}"
        },
        "body": {
          "model": "deepseek-chat",
          "temperature": 0.3,
          "max_tokens": 2048,
          "messages": [
            {
              "role": "system",
              "content": "你是一个专业的技术简报编辑。请根据提供的 GitHub 热门仓库数据，为每个项目生成一段简洁的中文亮点总结（50-80字），突出项目的核心创新点、适用场景和值得关注的原因。"
            },
            {
              "role": "user",
              "content": "请为以下 GitHub Trending 仓库生成中文简报总结：\n\n{{ JSON.stringify($json.repos.slice(0, 10).map(r => ({ name: r.name, description: r.description, language: r.language, stars: r.stars, topics: r.topics.slice(0, 5) }))) }}"
            }
          ]
        }
      }
    },
    {
      "id": "parse-summary",
      "name": "Parse AI Summary",
      "type": "n8n-nodes-base.function",
      "position": [1280, 300],
      "parameters": {
        "functionCode": "const aiResponse = $input.first().json.choices[0].message.content;\nconst repos = $('parse-repos').first().json.repos;\n\nreturn {\n  repos: repos,\n  aiSummary: aiResponse,\n  generatedAt: new Date().toISOString()\n};"
      }
    },
    {
      "id": "build-email-html",
      "name": "Build Email HTML",
      "type": "n8n-nodes-base.function",
      "position": [1540, 200],
      "parameters": {
        "functionCode": "const { repos, aiSummary, generatedAt } = $input.first().json;\n\nconst repoCards = repos.slice(0, 10).map((repo, i) => `\n  <tr>\n    <td style=\"padding: 16px; border-bottom: 1px solid #e5e7eb;\">\n      <div style=\"font-size: 14px; color: #6b7280; margin-bottom: 4px;\">#${i + 1} · ${repo.language}</div>\n      <a href=\"${repo.url}\" style=\"font-size: 18px; font-weight: 700; color: #2563eb; text-decoration: none;\">${repo.name}</a>\n      <p style=\"font-size: 14px; color: #4b5563; margin: 8px 0;\">${repo.description}</p>\n      <div style=\"font-size: 13px; color: #9ca3af;\">\n        ⭐ ${repo.stars.toLocaleString()} stars · 🍴 ${repo.forks.toLocaleString()} forks · 📋 ${repo.openIssues} issues\n        ${repo.license !== 'No License' ? ` · 📄 ${repo.license}` : ''}\n      </div>\n      ${repo.topics.length > 0 ? `<div style=\"margin-top: 8px;\">${repo.topics.slice(0, 5).map(t => `<span style=\"display: inline-block; background: #dbeafe; color: #1e40af; padding: 2px 8px; border-radius: 12px; font-size: 12px; margin-right: 4px;\">${t}</span>`).join('')}</div>` : ''}\n    </td>\n  </tr>\n`).join('');\n\nconst html = `\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>GitHub Trending 每日简报 - ${new Date(generatedAt).toLocaleDateString('zh-CN')}</title>\n</head>\n<body style=\"margin: 0; padding: 0; background-color: #f3f4f6; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">\n  <div style=\"max-width: 640px; margin: 0 auto; padding: 20px;\">\n    <!-- Header -->\n    <div style=\"background: linear-gradient(135deg, #1e293b, #334155); border-radius: 12px 12px 0 0; padding: 32px 24px; text-align: center;\">\n      <h1 style=\"color: #ffffff; font-size: 24px; margin: 0 0 8px 0;\">🚀 GitHub Trending 每日简报</h1>\n      <p style=\"color: #cbd5e1; font-size: 14px; margin: 0;\">${new Date(generatedAt).toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' })}</p>\n    </div>\n    \n    <!-- AI Summary -->\n    <div style=\"background: #ffffff; padding: 24px; border-bottom: 1px solid #e5e7eb;\">\n      <h2 style=\"font-size: 16px; color: #1e293b; margin: 0 0 16px 0;\">🤖 AI 亮点解读</h2>\n      <div style=\"font-size: 14px; color: #4b5563; line-height: 1.7; white-space: pre-wrap;\">${aiSummary}</div>\n    </div>\n    \n    <!-- Repo List -->\n    <div style=\"background: #ffffff; border-radius: 0 0 12px 12px; overflow: hidden;\">\n      <table style=\"width: 100%; border-collapse: collapse;\">\n        <tbody>\n          ${repoCards}\n        </tbody>\n      </table>\n    </div>\n    \n    <!-- Footer -->\n    <div style=\"text-align: center; padding: 24px; color: #9ca3af; font-size: 12px;\">\n      <p>本简报由 n8n 工作流自动生成 · 数据来源 GitHub API</p>\n      <p>如需退订，请回复此邮件</p>\n    </div>\n  </div>\n</body>\n</html>\n`;\n\nreturn {\n  html: html,\n  subject: `🚀 GitHub Trending 每日简报 - ${new Date(generatedAt).toLocaleDateString('zh-CN')}`,\n  repoCount: repos.length\n};"
      }
    },
    {
      "id": "build-discord-embed",
      "name": "Build Discord Embed",
      "type": "n8n-nodes-base.function",
      "position": [1540, 460],
      "parameters": {
        "functionCode": "const { repos, aiSummary, generatedAt } = $input.first().json;\n\nconst fields = repos.slice(0, 5).map((repo, i) => ({\n  name: `#${i + 1} ${repo.name} ⭐ ${repo.stars.toLocaleString()}`,\n  value: `${repo.description || '暂无描述'}\\n[🔗 查看项目](${repo.url}) · ${repo.language}`,\n  inline: false\n}));\n\nconst embed = {\n  title: `🚀 GitHub Trending 每日简报`,\n  description: `**🤖 AI 亮点解读**\\n${aiSummary.slice(0, 1000)}${aiSummary.length > 1000 ? '...' : ''}`,\n  color: 0x2563eb,\n  fields: fields,\n  footer: {\n    text: `数据来源 GitHub API · ${new Date(generatedAt).toLocaleDateString('zh-CN')}`\n  },\n  timestamp: new Date(generatedAt).toISOString()\n};\n\nreturn {\n  embeds: [embed],\n  username: 'GitHub Trending Bot',\n  avatar_url: 'https://github.githubassets.com/favicons/favicon-dark.png'\n};"
      }
    },
    {
      "id": "send-email",
      "name": "Send Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [1800, 200],
      "parameters": {
        "fromEmail": "noreply@yourdomain.com",
        "toEmail": "subscribers@yourdomain.com",
        "subject": "={{ $('build-email-html').first().json.subject }}",
        "emailType": "html",
        "html": "={{ $('build-email-html').first().json.html }}",
        "options": {
          "appendAttribution": false
        }
      },
      "credentials": {
        "smtp": "smtpCredentials"
      }
    },
    {
      "id": "send-discord",
      "name": "Send to Discord",
      "type": "n8n-nodes-base.httpRequest",
      "position": [1800, 460],
      "parameters": {
        "requestMethod": "POST",
        "url": "={{ $credentials.discordWebhookUrl }}",
        "sendHeaders": true,
        "headers": {
          "Content-Type": "application/json"
        },
        "body": {
          "username": "={{ $('build-discord-embed').first().json.username }}",
          "avatar_url": "={{ $('build-discord-embed').first().json.avatar_url }}",
          "embeds": "={{ $('build-discord-embed').first().json.embeds }}"
        },
        "authentication": "genericCredentialType",
        "credentials": {
          "generic": "discordWebhook"
        }
      }
    }
  ],
  "connections": {
    "cron-trigger": {
      "main": [[{ "node": "fetch-trending", "type": "main", "index": 0 }]]
    },
    "fetch-trending": {
      "main": [[{ "node": "parse-repos", "type": "main", "index": 0 }]]
    },
    "parse-repos": {
      "main": [[{ "node": "ai-summarize", "type": "main", "index": 0 }]]
    },
    "ai-summarize": {
      "main": [[{ "node": "parse-summary", "type": "main", "index": 0 }]]
    },
    "parse-summary": {
      "main": [
        [{ "node": "build-email-html", "type": "main", "index": 0 }],
        [{ "node": "build-discord-embed", "type": "main", "index": 0 }]
      ]
    },
    "build-email-html": {
      "main": [[{ "node": "send-email", "type": "main", "index": 0 }]]
    },
    "build-discord-embed": {
      "main": [[{ "node": "send-discord", "type": "main", "index": 0 }]]
    }
  },
  "settings": {
    "saveManualExecutions": false,
    "callerPolicy": "any",
    "errorWorkflow": "",
    "executionTimeout": -1,
    "maxExecutionTimeout": 7200000,
    "saveDataErrorExecution": "all",
    "saveDataSuccessExecution": "all",
    "saveExecutionProgress": false,
    "timezone": "Asia/Shanghai"
  },
  "staticData": null,
  "pinData": {},
  "tags": ["GitHub", "Trending", "AI", "Email", "Discord", "Automation", "Newsletter"],
  "versionId": "1",
  "id": "github-trending-bot-workflow",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "n8n-instance-id-placeholder"
  },
  "credentials": [
    {
      "name": "githubApi",
      "type": "httpHeaderAuth",
      "displayName": "GitHub API Token"
    },
    {
      "name": "deepseekApi",
      "type": "httpHeaderAuth",
      "displayName": "DeepSeek API Key"
    },
    {
      "name": "smtpCredentials",
      "type": "smtp",
      "displayName": "SMTP Email"
    },
    {
      "name": "discordWebhook",
      "type": "webhook",
      "displayName": "Discord Webhook"
    }
  ]
}