Discord 用に Gemini AI を使用した地域の注目ニュースの精選された要約の生成
上級
これはContent Creation, Multimodal AI分野の自動化ワークフローで、20個のノードを含みます。主にCode, Sort, Limit, Merge, Discordなどのノードを使用。 Gemini AIを使用してDiscordに精选された local ニュースサマリー(日本語)を生成
前提条件
- •Discord Bot Token または Webhook
- •ターゲットAPIの認証情報が必要な場合あり
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
"meta": {
"instanceId": "105694f414213a0eca348284005921253960bd1b0223294a4970522d0da53055",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "e5629011-82f2-4107-967f-91659ee7455f",
"name": "毎日 8AM トリガー",
"type": "n8n-nodes-base.scheduleTrigger",
"notes": "Change the cron expression to adjust schedule. Current: 8AM daily",
"position": [
-400,
48
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * *"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "fb7df187-44df-4e20-bc35-64ef353e6ee0",
"name": "RSS Phoenix New Times",
"type": "n8n-nodes-base.rssFeedRead",
"position": [
-192,
-256
],
"parameters": {
"url": "https://www.phoenixnewtimes.com/phoenix/Rss.xml",
"options": {}
},
"typeVersion": 1
},
{
"id": "9d60cd62-960a-451b-bde1-5543eaef63ae",
"name": "RSS AZ Free News",
"type": "n8n-nodes-base.rssFeedRead",
"position": [
-192,
-96
],
"parameters": {
"url": "https://azfreenews.com/feed/",
"options": {}
},
"typeVersion": 1
},
{
"id": "6dbf6940-9f45-48be-87f2-1d03727c2f71",
"name": "RSS Reddit Phoenix",
"type": "n8n-nodes-base.rssFeedRead",
"position": [
-192,
48
],
"parameters": {
"url": "https://www.reddit.com/r/Phoenix/.rss",
"options": {}
},
"typeVersion": 1
},
{
"id": "6633710a-8742-45f6-b21b-07c800067043",
"name": "RSS Reddit Scottsdale",
"type": "n8n-nodes-base.rssFeedRead",
"position": [
-192,
192
],
"parameters": {
"url": "https://www.reddit.com/r/Scottsdale/.rss",
"options": {}
},
"typeVersion": 1
},
{
"id": "b5248dc3-2541-4ee1-8ae8-342c363963f6",
"name": "RSS Reddit Arizona",
"type": "n8n-nodes-base.rssFeedRead",
"position": [
-192,
336
],
"parameters": {
"url": "https://www.reddit.com/r/Arizona/.rss",
"options": {}
},
"typeVersion": 1
},
{
"id": "834fa6ed-9b2d-433f-b121-f58ff9dba58b",
"name": "全RSSフィードを統合",
"type": "n8n-nodes-base.merge",
"position": [
16,
48
],
"parameters": {
"numberInputs": 5
},
"typeVersion": 3
},
{
"id": "588b18cf-44a7-42b8-940e-219bb5176cfb",
"name": "重複排除と準備",
"type": "n8n-nodes-base.code",
"position": [
208,
48
],
"parameters": {
"jsCode": "// Deduplicate articles based on URL and prepare for Gemini scoring\nconst items = $input.all();\nconst uniqueArticles = new Map();\nconst locations = ['Phoenix', 'Scottsdale', 'Paradise Valley', 'Arizona', 'Tempe', 'Mesa', 'Chandler'];\n\n// Process and deduplicate\nfor (const item of items) {\n const url = item.json.link || item.json.url || '';\n const title = item.json.title || '';\n const description = item.json.description || item.json.content || item.json.summary || '';\n const source = item.json.source || 'Unknown';\n const pubDate = item.json.pubDate || item.json.published || new Date().toISOString();\n \n // Create unique key based on URL or title\n const key = url || title;\n \n if (key && !uniqueArticles.has(key)) {\n // Check if article mentions any of our locations\n const fullText = `${title} ${description}`.toLowerCase();\n const mentionsLocation = locations.some(loc => fullText.includes(loc.toLowerCase()));\n \n uniqueArticles.set(key, {\n title: title.substring(0, 200),\n url: url,\n description: description.substring(0, 500),\n source: source,\n pubDate: pubDate,\n mentionsLocation: mentionsLocation\n });\n }\n}\n\n// Convert to array and return\nconst deduplicatedArticles = Array.from(uniqueArticles.values());\n\n// Sort by date (newest first) and filter to most recent 50 for processing\nconst sortedArticles = deduplicatedArticles\n .sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate))\n .slice(0, 50);\n\nreturn sortedArticles.map(article => ({ json: article }));"
},
"typeVersion": 2,
"continueOnFail": true
},
{
"id": "add1c53d-bfb6-4ae7-898d-3205404f96b6",
"name": "Gemini 向け準備",
"type": "n8n-nodes-base.code",
"position": [
416,
48
],
"parameters": {
"jsCode": "// Prepare batch of articles for Gemini scoring - ONLY TITLES for efficiency\nconst articles = $input.all().map(item => item.json);\n\n// Create a text summary for Gemini to score - ONLY TITLES to save tokens\nconst titlesText = articles.map((article, index) => {\n return `${index + 1}. ${article.title}`;\n}).join('\\n');\n\n// Return both the articles and the formatted text\nreturn [{\n json: {\n articles: articles,\n titlesText: titlesText,\n articlesCount: articles.length\n }\n}];"
},
"typeVersion": 2,
"continueOnFail": true
},
{
"id": "8e245ef2-dada-4bdf-b0cf-82f36732ae7e",
"name": "Gemini 関連性スコアリング",
"type": "n8n-nodes-base.httpRequest",
"notes": "REPLACE YOUR_GEMINI_API_KEY_HERE with your actual Gemini API key",
"position": [
608,
48
],
"parameters": {
"url": "=https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-lite:generateContent?key=YOUR_KEY_HERE",
"method": "POST",
"options": {},
"jsonBody": "={{ JSON.stringify({\n \"contents\": [{\n \"parts\": [{\n \"text\": \"You are a local news relevance scorer for Phoenix, Scottsdale, and Paradise Valley area. Score the following \" + $json.articlesCount + \" article TITLES based on their local relevance.\\n\\nScore each from 0-100 based on:\\n- Local relevance (50%): Is it about Phoenix/Scottsdale/Paradise Valley?\\n- Community impact (30%): Will locals care?\\n- News value (20%): Is it newsworthy?\\n\\nArticle titles:\\n\" + $json.titlesText + \"\\n\\nReturn ONLY a JSON array with scores in the same order. Example: [85, 72, 45, 90, 33]\\nBe strict - only highly local news should score above 70.\"\n }]\n }],\n \"generationConfig\": {\n \"temperature\": 0.3,\n \"topK\": 40,\n \"topP\": 0.95,\n \"maxOutputTokens\": 512\n }\n}) }}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "8d17b168-d628-403e-8d02-7c28ef911b04",
"name": "スコア処理",
"type": "n8n-nodes-base.code",
"position": [
816,
48
],
"parameters": {
"jsCode": "// Process Gemini response and add scores to articles\nconst geminiResponse = $input.first().json;\nconst preparedData = $('Prepare for Gemini').first().json;\nconst articles = preparedData.articles;\n\n// Extract scores from Gemini response\nlet scores = [];\ntry {\n // Parse the response from Gemini\n const responseText = geminiResponse.candidates[0].content.parts[0].text;\n \n // Try to extract JSON array from the response\n const jsonMatch = responseText.match(/\\[.*\\]/s);\n if (jsonMatch) {\n scores = JSON.parse(jsonMatch[0]);\n } else {\n // Fallback: assign default scores based on location mentions\n scores = articles.map(article => article.mentionsLocation ? 75 : 50);\n }\n} catch (error) {\n console.error('Error parsing Gemini response:', error);\n // Fallback scoring based on location mentions\n scores = articles.map(article => article.mentionsLocation ? 75 : 50);\n}\n\n// Combine articles with scores\nconst scoredArticles = articles.map((article, index) => ({\n ...article,\n relevanceScore: scores[index] || 50\n}));\n\nreturn scoredArticles.map(article => ({ json: article }));"
},
"typeVersion": 2,
"continueOnFail": true
},
{
"id": "339e1098-65ba-4e89-85e1-9edcd6049ec9",
"name": "関連性でソート",
"type": "n8n-nodes-base.sort",
"position": [
1008,
48
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"order": "descending",
"fieldName": "relevanceScore"
}
]
}
},
"typeVersion": 1
},
{
"id": "03a00299-fa97-4cb2-8265-d1b0962344a3",
"name": "上位5件に制限",
"type": "n8n-nodes-base.limit",
"notes": "Change maxItems to adjust how many articles to send (e.g., 15)",
"position": [
1216,
48
],
"parameters": {
"maxItems": 5
},
"typeVersion": 1
},
{
"id": "1e31fe92-f998-4e72-a8a6-388d0b3db8e1",
"name": "Discord メッセージをフォーマット",
"type": "n8n-nodes-base.code",
"notes": "Using RSS descriptions directly - no additional AI summarization to save tokens",
"position": [
1408,
48
],
"parameters": {
"jsCode": "// Collect all incoming articles\nconst articles = $input.all().map(item => item.json);\n\n// Get today's date formatted\nconst today = new Date().toLocaleDateString('en-US', { \n weekday: 'long', \n year: 'numeric', \n month: 'long', \n day: 'numeric' \n});\n\n// Utility: strip HTML tags from text\nfunction stripHtml(html) {\n return html\n .replace(/<[^>]*>/g, '') // remove HTML tags\n .replace(/\\s+/g, ' ') // collapse whitespace\n .trim();\n}\n\n// Build the full digest string\nlet discordMessage = `🌵 **LOCAL NEWS DIGEST** 🌵\\n📅 ${today}\\n${'━'.repeat(40)}\\n\\n`;\n\narticles.forEach((article, index) => {\n const emoji = index === 0 ? '🥇' : index === 1 ? '🥈' : index === 2 ? '🥉' : `${index + 1}.`;\n \n const description = stripHtml(article.description || 'No description available');\n\n discordMessage += `${emoji} **${article.title}**\\n`;\n discordMessage += `📍 ${description}\\n`;\n discordMessage += `🔗 ${article.url}\\n\\n`;\n});\n\ndiscordMessage += `${'━'.repeat(40)}\\n`;\ndiscordMessage += `_Powered by n8n automation | Phoenix • Scottsdale • Paradise Valley_`;\n\n// Discord has a 2000 character limit, so split into multiple messages if necessary\nconst maxLength = 1900; // leave buffer for safety\nconst messages = [];\n\nfor (let i = 0; i < discordMessage.length; i += maxLength) {\n messages.push(discordMessage.slice(i, i + maxLength));\n}\n\n// Return multiple items (Discord node will send each separately)\nreturn messages.map(msg => ({\n json: { content: msg }\n}));\n"
},
"typeVersion": 2,
"continueOnFail": true
},
{
"id": "6b23ead3-4d35-451f-b0f2-7e5146dd26a1",
"name": "Discord に送信",
"type": "n8n-nodes-base.discord",
"notes": "REPLACE with your actual Discord webhook URL",
"position": [
1616,
48
],
"webhookId": "5565d2a2-5e59-43c4-8733-d6b1ca51f509",
"parameters": {
"content": "={{ $json.content }}",
"options": {},
"authentication": "webhook"
},
"credentials": {
"discordWebhookApi": {
"id": "6S341y8tVCvOIO8r",
"name": "All Ops Notis Discord Webhook"
}
},
"typeVersion": 2,
"continueOnFail": true
},
{
"id": "9983e297-ee82-4fc9-bd87-74f46857afaf",
"name": "付箋",
"type": "n8n-nodes-base.stickyNote",
"position": [
528,
-336
],
"parameters": {
"height": 304,
"content": "## Set Your Gemini API Key. Get for free!\n**Link Below For Example: Get your key at Google AI Studio**\n\nhttps://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-lite:generateContent?key=YOUR_KEY_HERE"
},
"typeVersion": 1
},
{
"id": "0cb7e7cd-9818-40fd-9444-7a040fe054bf",
"name": "付箋1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-256,
-496
],
"parameters": {
"height": 208,
"content": "## Set Your News Feeds Here\n**Make sure they are rss**\n\nSee examples below for link structures. There are tools online to help you find RSS feeds for websites. "
},
"typeVersion": 1
},
{
"id": "5e83db58-6f66-4e74-b355-e7d32ff6649d",
"name": "付箋2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1136,
272
],
"parameters": {
"height": 112,
"content": "## Set how many articles you want.\n**Default is 5**\n"
},
"typeVersion": 1
},
{
"id": "ef2042de-6862-4981-b195-2dfc11d68df6",
"name": "付箋3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1328,
-224
],
"parameters": {
"height": 192,
"content": "## Might need changing for other sending locations, telegram whatsapp etc.\n\n"
},
"typeVersion": 1
},
{
"id": "023096cc-74b9-4c66-91ad-9102f6ba209c",
"name": "付箋4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1584,
224
],
"parameters": {
"height": 112,
"content": "## Recieve your relevant news articles\n"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"03a00299-fa97-4cb2-8265-d1b0962344a3": {
"main": [
[
{
"node": "1e31fe92-f998-4e72-a8a6-388d0b3db8e1",
"type": "main",
"index": 0
}
]
]
},
"8d17b168-d628-403e-8d02-7c28ef911b04": {
"main": [
[
{
"node": "339e1098-65ba-4e89-85e1-9edcd6049ec9",
"type": "main",
"index": 0
}
]
]
},
"9d60cd62-960a-451b-bde1-5543eaef63ae": {
"main": [
[
{
"node": "834fa6ed-9b2d-433f-b121-f58ff9dba58b",
"type": "main",
"index": 1
}
]
]
},
"e5629011-82f2-4107-967f-91659ee7455f": {
"main": [
[
{
"node": "fb7df187-44df-4e20-bc35-64ef353e6ee0",
"type": "main",
"index": 0
},
{
"node": "9d60cd62-960a-451b-bde1-5543eaef63ae",
"type": "main",
"index": 0
},
{
"node": "6dbf6940-9f45-48be-87f2-1d03727c2f71",
"type": "main",
"index": 0
},
{
"node": "6633710a-8742-45f6-b21b-07c800067043",
"type": "main",
"index": 0
},
{
"node": "b5248dc3-2541-4ee1-8ae8-342c363963f6",
"type": "main",
"index": 0
}
]
]
},
"339e1098-65ba-4e89-85e1-9edcd6049ec9": {
"main": [
[
{
"node": "03a00299-fa97-4cb2-8265-d1b0962344a3",
"type": "main",
"index": 0
}
]
]
},
"add1c53d-bfb6-4ae7-898d-3205404f96b6": {
"main": [
[
{
"node": "8e245ef2-dada-4bdf-b0cf-82f36732ae7e",
"type": "main",
"index": 0
}
]
]
},
"b5248dc3-2541-4ee1-8ae8-342c363963f6": {
"main": [
[
{
"node": "834fa6ed-9b2d-433f-b121-f58ff9dba58b",
"type": "main",
"index": 4
}
]
]
},
"6dbf6940-9f45-48be-87f2-1d03727c2f71": {
"main": [
[
{
"node": "834fa6ed-9b2d-433f-b121-f58ff9dba58b",
"type": "main",
"index": 2
}
]
]
},
"834fa6ed-9b2d-433f-b121-f58ff9dba58b": {
"main": [
[
{
"node": "588b18cf-44a7-42b8-940e-219bb5176cfb",
"type": "main",
"index": 0
}
]
]
},
"588b18cf-44a7-42b8-940e-219bb5176cfb": {
"main": [
[
{
"node": "add1c53d-bfb6-4ae7-898d-3205404f96b6",
"type": "main",
"index": 0
}
]
]
},
"fb7df187-44df-4e20-bc35-64ef353e6ee0": {
"main": [
[
{
"node": "834fa6ed-9b2d-433f-b121-f58ff9dba58b",
"type": "main",
"index": 0
}
]
]
},
"6633710a-8742-45f6-b21b-07c800067043": {
"main": [
[
{
"node": "834fa6ed-9b2d-433f-b121-f58ff9dba58b",
"type": "main",
"index": 3
}
]
]
},
"1e31fe92-f998-4e72-a8a6-388d0b3db8e1": {
"main": [
[
{
"node": "6b23ead3-4d35-451f-b0f2-7e5146dd26a1",
"type": "main",
"index": 0
}
]
]
},
"8e245ef2-dada-4bdf-b0cf-82f36732ae7e": {
"main": [
[
{
"node": "8d17b168-d628-403e-8d02-7c28ef911b04",
"type": "main",
"index": 0
}
]
]
}
}
}よくある質問
このワークフローの使い方は?
上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。
このワークフローはどんな場面に適していますか?
上級 - コンテンツ作成, マルチモーダルAI
有料ですか?
このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。
関連ワークフロー
ETHウォレット監視器
毎日のETHウォレット監視(Etherscan、CoinGecko価格、Discord通知)
Code
Discord
Http Request
+
Code
Discord
Http Request
13 ノードKaden Reese
コンテンツ作成
AI駆動型動画制作&Instagram/TikTok/YouTubeへの自動アップロード
クラウドドライブからAI駆動の動画作成およびInstagram、TikTok、YouTubeへのアップロード
If
Set
Code
+
If
Set
Code
53 ノードDevCode Journey
コンテンツ作成
コンテンツジェネレーター v3
AI驱动ブログ自動化:使用GPT-4生成并公開SEO記事至WordPressとTwitter
If
Set
Code
+
If
Set
Code
144 ノードJay Emp0
コンテンツ作成
Groq、Gemini、Slack承認システムを使用してRSSからMediumへの公開を自動化
Groq、Gemini、Slack承認システムを用いたRSSからMediumへの自動公開プロセス
If
Set
Code
+
If
Set
Code
41 ノードObisDev
コンテンツ作成
キーワードからGPT-5とfal.ai画像を使ってWordPressまで自動SEOブログ生成のプロセス
GPT-5とfal.ai画像を使用したキーワードからWordPressへのSEOブログ自動化プロセス
Set
Code
Wait
+
Set
Code
Wait
96 ノードPaul
コンテンツ作成
WordPressブログの自動化プロフェッショナル版(先端研究)v2.1マーケットプラグイン
GPT-4o、Perplexity AI、そして多言語対応を使ったSEO最適化ブログ作成の自動化
If
Set
Xml
+
If
Set
Xml
125 ノードDaniel Ng
コンテンツ作成
ワークフロー情報
難易度
上級
ノード数20
カテゴリー2
ノードタイプ9
作成者
Kaden Reese
@kadenreeseI started automating with Python in 2020 and still use it in workflows when needed, but I’ve recently leaned into n8n for client-facing solutions. Lately I’ve focused on real estate automations, though I also build workflows for email, scraping, and other use cases. Currently Building 👇🏻
外部リンク
n8n.ioで表示 →
このワークフローを共有