This workflow corresponds to n8n.io template #13967 — we link there as the canonical source.
This workflow follows the Agent → Google Sheets 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "cbcaf93f-97a8-42ad-9432-3274adad1d21",
"name": "Browser MCP Tool (Comment)",
"type": "n8n-nodes-browser-mcp.browserToolTool",
"position": [
-2576,
1392
],
"parameters": {
"baseUrl": "http://localhost:8931/mcp",
"toolName": "={{ $fromAI('Tool_Name', ``, 'json') }}",
"driverUrl": "={{ $json.url }}",
"operation": "callTool",
"toolArguments": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Tool_Arguments', ``, 'json') }}"
},
"typeVersion": 1
},
{
"id": "cf2ed5ea-c05d-4579-8fe8-7640817a6c05",
"name": "DeepSeek Model (Comment)",
"type": "@n8n/n8n-nodes-langchain.lmChatDeepSeek",
"position": [
-2728,
1384
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "63642b70-0478-4e5f-a6f5-291ae7bdb56b",
"name": "Loop Through Accounts",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-5200,
1085
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "fb399fce-5a85-4723-8a88-9be0488b53e2",
"name": "Remove Shadowbanned",
"type": "n8n-nodes-base.filter",
"position": [
-5872,
1085
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9d19ef8f-14f5-4732-8f19-0917dfb52c6f",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.shadowban}}",
"rightValue": "No"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "03a53c01-9a8a-4595-a5a0-af44e3f35c8b",
"name": "Browser MCP Tool (Post)",
"type": "n8n-nodes-browser-mcp.browserToolTool",
"position": [
-2600,
880
],
"parameters": {
"baseUrl": "http://localhost:8931/mcp",
"toolName": "={{ $fromAI('Tool_Name', ``, 'json') }}",
"driverUrl": "={{ $json.url }}",
"operation": "callTool",
"toolArguments": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Tool_Arguments', ``, 'json') }}"
},
"typeVersion": 1
},
{
"id": "c27b8cd1-71fa-4ea3-b79d-1ae8c6a266cb",
"name": "DeepSeek Model (Post)",
"type": "@n8n/n8n-nodes-langchain.lmChatDeepSeek",
"position": [
-2728,
880
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "3638b6b1-fd81-4e76-b938-599a870d61e8",
"name": "Reddit Comment Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueRegularOutput",
"position": [
-2736,
1160
],
"parameters": {
"text": "=Run autonomous Reddit community analysis and engagement.\n\nTarget:\n{{$json.target}}\n\nObjective:\n- Analyze recent posts in the target subreddit.\n- Decide whether to skip, comment, or create a new text post based on subreddit rules and content relevance.\n- If commenting or posting, generate and submit a high-quality, human-like contribution that adds value (e.g., insightful response or discussion starter).\n- If no safe or valuable engagement is possible, skip and provide a reason.\n- Always retrieve user profile details including post karma, comment karma, total karma.\n- Return the permalink if commented or posted (or a skip reason if skipped), along with karma details in a structured JSON format.",
"options": {
"maxIterations": 20,
"systemMessage": "=SYSTEM DIRECTIVE \u2014 FULL AUTONOMY\nYou are an autonomous Reddit user.\nAct like a careful, normal human Redditor.\nDo NOT ask the user:\n* What to post\n* Whether to comment or post\n* For approval or clarification\nMake all decisions by reading the subreddit and its rules.\n-----------------------------------\nA. READ SUBREDDIT RULES (MANDATORY)\n-----------------------------------\n1. Open the subreddit URL using browser_navigate({url}).\n2. Take browser_snapshot({}).\n3. Read:\n * Rules section\n * Pinned posts\n * Sidebar/About\nFind out:\n* Are comments allowed?\n* Are text posts allowed?\n* Any karma/account limits?\n* Any banned content (promo, links, AI, memes, etc.)\n* Required tone/format\nIf rules block safe participation \u2192\nReturn:\nSKIPPED \u2014 subreddit rules prevent safe participation\n-----------------------------------\nB. SCAN POSTS\n-----------------------------------\n1. Scroll and review posts using browser_wait(1500\u20133000ms between scrolls).\n2. Take multiple browser_snapshot({}) while scrolling.\n3. Ignore pinned, mod posts, ads.\n4. Prefer posts with:\n * 0\u201310 comments\n * Clear question or discussion\n * Real human content\nPick ONE post only.\n-----------------------------------\nC. ANALYZE POST\n-----------------------------------\n1. Open the post using browser_click({ref, element}).\n2. Take browser_snapshot({}).\n3. Read title, body, top comments.\nUnderstand OP intent:\n* Asking for help\n* Feedback\n* Discussion\n* Sharing experience\n-----------------------------------\nD. HUMAN SCROLL BEHAVIOR (REQUIRED)\n-----------------------------------\nDo NOT act immediately.\n1. Scroll slowly.\n2. browser_wait(1500\u20133000ms between scrolls).\n3. Take multiple snapshots while scrolling.\n4. Observe post patterns and tone.\nIgnore:\n* Pinned/mod posts\n* Ads\nPrefer:\n* 0\u201310 comments\n* Real questions\n* Genuine discussion\n-----------------------------------\nE. DECIDE (CHOOSE ONE)\n-----------------------------------\n1. SKIP\n * Rules restrict participation\n * Spam/low effort\n * Nothing valuable to add\n2. COMMENT\n * Allowed by rules\n * You can add real value\n3. CREATE TEXT POST\n * Text posts allowed\n * Follows rules\n * Adds value\n-----------------------------------\nF. WRITING RULES\n-----------------------------------\n* Sound human\n* No emojis\n* No promo\n* No links unless allowed\n* Match subreddit tone\n* Avoid extreme claims\n* Slightly imperfect is fine\n* Comments: 1-2 short sentences\nKeep it natural and short.\n-----------------------------------\nG. BROWSER RULES\n-----------------------------------\nAllowed actions only:\n* browser_navigate({url})\n* browser_snapshot({})\n* browser_click({ref, element})\n* browser_type({text, ref, element})\n* browser_wait({milliseconds})\n* browser_evaluate({function})\nRules:\n* ref + element required for click/type\n* element must be a string (textbox, button, etc.)\n* Always snapshot before interacting\n* Never assume UI state\nPosting steps:\n1. Click input\n2. Type content\n3. Submit\n4. Copy permalink\n-----------------------------------\nH. PARTICIPATE (IF DECIDED)\n-----------------------------------\nIf SKIP: Proceed to I.\nIf COMMENT or POST:\n1. Follow writing rules.\n2. Use browser actions to interact (click/type/submit).\n3. After submission, copy permalink.\n-----------------------------------\nI. GET USER KARMA (FINAL STEP, ALWAYS)\n-----------------------------------\n1. browser_navigate({url: 'https://www.reddit.com/user/YOUR_USERNAME_HERE'}). Replace YOUR_USERNAME_HERE with the actual username.\n2. Take browser_snapshot({}).\n3. Use browser_evaluate({function}) to parse and extract:\n * post_karma: Numerical value from post karma element.\n * comment_karma: Numerical value from comment karma element.\n * total_karma: Sum of post_karma + comment_karma.\n * status: 'comment_success' when new \u2018comment_success\u2019 or 'comment_failed' or 'skipped'.\n * comment: Any relevant note (e.g., empty string if none).\nIf extraction fails, default to 0 for karmas and note in comment.\n-----------------------------------\nJ. FINAL OUTPUT\n-----------------------------------\n* Return ONLY a valid JSON array:\n[\n {\n \"username\": \"string\",\n \"post_karma\": number,\n \"comment_karma\": number,\n \"comment_post\":\"string\"\n \"comment_content\": \"string\",\n \"coments_Permalink\":\"string\",\n \"status\": \"string\",\n \"total_karma\": number\n }\n]\n* If participated: Include permalink in comment field if applicable.\nNever invent rules.\nNever break subreddit rules.\nNever ask user for guidance.",
"enableStreaming": true
},
"promptType": "define"
},
"retryOnFail": true,
"typeVersion": 3.1
},
{
"id": "287d4168-9fc1-4d30-824d-890048a0727b",
"name": "Reddit Post Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-2736,
656
],
"parameters": {
"text": "=Run autonomous Reddit community analysis and posting.\n\nTarget:\n{{$json.target}}\n\nMode:\nNEW POST ONLY \u2014 commenting is forbidden\n",
"options": {
"maxIterations": 20,
"systemMessage": "=\u26a0\ufe0f SYSTEM DIRECTIVE \u2014 FULL AUTONOMY / POST-ONLY MODE\n\nYou are an autonomous Reddit community participant.\nYour ONLY allowed engagement is creating a NEW TEXT POST.\nYou must NEVER comment on existing posts.\n\nYou must NOT ask the user for:\n- Post ideas\n- Approval\n- Clarification\n- Formatting guidance\n\nAll decisions must be made independently using subreddit content and rules.\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nA. SUBREDDIT RULE DISCOVERY (MANDATORY)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n1. Navigate to the subreddit URL provided by the user.\n2. Take a browser_snapshot().\n3. Locate and read:\n - Subreddit rules\n - Sidebar / About section\n - Pinned moderator posts\n\nDetermine internally:\n- Are TEXT POSTS allowed?\n- Are there posting restrictions (karma, account age)?\n- Are flairs required?\n- Are certain topics banned?\n\nIf text posting is unsafe:\n\u2192 STOP and return:\n\"SKIPPED \u2014 subreddit rules do not allow safe posting\"\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nB. EXISTING POST TITLE ANALYSIS (CRITICAL)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n1. Scroll through recent posts (at least 20\u201330).\n2. Collect and analyze visible POST TITLES only.\n3. Identify:\n - Repeated questions\n - Trending topics\n - Recently answered discussions\n - Overused formats (e.g., \u201cWhat do you think about\u2026\u201d, \u201cBeginner question\u201d)\n\nYou MUST avoid creating a post that:\n- Duplicates a recent title or topic\n- Slightly rephrases an existing thread\n- Asks something already active in the last 24\u201372 hours\n\nIf no unique angle exists:\n\u2192 SKIP immediately\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nC. COMMUNITY & CONTENT GAP ANALYSIS\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n1. Analyze tone and depth of existing posts.\n2. Identify ONE clear content gap:\n - A missing perspective\n - A deeper follow-up not yet discussed\n - A practical example missing from current threads\n - A thoughtful, rule-compliant discussion prompt\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nD. POST DECISION GATE (CRITICAL)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nProceed ONLY if:\n- Topic is clearly distinct from recent titles\n- Adds new value\n- Fits subreddit norms\n- Can be expressed as a TEXT post\n\nIf any condition fails:\n\u2192 SKIP without posting\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nE. POST GENERATION RULES (STRICT)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n- Create ONE new TEXT post\n- Title must be:\n \u2022 Unique\n \u2022 Natural\n \u2022 Non-clickbait\n- Body:\n \u2022 1\u20133 short paragraphs\n \u2022 Human tone\n \u2022 No emojis\n \u2022 No self-promotion\n \u2022 No links unless allowed\n \u2022 No mention of AI or automation\n- Slight imperfection is acceptable\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nBROWSER ACTION RULES (STRICT)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nAllowed actions only:\n- browser_navigate(arguments{url})\n- browser_snapshot(arguments{})\n- browser_click(arguments{ref, element})\n- browser_type(arguments{text, ref, element})\n- browser_wait(arguments{milliseconds})\n- browser_evaluate(arguments{function})\n\nRules:\n- \"element\" and \"ref\" is REQUIRED for click and type\n- \"element\" must be a string like textbox or button\n- Never assume UI state\n- Always snapshot before interacting\n\n\nPosting workflow:\n1. Click \"Create Post\"\n2. Select TEXT post\n3. Enter title\n4. Enter body\n5. Submit post\n6. Copy post permalink\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nG. FINAL OUTPUT\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n- If post created:\n \u2192 Return post permalink\n- If skipped:\n \u2192 Return \"SKIPPED \u2014 recent posts already cover this topic\"\n\n\u26a0\ufe0f COMMENTING IS FORBIDDEN\n\u26a0\ufe0f NEVER repeat existing topics\n\u26a0\ufe0f NEVER violate subreddit rules\n\u26a0\ufe0f NEVER ask the user for input"
},
"promptType": "define"
},
"typeVersion": 3.1
},
{
"id": "3702ca55-26be-421b-b0e8-1b3a890bb76e",
"name": "Close Multilogin Profile",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1712,
1085
],
"parameters": {
"url": "=https://launcher.mlx.yt:45001/api/v1/profile/stop/p/{{ $json.profile_id }}",
"options": {
"redirect": {
"redirect": {}
},
"allowUnauthorizedCerts": true
},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "f0ba210a-c868-4abc-9617-3d176f0e21d1",
"name": "Update Sheet - Posts",
"type": "n8n-nodes-base.googleSheets",
"position": [
-2160,
760
],
"parameters": {
"columns": {
"value": {
"row_number": "={{ $json.row_number }}",
"time_of_post": "={{$json.time_of_post}}",
"posts_made_today": "={{$json.posts_made_today }}",
"last_allocated_ip": "={{$json.last_allocated_ip}}"
},
"schema": [
{
"id": "proxy_provider",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "proxy_provider",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "creation_ip",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "creation_ip",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "last_allocated_ip",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "last_allocated_ip",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "multilogin_profile_name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "multilogin_profile_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "multilogin_folder_id",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "multilogin_folder_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "multilogin_profile_id",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "multilogin_profile_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "account_email",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "account_email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "account_id",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "account_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "account_password",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "account_password",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "shadowban?",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "shadowban?",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "karma",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "karma",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "age",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "age",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "dms_daily_limit",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "dms_daily_limit",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "dms_sent_today",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "dms_sent_today",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "posts_made_today",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "posts_made_today",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "time_of_post",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "time_of_post",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "comments_made_today",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "comments_made_today",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "time_of_comment",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "time_of_comment",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "posts_links",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "posts_links",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "comments_links",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "comments_links",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"row_number"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 277853152,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/10rlYT2b1VNbbwgfd5rXuIHDrihlf1spgkol7GvX0Oaw/edit#gid=277853152",
"cachedResultName": "Reddit Accounts"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "10rlYT2b1VNbbwgfd5rXuIHDrihlf1spgkol7GvX0Oaw",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/10rlYT2b1VNbbwgfd5rXuIHDrihlf1spgkol7GvX0Oaw/edit?usp=drivesdk",
"cachedResultName": "Boomerang + LeadAssist | Demand Generation | Reddit DM's"
},
"authentication": "serviceAccount"
},
"typeVersion": 4.7
},
{
"id": "b5372777-d2d9-4561-9b9e-f523a6916265",
"name": "Update Sheet - Comments",
"type": "n8n-nodes-base.googleSheets",
"position": [
-2160,
1160
],
"parameters": {
"columns": {
"value": {
"karma": "={{$json.total_karma}}",
"row_number": "={{ $json.row_number }}",
"posts_links": "={{ $json.posts_links }}",
"comments_links": "={{ $json.comments_links }}",
"time_of_comment": "={{ $json.time_of_comment }}",
"last_allocated_ip": "={{ $json.last_allocated_ip }}",
"comments_made_today": "={{ $json.comments_made_today}}"
},
"schema": [
{
"id": "proxy_provider",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "proxy_provider",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "creation_ip",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "creation_ip",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "last_allocated_ip",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "last_allocated_ip",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "multilogin_profile_name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "multilogin_profile_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "multilogin_folder_id",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "multilogin_folder_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "multilogin_profile_id",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "multilogin_profile_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "account_email",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "account_email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "account_id",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "account_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "account_password",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "account_password",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "shadowban?",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "shadowban?",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "karma",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "karma",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "age",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "age",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "dms_daily_limit",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "dms_daily_limit",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "dms_sent_today",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "dms_sent_today",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "posts_made_today",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "posts_made_today",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "time_of_post",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "time_of_post",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "comments_made_today",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "comments_made_today",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "time_of_comment",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "time_of_comment",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "posts_links",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "posts_links",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "comments_links",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "comments_links",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"row_number"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 277853152,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/10rlYT2b1VNbbwgfd5rXuIHDrihlf1spgkol7GvX0Oaw/edit#gid=277853152",
"cachedResultName": "Reddit Accounts"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "10rlYT2b1VNbbwgfd5rXuIHDrihlf1spgkol7GvX0Oaw",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/10rlYT2b1VNbbwgfd5rXuIHDrihlf1spgkol7GvX0Oaw/edit?usp=drivesdk",
"cachedResultName": "Boomerang + LeadAssist | Demand Generation | Reddit DM's"
},
"authentication": "serviceAccount"
},
"typeVersion": 4.7
},
{
"id": "dc08fac8-8cea-48db-9504-a53f37f8fe42",
"name": "Run workflow on schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-6768,
1085
],
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"typeVersion": 1.3
},
{
"id": "1d7721b3-bfc9-4104-b7d7-e883a0e8eba6",
"name": "Sort by Action Type",
"type": "n8n-nodes-base.sort",
"position": [
-5424,
1085
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"fieldName": "action"
}
]
}
},
"typeVersion": 1
},
{
"id": "3aa8dac1-7b62-410c-b0f2-a001e1147b91",
"name": "Get Profile ID for Cleanup",
"type": "n8n-nodes-base.code",
"position": [
-1936,
960
],
"parameters": {
"jsCode": "try {\n return $('Parse Post Result').all()\n} catch (error) {\n return $('Parse Comment Result').all()\n}\n"
},
"typeVersion": 2
},
{
"id": "ae7eeeeb-aa69-4c45-8e88-c2454d476a83",
"name": "Parse Post Result",
"type": "n8n-nodes-base.code",
"position": [
-2384,
760
],
"parameters": {
"jsCode": "const comment_account = $('Route Post or Comment').all()[0].json;\nconst profile_id=$('Open Multilogin Profile').first().json.data.id\nconst extractedIP = $('Get Proxy Exit IP').first().json.origin\nconst check = $input.all()[0].json.output?.toLowerCase().includes('successfully');\ncomment_account.last_allocated_ip=extractedIP\n\nconst result = [];\n\nif (check) {\n\n const updatedAccount = {\n ...comment_account,\n posts_made_today: Number(comment_account.posts_made_today || 0) + 1,\n time_of_post: new Date().toISOString(),\n last_action_status: \"post_success\",\n profile_id:profile_id\n };\n\n result.push({ json: updatedAccount });\n\n} else {\n\n // If failed, return original account with failure status\n result.push({\n json: {\n ...comment_account,\n last_action_status: \"post_failed\",\n profile_id:profile_id\n }\n });\n}\n\nreturn result;\n\n"
},
"typeVersion": 2
},
{
"id": "aa886ecf-66e2-4438-ab9f-497ef647d43c",
"name": "Parse Comment Result",
"type": "n8n-nodes-base.code",
"position": [
-2384,
1160
],
"parameters": {
"jsCode": "const comment_account = $('Route Post or Comment').all()[0].json;\n\nconst extractedIP = $('Get Proxy Exit IP').first().json.origin\nconst profile_id=$('Open Multilogin Profile').first().json.data.id\n\n// Extract fields safely from broken AI JSON\nconst x=$input.first().json.output\nconst usernameMatch = x.match(/\"username\"\\s*:\\s*\"([^\"]+)/);\nconst username = usernameMatch ? usernameMatch[1] : null;\n\nconst commentMatch = x.match(/\"comment_content\"\\s*:\\s*\"([^\"]+)/);\nconst comment_content = commentMatch ? commentMatch[1] : null;\n\n\nconst comment_postMatch = x.match(/\"comment_post\"\\s*:\\s*\"([^\"]+)/);\nconst posts_links = comment_postMatch ? comment_postMatch[1] : null;\n\nconst comment_permalingMatch = x.match(/\"coments_Permalink\"\\s*:\\s*\"([^\"]+)/);\nconst comments_links = comment_permalingMatch ? comment_permalingMatch[1] : null;\n\nconst postKarmaMatch = x.match(/\"post_karma\"\\s*:\\s*(\\d+)/);\nconst post_karma = postKarmaMatch ? Number(postKarmaMatch[1]) : 0;\n\nconst commentKarmaMatch = x.match(/\"comment_karma\"\\s*:\\s*(\\d+)/);\nconst comment_karma = commentKarmaMatch ? Number(commentKarmaMatch[1]) : 0;\n\nconst totalKarmaMatch = x.match(/\"total_karma\"\\s*:\\s*(\\d+)/);\nconst total_karma = totalKarmaMatch ? Number(totalKarmaMatch[1]) : 0;\n\nconst statusMatch = x.match(/\"status\"\\s*:\\s*\"([^\"]+)/);\nconst status = statusMatch ? statusMatch[1] : \"comment_failed\";\ncomment_account.last_allocated_ip=extractedIP\n// Build final object\nreturn [{\n json: {\n ...comment_account,\n username,\n posts_links,\n comment_content,\n comments_links,\n post_karma,\n comment_karma,\n total_karma,\n last_action_status: status === \"comment_success\" ? \"comment_success\" : \"comment_failed\",\n profile_id,\n comments_made_today: Number(comment_account.comments_made_today || 0) + (status === \"comment_success\" ? 1 : 0),\n time_of_comment: new Date().toISOString()\n }\n}];"
},
"typeVersion": 2
},
{
"id": "1a8b561c-f9fa-4ad0-b312-b61221489316",
"name": "Route Post or Comment",
"type": "n8n-nodes-base.switch",
"position": [
-2960,
960
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Post",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0108ef46-185e-4c85-85a3-53f7da0e3677",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.action }}",
"rightValue": "post"
}
]
},
"renameOutput": true
},
{
"outputKey": "Comment",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "6c0a3817-57f8-4231-b298-454ff6976ca7",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{$json.action }}",
"rightValue": "comment"
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.4
},
{
"id": "e6403ec7-03cd-44aa-aa02-e652d97a8d32",
"name": "Prepare Agent Input",
"type": "n8n-nodes-base.set",
"position": [
-3184,
960
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "64c52a8c-19e8-4cb6-9a6a-0d765540acee",
"name": "url",
"type": "string",
"value": "={{ $('Get Browser WebSocket URL').first().json.webSocketDebuggerUrl }}"
},
{
"id": "b992ef92-2684-44a6-89c4-14634c44f45f",
"name": "target",
"type": "string",
"value": "https://old.reddit.com/r/AskReddit/new/"
},
{
"id": "751eb529-529d-4b73-a635-1e69020f0dca",
"name": "action",
"type": "string",
"value": "={{ $('Loop Through Accounts').item.json.action }}"
},
{
"id": "cde9790a-d60f-4063-b1ec-dae513b20f13",
"name": "row_number",
"type": "number",
"value": "={{ $('Loop Through Accounts').item.json.row_number }}"
},
{
"id": "64fa79e2-53ec-4efd-8c0a-81e1681f4c09",
"name": "comments_made_today",
"type": "string",
"value": "={{ $('Loop Through Accounts').item.json.comments_made_today }}"
},
{
"id": "2cd6b9ec-07a3-4873-bd56-8a1e2b8180a9",
"name": "posts_made_today",
"type": "string",
"value": "={{ $('Loop Through Accounts').item.json.posts_made_today }}"
},
{
"id": "40e1bc78-3222-4420-be28-a8978b58d196",
"name": "last_allocated_ip",
"type": "string",
"value": "={{ $('Loop Through Accounts').item.json.last_allocated_ip }}"
},
{
"id": "b1da3a0d-654f-4ca6-b9ed-788272994f22",
"name": "creation_ip",
"type": "string",
"value": "={{ $('Loop Through Accounts').item.json.creation_ip }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "1891b028-6a5d-472b-824c-0688b9ee474a",
"name": "Get Browser WebSocket URL",
"type": "n8n-nodes-base.httpRequest",
"position": [
-3408,
960
],
"parameters": {
"url": "={{ $json.localhost }}",
"options": {}
},
"typeVersion": 4.3
},
{
"id": "36fa72d9-7215-4a5c-8e61-0d9d6622e29e",
"name": "Build Debug URL",
"type": "n8n-nodes-base.set",
"position": [
-3632,
960
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "bbf7762d-3108-41f8-bfdc-fa10e9b40371",
"name": "localhost",
"type": "string",
"value": "=http://127.0.0.1:{{ $json.data.port }}/json/version"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "efce8dc9-b7ba-44dc-9b30-a226131e4f9a",
"name": "Open Multilogin Profile",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
-4080,
960
],
"parameters": {
"url": "=https://launcher.mlx.yt:45001/api/v2/profile/f/YOUR_FOLDER_ID/p/{{$('Loop Through Accounts').item.json.multilogin_profile_id}}/start",
"options": {
"timeout": 30000,
"allowUnauthorizedCerts": true
},
"sendQuery": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"queryParameters": {
"parameters": [
{
"name": "automation_type",
"value": "playwright"
},
{
"name": "headless_mode",
"value": "false"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
}
]
}
},
"notesInFlow": false,
"typeVersion": 4.3
},
{
"id": "39ebeb5b-e1ef-4ae4-b0e0-f6d9c0de722c",
"name": "Calculate Actions",
"type": "n8n-nodes-base.code",
"position": [
-5648,
1085
],
"parameters": {
"jsCode": "const accounts = $input.all().map(i => i.json);\nconst result = [];\n\nconst now = new Date();\nconst currentHour = now.getHours();\n\n// ---- ACTIVE HOURS 0 \u2192 12 ----\nif (currentHour >= 12) {\n return [{\n json: {\n action: \"none\",\n wait_minutes: 5\n }\n }];\n}\n\n// ---- RANDOM ----\nfunction randomBetween(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\n// shuffle accounts\naccounts.sort(() => Math.random() - 0.5);\n\n// pick random accounts\nconst activeAccounts = accounts.slice(0, randomBetween(3, 8));\n\nfor (const acc of activeAccounts) {\n\n const lastPostTime = acc.time_of_post ? new Date(acc.time_of_post) : null;\n const lastCommentTime = acc.time_of_comment ? new Date(acc.time_of_comment) : null;\n\n const postDelay = randomBetween(60,180) * 60 * 1000; // 1\u20133 hours\n const commentDelay = randomBetween(30,120) * 60 * 1000; // 30\u2013120 min\n\n const actionType = Math.random() < 0.5 ? \"post\" : \"comment\";\n\n // ---- POST CHECK ----\n if (\n actionType === \"post\" &&\n (!lastPostTime || (now - lastPostTime) >= postDelay)\n ) {\n\n result.push({\n json: {\n ...acc,\n action: \"post\",\n wait_minutes: 5,\n scheduled_hour: currentHour\n }\n });\n\n }\n\n // ---- COMMENT CHECK ----\n if (\n actionType === \"comment\" &&\n (!lastCommentTime || (now - lastCommentTime) >= commentDelay)\n ) {\n\n result.push({\n json: {\n ...acc,\n action: \"comment\",\n wait_minutes: 5,\n scheduled_hour: currentHour\n }\n });\n\n }\n\n}\n\n// prevent empty output\nif (result.length === 0) {\n return [{\n json: {\n action: \"none\",\n wait_minutes: 5\n }\n }];\n}\n\nreturn result;"
},
"typeVersion": 2
},
{
"id": "99ae7a0e-974a-4e90-8c19-cb6aa5927149",
"name": "Sticky Note Action timing",
"type": "n8n-nodes-base.stickyNote",
"position": [
-5728,
640
],
"parameters": {
"color": 7,
"width": 404,
"height": 232,
"content": "## Action timing\n\nThis step picks a small random set of eligible accounts (3\u20138), assigns either post or comment, and enforces cooldowns based on each account\u2019s last activity. If nothing is eligible, it returns `action: none` and retries later."
},
"typeVersion": 1
},
{
"id": "37a9bfc0-8507-491b-8c83-df4f31ef1029",
"name": "Delay Between Accounts",
"type": "n8n-nodes-base.wait",
"position": [
-4976,
960
],
"parameters": {
"unit": "minutes",
"amount": "={{ $json.wait_minutes}}"
},
"typeVersion": 1.1
},
{
"id": "09793fa7-9d20-4bbf-92dd-b8ddf41ada22",
"name": "Extract Account Fields",
"type": "n8n-nodes-base.set",
"position": [
-6096,
1085
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "3945b285-3ab8-40f6-b2ec-b724f9f8951f",
"name": "row_number",
"type": "number",
"value": "={{ $json.row_number }}"
},
{
"id": "12f40092-15be-497f-87fc-73748cab02af",
"name": "IP",
"type": "string",
"value": "={{ $json.creation_ip }}"
},
{
"id": "3dd45370-f9ef-4b2f-91dd-9c99d64dc593",
"name": "UserID",
"type": "string",
"value": "={{ $json.account_id }}"
},
{
"id": "e15b96ca-45b9-49b6-89cb-7b0bfe1fcc98",
"name": "Password",
"type": "string",
"value": "={{ $json.account_password }}"
},
{
"id": "dcf8ce17-690c-4d97-9e16-90da23964406",
"name": "multilogin_profile_id",
"type": "string",
"value": "={{ $json.multilogin_profile_id }}"
},
{
"id": "b89e4e04-aa15-4f0b-b271-49c02e347989",
"name": "shadowban",
"type": "string",
"value": "={{ $json['shadowban?'] }}"
},
{
"id": "874b5301-e7ed-46bf-ae3a-ce71b5520410",
"name": "comments_made_today",
"type": "string",
"value": "={{ $json.comments_made_today }}"
},
{
"id": "bde7585a-89c1-497e-8eb7-7f46ef9065a1",
"name": "time_of_comment",
"type": "string",
"value": "={{ $json.time_of_comment }}"
},
{
"id": "6e099df9-d88d-4509-ba49-6e1941de4cb2",
"name": "posts_made_today",
"type": "string",
"value": "={{ $json.posts_made_today }}"
},
{
"id": "9403e34b-b366-4af6-9394-ed605c3f88f4",
"name": "time_of_post",
"type": "string",
"value": "={{ $json.time_of_post }}"
},
{
"id": "67e71e3b-c611-4c5f-a388-01c7a6a39cfa",
"name": "last_allocated_ip",
"type": "string",
"value": "={{ $json.last_allocated_ip }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "149f6f52-4c9e-4db1-811e-86d1959bae6e",
"name": "Compare IP Addresses",
"type": "n8n-nodes-base.code",
"position": [
-4528,
888
],
"parameters": {
"jsCode": "// 1\ufe0f\u20e3 Get httpbin single IP\nconst extractedIP = $input.first().json.origin\nconst myItems = $('Extract Account Fields').all();\nconst time=$('Loop Through Accounts').first().json.wait_minutes\n// 3\ufe0f\u20e3 Check if ANY matches\nconst isMatch = myItems.some(item => \n item.json.last_allocated_ip.trim() === extractedIP || item.json.last_allocated_ip.trim()==extractedIP\n);\n\n\n\n// 4\ufe0f\u20e3 Return ONLY ONE item\nreturn [\n {\n json: {\n httpbin_ip: extractedIP,\n wait_minutes:time,\n ip_match: isMatch\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "ea16ae4a-8fc4-4905-babd-a74e0f507023",
"name": "Check IP Uniqueness",
"type": "n8n-nodes-base.if",
"position": [
-4304,
960
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "2e4c50b1-a3e9-4feb-bfd8-2da330e81388",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.ip_match }}",
"rightValue": false
}
]
}
},
"typeVersion": 2.3
},
{
"id": "3f84a552-eb50-4866-a0a6-d557e3d14965",
"name": "Filter Valid Accounts",
"type": "n8n-nodes-base.filter",
"position": [
-6320,
1085
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "e10bb9f6-4613-4c73-bd52-dccb5b31f510",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.multilogin_profile_id }}",
"rightValue": ""
},
{
"id": "47b23737-49a0-423f-a0fc-d5d8887a085d",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.proxy_provider }}",
"rightValue": "GridPanel"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "540ed453-d0ef-4009-94eb-e8ab93d28eef",
"name": "Wait for Browser Init",
"type": "n8n-nodes-base.wait",
"position": [
-3856,
960
],
"parameters": {
"amount": 10
},
"typeVersion": 1.1
},
{
"id": "0c9f06df-9876-4b39-9176-eda7a9bd4e19",
"name": "Get Proxy Exit IP",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
-4752,
888
],
"parameters": {
"url": "https://httpbin.org/get",
"options": {
"proxy": "http://YOUR_PROXY_USER:YOUR_PROXY_PASS@YOUR_PROXY_HOST:PORT"
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{}
]
}
},
"retryOnFail": true,
"typeVersion": 4.3
},
{
"id": "ae063318-080c-4e9f-a978-5848e2a38b43",
"name": "Read Reddit Accounts",
"type": "n8n-nodes-base.googleSheets",
"position": [
-6544,
1085
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "No",
"lookupColumn": "shadowban?"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 277853152,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/10rlYT2b1VNbbwgfd5rXuIHDrihlf1spgkol7GvX0Oaw/edit#gid=277853152",
"cachedResultName": "Reddit Accounts"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "10rlYT2b1VNbbwgfd5rXuIHDrihlf1spgkol7GvX0Oaw",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/10rlYT2b1VNbbwgfd5rXuIHDrihlf1spgkol7GvX0Oaw/edit?usp=drivesdk",
"cachedResultName": "Boomerang + LeadAssist | Demand Generation | Reddit DM's"
},
"authentication": "serviceAccount"
},
"typeVersion": 4.7
},
{
"id": "faf22746-5b5a-492d-b817-457f9e478d39",
"name": "Sticky Note Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-6816,
416
],
"parameters": {
"color": 5,
"width": 520,
"height": 620,
"content": "## How it works\n\nThis workflow runs on a schedule, reads Reddit account rows from Google Sheets, and keeps only valid non-shadowbanned records. It then selects a small random batch, checks proxy exit IP uniqueness, and starts each account in Multilogin.\n\nFor each account, the flow opens a Browser MCP session and routes to either the post or comment AI agent based on the calculated action. The result is parsed, activity counters and timestamps are updated in Google Sheets, the profile is closed, and the loop continues with the next account.\n\n## Setup steps\n\n1. Connect Google Sheets credentials and confirm the required columns exist in the account sheet.\n2. Configure Multilogin API access, folder ID, and profile IDs.\n3. Set your proxy credentials in `Get Proxy Exit IP`.\n4. Confirm Browser MCP is reachable at `http://localhost:8931/mcp`.\n5. Configure DeepSeek/model credentials and run one manual test.\n6. Set the schedule trigger interval and activate the workflow."
},
"typeVersion": 1
},
{
"id": "5cfdcd30-afeb-4f13-b658-a91985401075",
"name": "Sticky Note Filtering",
"type": "n8n-nodes-base.stickyNote",
"position": [
-6208,
656
],
"parameters": {
"color": 7,
"width": 392,
"height": 214,
"content": "## Account filtering\n\nReads account rows, extracts the fields used by downstream nodes, and keeps only records with valid profile/proxy data. Shadowbanned or incomplete rows are removed before batching."
},
"typeVersion": 1
},
{
"id": "8f277bb5-708a-4f97-8bc5-f97ffe5a273c",
"name": "Sticky Note Proxy",
"type": "n8n-nodes-base.stickyNote",
"position": [
-4800,
592
],
"parameters": {
"color": 7,
"width": 392,
"height": 214,
"content": "## Proxy validation\n\nCalls httpbin to get the active exit IP, compares it with previously assigned IPs, and only continues when the IP is unique for this run. Non-unique IPs are skipped."
},
"typeVersion": 1
},
{
"id": "4d7dd1ac-194b-44e8-aec0-a2a1b482f788",
"name": "Sticky Note Multilogin",
"type": "n8n-nodes-base.stickyNote",
"position": [
-4128,
640
],
"parameters": {
"color": 7,
"width": 488,
"height": 214,
"content": "## Browser session setup\n\nStarts the Multilogin profile, waits for browser initialization, fetches the debug endpoint, and prepares the WebSocket URL used by Browser MCP tools."
},
"typeVersion": 1
},
{
"id": "0b63de7f-ce35-4b7e-baee-1ead9b8ff8e9",
"name": "Sticky Note AI Agents",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2960,
224
],
"parameters": {
"color": 7,
"width": 472,
"height": 214,
"content": "## AI execution\n\nRoutes each account by action (`post` or `comment`) to the matching agent. Both agents use the same Browser MCP tool and return structured output for parsing."
},
"typeVersion": 1
},
{
"id": "4125df22-0897-47b3-8e09-20ea38a702a7",
"name": "Sticky Note Tracking",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2384,
224
],
"parameters": {
"color": 7,
"width": 472,
"height": 230,
"content": "## Tracking and cleanup\n\nParses agent output, updates Google Sheets counters/timestamps/links, closes the active Multilogin profile, and continues to the next account in the batch."
},
"typeVersion": 1
}
],
"connections": {
"Build Debug URL": {
"main": [
[
{
"node": "Get Browser WebSocket URL",
"type": "main",
"index": 0
}
]
]
},
"Calculate Actions": {
"main": [
[
{
"node": "Sort by Action Type",
"type": "main",
"index": 0
}
]
]
},
"Get Proxy Exit IP": {
"main": [
[
{
"node": "Compare IP Addresses",
"type": "main",
"index": 0
}
]
]
},
"Parse Post Result": {
"main": [
[
{
"node": "Update Sheet - Posts",
"type": "main",
"index": 0
}
]
]
},
"Reddit Post Agent": {
"main": [
[
{
"node": "Parse Post Result",
"type": "main",
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Run workflow on schedule fires on a set interval to pull Reddit accounts from a Google Sheets spreadsheet (filtered to exclude shadowbanned accounts) Smart action calculator randomly selects 3–8 accounts and decides whether each should post or comment, respecting cooldown timers…
Source: https://n8n.io/workflows/13967/ — 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 workflow automates the complete blog publishing process. It removes manual work from content creation, image generation, category management, and WordPress publishing by using AI and n8n. It help
This n8n automation workflow automates the creation, scripting, production, and posting of YouTube videos. It leverages AI (OpenAI), image generation (PIAPI), video rendering (Shotstack), and platform
This workflow is designed for: Content creators and marketers E-commerce and product-based businesses Agencies producing social media visuals and videos Automation builders looking for AI-powered crea
This workflow is for beauty salons who want consistent, high‑quality social media content without writing every post manually. It also suits agencies and automation builders who manage multiple beauty
Created by: Peyton Leveillee Last updated: October 2025