This workflow follows the Chainllm → Emailsend recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "github-trending",
"nodes": [
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
-416,
-256
],
"id": "b07134c8-89f6-490b-b0ad-f012b5c4dfbb",
"name": "When clicking \u2018Execute workflow\u2019"
},
{
"parameters": {
"content": "* Specify programming language or leave it empty.\n* Specify top N (default 3)\n* **Specify mail recipient**",
"height": 304,
"width": 192
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-256,
-208
],
"id": "320357dd-e58c-4e89-bf66-f7c7138fca27",
"name": "Sticky Note"
},
{
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 9
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-416,
-48
],
"id": "cf9c424d-9045-403e-86ab-0820ad9ad2bd",
"name": "Schedule Trigger"
},
{
"parameters": {
"url": "=https://api.github.com/repos/{{ $json.name }}/readme",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "githubApi",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/vnd.github.raw+json"
},
{
"name": "X-GitHub-Api-Version",
"value": "2022-11-28"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-416,
288
],
"id": "78190c1a-eed3-464c-b2b2-61d672f5be1f",
"name": "GitHub Repo Readme",
"credentials": {
"githubApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "=https://github.com/trending{{ $json.language === \"\" ? \"\" : \"/\" + $json.language }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
192,
-48
],
"id": "0714dd4a-fe61-421a-afe5-1c96030c1f33",
"name": "GitHub Trending"
},
{
"parameters": {
"language": "python",
"pythonCode": "from bs4 import BeautifulSoup\n\nsoup = BeautifulSoup(_json.data, 'html.parser')\n\nrepositories_data = []\n# Find all articles representing repositories\n# GitHub's trending page uses <article> tags with specific classes\nrepo_articles = soup.find_all(\"article\", class_=\"Box-row\")\n\nfor rank, article in enumerate(repo_articles):\n # Extract repository name\n title_tag = article.find(\"h2\", class_=\"h3\")\n if title_tag and title_tag.a:\n full_name = title_tag.a.text.strip().replace('\\n', '').replace(' ', '')\n # Format: \"owner/repo-name\"\n repo_name_parts = full_name.split('/')\n if len(repo_name_parts) >= 2:\n owner = repo_name_parts[0]\n repo_name = repo_name_parts[1]\n name = f\"{owner.strip()}/{repo_name.strip()}\"\n else:\n name = full_name.strip() # Fallback if format isn't as expected\n else:\n continue # Skip if name is not found\n\n # Extract description\n description_tag = article.find(\"p\", class_=\"col-9\")\n description = description_tag.text.strip() if description_tag else ''\n\n # Extract language\n language_tag = article.find(\"span\", itemprop=\"programmingLanguage\")\n language = language_tag.text.strip() if language_tag else ''\n\n # Extract stars and forks\n # Look for <a> tags with specific href patterns\n star_link = article.find(\"a\", href=f\"/{name}/stargazers\")\n fork_link = article.find(\"a\", href=f\"/{name}/forks\")\n stars = int(star_link.text.strip().replace(',', '')) if star_link else 0\n forks = int(fork_link.text.strip().replace(',', '')) if fork_link else 0\n\n # Extract \"Built by\" contributors (optional)\n built_by_avatars = []\n built_by_container = article.find(\"span\", class_=\"d-inline-block mr-3\")\n if built_by_container:\n for img_tag in built_by_container.find_all(\"img\", class_=\"avatar-user\"):\n alt_text = img_tag.get('alt')\n if alt_text and alt_text.startswith('@'):\n built_by_avatars.append(alt_text[1:]) # Remove '@' prefix\n\n today_stars = 0\n today_stars_tag = article.find(\"span\", class_=\"d-inline-block float-sm-right\")\n if today_stars_tag:\n today_stars_text = today_stars_tag.text.strip().split()[0] # Get the first part of the text\n if 'k' in today_stars_text:\n today_stars = int(float(today_stars_text.replace('k', '')) * 1000)\n else:\n today_stars = int(today_stars_text.replace(',', ''))\n\n repo_data = {\n \"rank\": rank,\n \"name\": name,\n \"description\": description,\n \"language\": language,\n \"stars\": stars,\n \"forks\": forks,\n \"today_stars\": today_stars,\n \"built_by\": built_by_avatars,\n }\n repositories_data.append(repo_data)\n\nreturn repositories_data"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
400,
-48
],
"id": "f21b06e7-7b07-495c-95aa-c7c55d0f19e0",
"name": "Extract Trending List"
},
{
"parameters": {
"promptType": "define",
"text": "=\u4f60\u662f\u4e00\u4e2a\u4e13\u4e1a\u7684GitHub\u9879\u76ee\u63a8\u8350\u535a\u4e3b\u3002\u4f60\u7684\u4efb\u52a1\u662f\u6839\u636e\u63d0\u4f9b\u7684GitHub\u4ed3\u5e93\u4fe1\u606f\u548cREADME.md\u5185\u5bb9\uff0c\u64b0\u5199\u4e00\u7bc7\u5438\u5f15\u4eba\u7684\u6bcf\u65e5\u63a8\u9001\u535a\u6587\uff0c\u4ee5Markdown\u683c\u5f0f\u8f93\u51fa\u3002\n\n\u535a\u6587\u5e94\u5305\u542b\u4ee5\u4e0b\u90e8\u5206\uff1a\n1. **\u6807\u9898**\uff1a\u7b80\u6d01\u660e\u4e86\uff0c\u80fd\u5438\u5f15\u8bfb\u8005\u70b9\u51fb\u3002\n2. **\u5f15\u8a00**\uff1a\u7b80\u8981\u4ecb\u7ecd\u4eca\u5929\u63a8\u8350\u7684\u9879\u76ee\uff0c\u6fc0\u53d1\u8bfb\u8005\u7684\u5174\u8da3\u3002\n3. **\u9879\u76ee\u4eae\u70b9**\uff1a\u4eceREADME.md\u548c\u4ed3\u5e93\u4fe1\u606f\u4e2d\u63d0\u70bc\u51fa\u9879\u76ee\u7684\u6838\u5fc3\u4ef7\u503c\u3001\u4e3b\u8981\u529f\u80fd\u3001\u89e3\u51b3\u7684\u95ee\u9898\u6216\u72ec\u7279\u4e4b\u5904\u3002\u8bf7\u5c1d\u8bd5\u4ece\u6280\u672f\u548c\u5e94\u7528\u4e24\u4e2a\u89d2\u5ea6\u8fdb\u884c\u63cf\u8ff0\u3002\n4. **\u6280\u672f\u7ec6\u8282/\u9002\u7528\u573a\u666f\uff08\u53ef\u9009\uff09**\uff1a\u5982\u679c\u4fe1\u606f\u5141\u8bb8\uff0c\u53ef\u4ee5\u7b80\u8981\u63d0\u53ca\u9879\u76ee\u4f7f\u7528\u7684\u6280\u672f\u6808\u6216\u9002\u5408\u7684\u5e94\u7528\u573a\u666f\u3002\n5. **\u5982\u4f55\u5f00\u59cb/\u94fe\u63a5**\uff1a\u5f15\u5bfc\u8bfb\u8005\u5982\u4f55\u8fdb\u4e00\u6b65\u4e86\u89e3\u6216\u4f7f\u7528\u8be5\u9879\u76ee\uff0c\u5e76\u63d0\u4f9bGitHub\u4ed3\u5e93\u94fe\u63a5\u3002\n6. **\u547c\u5401\u884c\u52a8**\uff1a\u9f13\u52b1\u8bfb\u8005\u63a2\u7d22\u3001\u8d21\u732e\u6216\u5206\u4eab\u3002\n\n\u8bf7\u6ce8\u610f\u4ee5\u4e0b\u4e8b\u9879\uff1a\n* **\u98ce\u683c**\uff1a\u4e13\u4e1a\u3001\u53cb\u597d\u3001\u5f15\u4eba\u5165\u80dc\u3002\u907f\u514d\u8fc7\u4e8e\u6280\u672f\u5316\u800c\u8ba9\u975e\u5f00\u53d1\u8005\u96be\u4ee5\u7406\u89e3\u3002\n* **\u957f\u5ea6**\uff1a\u6bcf\u7bc7\u535a\u6587\u603b\u957f\u5ea6\u63a7\u5236\u5728300-500\u5b57\u4e4b\u95f4\u3002\n* **\u591a\u4ed3\u5e93\u5904\u7406**\uff1a\u5982\u679c\u63d0\u4f9b\u4e86\u591a\u4e2a\u4ed3\u5e93\uff0c\u8bf7\u4e3a\u6bcf\u4e2a\u4ed3\u5e93\u5206\u522b\u64b0\u5199\u4e00\u4e2a\u72ec\u7acb\u7684\u535a\u6587\u6761\u76ee\uff0c\u5e76\u6700\u7ec8\u5408\u5e76\u4e3a\u4e00\u4e2a\u5b8c\u6574\u535a\u5ba2\u5185\u5bb9\u3002\n* **\u4fe1\u606f\u63d0\u53d6**\uff1a\u4f18\u5148\u4ece`README.md`\u4e2d\u63d0\u53d6\u9879\u76ee\u63cf\u8ff0\u3001\u529f\u80fd\u548c\u4f7f\u7528\u6307\u5357\u3002\u4ece\u4ed3\u5e93\u4fe1\u606f\u4e2d\u83b7\u53d6\u661f\u6807\u6570\u3001fork\u6570\u3001\u6700\u8fd1\u66f4\u65b0\u65f6\u95f4\u7b49\u5143\u6570\u636e\u4ee5\u589e\u52a0\u535a\u6587\u7684\u4e30\u5bcc\u6027\u3002\n* **\u521b\u610f\u548c\u6d1e\u5bdf**\uff1a\u9664\u4e86\u76f4\u63a5\u5f15\u7528\u4fe1\u606f\uff0c\u8bf7\u5c1d\u8bd5\u5bf9\u9879\u76ee\u8fdb\u884c\u7b80\u8981\u8bc4\u4ef7\u6216\u63d0\u51fa\u4f60\u7684\u770b\u6cd5\uff0c\u4ee5\u589e\u52a0\u535a\u6587\u7684\u6df1\u5ea6\u3002\n\n\u683c\u5f0f\u8981\u6c42\uff1a\n* \u4ec5\u8f93\u51fa\u6587\u7ae0\u5185\u5bb9\u7ed3\u679c\uff0c\u4e0d\u8981\u52a0\u5176\u4ed6\u4fe1\u606f\n* \u4e0d\u9700\u8981\u91cd\u5ea6\u7684\u5f00\u573a\u767d\u7b49\uff0c\u5982\u201c\u5927\u5bb6\u597d\u201d\u7b49\u5185\u5bb9\n* \u6807\u9898\u4f7f\u7528\u4e8c\u7ea7\u6807\u7b7e\n* \u6807\u9898\u4f7f\u7528\u5982\u4e0b\u683c\u5f0f\u793a\u4f8b\uff1a`## \u6bcf\u65e5GitHub\u9879\u76ee\u63a8\u8350\uff1aVosk API - \u4f60\u7684\u79bb\u7ebf\u8bed\u97f3\u8bc6\u522b\u5229\u5668\uff01`\n\n\u4ee5\u4e0b\u4e3aGithub\u4ed3\u5e93\u540d\u79f0 `{{ $('Limit Top N').item.json.name }}`\u3002\n\u4ed3\u5e93\u4fe1\u606f\uff1a\n```json\n{{ JSON.stringify($('Limit Top N').item.json, null, 2) }}\n```\n\n\u4ed3\u5e93\u539f\u59cbREADME\u4fe1\u606f\uff1a\n```markdown\n{{ $json.data }}\n```",
"batching": {}
},
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.7,
"position": [
-208,
288
],
"id": "28029161-7d6f-4bf1-ba37-5c66281ed332",
"name": "GitHub Repo Summarize"
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
-208,
480
],
"id": "a0ff40b7-38fa-41ee-9fe6-36b3d9f5e3c9",
"name": "Google Gemini Chat Model",
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "return {\n \"content\": $input.all().map(item => item.json.text).join('\\n\\n')\n}"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
192,
288
],
"id": "a7e28c63-4ea4-429a-89a5-bf6e2adbaadb",
"name": "Merge Markdown"
},
{
"parameters": {
"mode": "markdownToHtml",
"markdown": "={{ $json.content }}",
"options": {}
},
"type": "n8n-nodes-base.markdown",
"typeVersion": 1,
"position": [
400,
288
],
"id": "b9113dba-9441-4896-b813-025f07eb3dd6",
"name": "Markdown"
},
{
"parameters": {
"fromEmail": "no-reply@tomo.dev",
"toEmail": "={{ $('Set Variables').first().json.recipients }}",
"subject": "=GitHub Daily Trending #{{ $today.toISODate() }}",
"html": "={{ $json.data }}",
"options": {}
},
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2.1,
"position": [
608,
288
],
"id": "4e2173f4-5359-48e4-a07c-c88c05a71a80",
"name": "Send email",
"credentials": {
"smtp": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "3fc96359-e4d9-4280-b209-1b7aaaffd9a9",
"name": "language",
"value": "",
"type": "string"
},
{
"id": "d41d647d-2eee-4210-b246-f7f47186685a",
"name": "topN",
"value": 3,
"type": "number"
},
{
"id": "22eb48a8-5f2b-40f4-85b7-342ffdc31e66",
"name": "recipients",
"value": "",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-208,
-48
],
"id": "c040d611-8b78-4005-a4de-b290f6b884d0",
"name": "Set Variables",
"notesInFlow": false
},
{
"parameters": {
"errorMessage": "Please specify mail recipients"
},
"type": "n8n-nodes-base.stopAndError",
"typeVersion": 1,
"position": [
192,
-240
],
"id": "3ef03fe2-1867-4d91-b16f-980d7581d4e0",
"name": "Stop and Error"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "8fbbdf83-e290-4974-8f7d-e47ed268a2f7",
"leftValue": "={{ $json.recipients }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
0,
-48
],
"id": "ccef8f52-3228-44b2-820d-058ea38249b1",
"name": "If recipients Empty?"
},
{
"parameters": {
"maxItems": "={{ $('Set Variables').item.json.topN }}"
},
"type": "n8n-nodes-base.limit",
"typeVersion": 1,
"position": [
608,
-48
],
"id": "ea864cb1-f20d-4644-931a-bb1ee873803e",
"name": "Limit Top N"
}
],
"connections": {
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "Set Variables",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Set Variables",
"type": "main",
"index": 0
}
]
]
},
"GitHub Trending": {
"main": [
[
{
"node": "Extract Trending List",
"type": "main",
"index": 0
}
]
]
},
"Extract Trending List": {
"main": [
[
{
"node": "Limit Top N",
"type": "main",
"index": 0
}
]
]
},
"GitHub Repo Readme": {
"main": [
[
{
"node": "GitHub Repo Summarize",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "GitHub Repo Summarize",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"GitHub Repo Summarize": {
"main": [
[
{
"node": "Merge Markdown",
"type": "main",
"index": 0
}
]
]
},
"Merge Markdown": {
"main": [
[
{
"node": "Markdown",
"type": "main",
"index": 0
}
]
]
},
"Markdown": {
"main": [
[
{
"node": "Send email",
"type": "main",
"index": 0
}
]
]
},
"Set Variables": {
"main": [
[
{
"node": "If recipients Empty?",
"type": "main",
"index": 0
}
]
]
},
"If recipients Empty?": {
"main": [
[
{
"node": "Stop and Error",
"type": "main",
"index": 0
}
],
[
{
"node": "GitHub Trending",
"type": "main",
"index": 0
}
]
]
},
"Limit Top N": {
"main": [
[
{
"node": "GitHub Repo Readme",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "knYWO6K2TJ83te3L"
},
"versionId": "d7eba448-8323-4914-b680-b10aea2c533d",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "L791u8q7du3EUAl7",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
githubApigooglePalmApismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
github-trending. Uses httpRequest, chainLlm, lmChatGoogleGemini, emailSend. Event-driven trigger; 15 nodes.
Source: https://github.com/datawhalechina/handy-n8n/blob/d0d1f6dbb65815de8b1433dd671482f25e76122b/workflows/c06/github-trending.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This template attempts to replicate OpenAI's DeepResearch feature which, at time of writing, is only available to their pro subscribers.
How it Works
My workflow 53. Uses formTrigger, httpRequest, lmChatOpenAi, form. Event-driven trigger; 74 nodes.
It transforms a single text prompt into a fully scripted, visually rich video with AI-generated images and voiceovers, then distributes it across multiple social media platforms. Content Creators & Yo
AI Competition – Small Business Problems – Rebound Email. Uses httpRequest, chainLlm, outputParserStructured, lmChatOpenAi. Event-driven trigger; 25 nodes.