This workflow follows the Form → Form Trigger 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": "ASO Analyzer",
"nodes": [
{
"parameters": {
"formTitle": "ASO Analyzer",
"formDescription": "=Enter your app details and upload Google Play screenshots (4-8 PNG/JPG images) to get a full ASO analysis report",
"formFields": {
"values": [
{
"fieldLabel": "App Name"
},
{
"fieldLabel": "App Category"
},
{
"fieldLabel": "Main Competitor App"
},
{
"fieldLabel": "=Your Email",
"fieldType": "email"
},
{
"fieldLabel": "Your App Screenshots",
"fieldType": "file",
"acceptFileTypes": "=image/png,image/jpeg,image/jpg",
"requiredField": true
},
{
"fieldLabel": "Competitor App Screenshots",
"fieldType": "file",
"acceptFileTypes": "image/png,image/jpeg,image/jpg",
"requiredField": true
}
]
},
"options": {}
},
"type": "n8n-nodes-base.formTrigger",
"typeVersion": 2.5,
"position": [
-208,
16
],
"id": "7f013436-0e4c-40ad-90bd-c27c21dfb902",
"name": "On form submission"
},
{
"parameters": {
"url": "=https://r.jina.ai/https://play.google.com/store/search?q={{ $json['App Name'] }}&c=apps&hl=en&gl=us",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=<redacted-credential>"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
320,
16
],
"id": "b198b848-2f39-4685-8b47-92b4fa064291",
"name": "Scrape Google Play"
},
{
"parameters": {
"modelId": {
"__rl": true,
"value": "gpt-4o-mini",
"mode": "id"
},
"responses": {
"values": [
{
"role": "system",
"content": "=You are Marcus Chen, a senior ASO consultant. You write \ndetailed, human-sounding audit reports based on real data. \nYou are direct, specific, and never use generic filler \nphrases. You always back up your points with specific \nexamples from the data provided. You never say things like \n\"In conclusion\" or \"It is worth noting\". You write like a \nhuman expert, not an AI.\nWhen analyzing visual data, you have access to scored JSON for both the user's app AND the competitor. Use both to make REAL comparisons, not generic advice. Never invent screenshots that don't exist in the data \u2014 if you only have one screenshot per app, only reference that one."
},
{
"content": "=You are Marcus Chen, a senior ASO consultant with 12 years \nof hands-on experience growing apps on Google Play Store. \nYou've helped over 200 apps reach the top 10 in their \ncategories. You write like a human consultant, not a robot \n\u2014 direct, opinionated, and specific.\n\nAnalyze this Google Play Store data:\n\nApp Name: {{ $('On form submission').item.json['App Name'] }}\nCategory: {{ $('On form submission').item.json['App Category'] }}\nMain Competitor: {{ $('On form submission').item.json['Main Competitor App'] }}\n\nRaw Store Data:\n{{ $('Scrape Google Play').item.json.data }}\n\nVisual Analysis Data \u2014 YOUR APP (from GPT-4o-mini Vision):\n{{ $('Analyze Your App').item.json[0].content[0].text }}\n\nVisual Analysis Data \u2014 COMPETITOR (from GPT-4o-mini Vision):\n{{ $('Analyze Competitor').item.json[0].content[0].text }}\n\nWrite a consultant-style ASO audit report. Be brutally \nhonest. Don't sugarcoat problems. Use specific examples \nfrom the data. Write like you're talking to the app owner \ndirectly.\n\nStructure your report exactly like this:\n---\nASO AUDIT REPORT\nApp: [insert the actual App Name from the data above]\nAudited by: Marcus Chen, Senior ASO Consultant\nDate: {{ $now.format('MMMM d, yyyy') }} (USE THIS EXACT DATE - DO NOT CHANGE IT)\n---\n\nTHE BOTTOM LINE\n[Write 2-3 sentences giving your overall honest gut reaction \nto this app's current ASO health. Be direct.]\n\nKEYWORD STRATEGY\nWhat's working:\n[List 2-3 things with specific examples from the data]\n\nWhat's broken:\n[List 3-4 specific keyword problems with examples]\n\nKeywords you're completely missing:\n[List 8-10 high-value keywords this app should be targeting \nwith estimated monthly search volumes]\n\nKeyword Score: [X/10] \u2014 [one sentence explanation]\n\nTITLE & METADATA\nCurrent title problems:\n[Be specific about what's wrong \u2014 character count, missing \nkeywords, unclear value proposition etc]\n\nRewritten title suggestion:\n[Provide 3 different title options with explanation of why \neach works]\n\nMetadata Score: [X/10]\n\nDESCRIPTION AUDIT\nFirst 3 lines (most critical):\n[Analyse the opening lines specifically \u2014 this is what \nusers see before clicking \"more\"]\n\nFull description problems:\n[List specific issues with examples from actual description]\n\nRewritten opening paragraph:\n[Write an improved version of the first paragraph]\n\nDescription Score: [X/10]\n\nCOMPETITOR ANALYSIS vs {{ $('On form submission').item.json['Main Competitor App'] }}\n[Compare specifically \u2014 what are they doing better? \nWhat weaknesses can this app exploit? Be specific with \nexamples. AT LEAST 150 WORDS HERE \u2014 do not skimp on this section.]\n\nRATINGS & REVIEWS HEALTH\n[Analyse the ratings, review patterns, common complaints \nand praise from the scraped data]\n\nVISUAL ASSETS COMPARISON\nYou have visual analysis data for BOTH your app and the competitor's app. Use both to write a real side-by-side comparison.\n\nYour App's Visual Score Breakdown:\n- Hook Strength: [use hook_strength from YOUR APP JSON]/25\n- Visual Hierarchy: [use visual_hierarchy from YOUR APP JSON]/25\n- Feature Communication: [use feature_communication from YOUR APP JSON]/25\n- Brand Consistency: [use brand_consistency from YOUR APP JSON]/25\n- Total Visual Score: [use total from YOUR APP JSON]/100\n\nCompetitor's Visual Score Breakdown:\n- Hook Strength: [use hook_strength from COMPETITOR JSON]/25\n- Visual Hierarchy: [use visual_hierarchy from COMPETITOR JSON]/25\n- Feature Communication: [use feature_communication from COMPETITOR JSON]/25\n- Brand Consistency: [use brand_consistency from COMPETITOR JSON]/25\n- Total Visual Score: [use total from COMPETITOR JSON]/100\n\nHead-to-head verdict:\nLooking at the two scores side by side, who's winning visually and by how much? Be specific about which categories show the biggest gap. If your app loses, say so directly. If your app wins, don't be smug about it \u2014 point out where competitor still does something right.\n\nWhere competitor is doing something better:\n[Use the COMPETITOR's strengths array. For each strength, explain in 1-2 sentences what your app could learn or steal from this approach. Be tactical, not generic.]\n\nWhere your app has the edge:\n[Use YOUR APP's strengths array. For each strength, explain how to lean into it harder against this competitor specifically.]\n\nYour weakest visual areas (urgent fixes):\n[Use YOUR APP's weaknesses array. For each weakness, give a specific concrete fix. Reference the competitor's approach if it solves that exact weakness.]\n\nVisual verdict in one paragraph:\nQuote the one_line_verdict from YOUR APP's analysis, then add 3-4 sentences contextualizing it against the competitor's positioning. End with what the app owner should do THIS WEEK to close the visual gap.\n\nQUICK WIN ACTION PLAN\nPriority 1 (Do this week):\n[Specific action with expected impact]\n\nPriority 2 (Do this month):\n[Specific action with expected impact]\n\nPriority 3 (Do this quarter):\n[Specific action with expected impact]\n\nFINAL ASO HEALTH SCORE\n[Score breakdown by category]\nTitle & Keywords: [X/20]\nDescription: [X/20]\nRatings & Reviews: [X/20]\nVisual Assets: [X/20] (use the Visual Score Breakdown above to inform this score)\nUpdate Frequency: [X/20]\nTOTAL: [X/100]\n\nCONSULTANT'S FINAL NOTE\n[Write 3-4 sentences as if you're finishing a consulting \ncall. Personal, direct, motivating but realistic.]\n---"
}
]
},
"builtInTools": {},
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 2.1,
"position": [
1856,
0
],
"id": "1acbe346-4b0a-4fcc-9665-1efbae664135",
"name": "Message a model",
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "1KB4aanzc0YFjDIoxBKh8v0fupKQ0IFHmDkhRWRtZrME",
"mode": "list",
"cachedResultName": "ASO Reports",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1KB4aanzc0YFjDIoxBKh8v0fupKQ0IFHmDkhRWRtZrME/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Sheet1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1KB4aanzc0YFjDIoxBKh8v0fupKQ0IFHmDkhRWRtZrME/edit#gid=0"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"App Name": "={{ $('On form submission').item.json['App Name'] }}",
"Category": "={{ $('On form submission').item.json['App Category'] }}",
"Competitor": "={{ $('On form submission').item.json['Main Competitor App'] }}",
"Date": "={{ $now.format('dd/MM/yyyy') }}",
"ASO Report": "={{ $json.output[0].content[0].text }}"
},
"matchingColumns": [],
"schema": [
{
"id": "App Name",
"displayName": "App Name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Category",
"displayName": "Category",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Competitor",
"displayName": "Competitor",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Date",
"displayName": "Date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "ASO Report",
"displayName": "ASO Report",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
2160,
16
],
"id": "a799d34b-9104-4e0f-b743-ba71d7b81707",
"name": "Append row in sheet",
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "41de9e47-d8f6-4437-8be9-b6a51908a730",
"leftValue": "={{ $json.data }}",
"rightValue": "={{ $('On form submission').item.json['App Name'] }}",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
144,
16
],
"id": "d1f67450-5476-482f-8bbb-710b16fbff43",
"name": "App Exists?"
},
{
"parameters": {
"url": "=https://r.jina.ai/https://play.google.com/store/search?q={{ $json['App Name'] }}&c=apps&hl=en&gl=us",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=<redacted-credential>"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
-16,
16
],
"id": "2b2546b9-3fab-49b3-b811-4feb96ad3c50",
"name": "Check App Exists"
},
{
"parameters": {
"operation": "completion",
"completionTitle": "App Not Found",
"completionMessage": "=Sorry, we couldn't find \"{{ $('On form submission').item.json['App Name'] }}\" on Google Play Store. Please check the spelling and try again.",
"options": {}
},
"type": "n8n-nodes-base.form",
"typeVersion": 2.5,
"position": [
320,
208
],
"id": "486e89c2-fcee-41d9-8c76-ddb3e67f7b8d",
"name": "Form"
},
{
"parameters": {
"operation": "completion",
"completionTitle": "Report Generated Successfully! \ud83c\udf89",
"completionMessage": "=\u2705 Your ASO Report for \"{{ $('On form submission').item.json['App Name'] }}\" has been generated and saved successfully!",
"options": {}
},
"type": "n8n-nodes-base.form",
"typeVersion": 2.5,
"position": [
2816,
16
],
"id": "45f3012d-f770-40fe-a2b7-cd89d9b92e2f",
"name": "Form1"
},
{
"parameters": {
"sendTo": "={{ $('On form submission').item.json['Your Email'] }}",
"subject": "=Your ASO Audit Report for {{ $('On form submission').item.json['App Name'] }}",
"message": "={{ $('Markdown').item.json.data }}",
"options": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
2592,
16
],
"id": "1fe701df-e1d0-4ca5-ad13-fd797f0bcb03",
"name": "Send a message",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"mode": "markdownToHtml",
"markdown": "={{ $('Message a model').item.json.output[0].content[0].text }}",
"options": {}
},
"type": "n8n-nodes-base.markdown",
"typeVersion": 1,
"position": [
2368,
16
],
"id": "8a807d07-3338-404c-84d5-150fa751362c",
"name": "Markdown"
},
{
"parameters": {
"resource": "image",
"operation": "analyze",
"modelId": {
"__rl": true,
"value": "gpt-4o-mini",
"mode": "list",
"cachedResultName": "GPT-4O-MINI"
},
"text": "=You are a senior visual ASO consultant analyzing app store screenshots.\n\nThis is a screenshot from a mobile app's Google Play listing. Analyze it on these criteria and return ONLY a JSON object with no other text:\n\n{\n \"hook_strength\": <number 1-25 \u2014 does it stop the scroll in 1 second?>,\n \"visual_hierarchy\": <number 1-25 \u2014 does the eye flow naturally?>,\n \"feature_communication\": <number 1-25 \u2014 is it clear what the app does?>,\n \"brand_consistency\": <number 1-25 \u2014 color/font/mood quality>,\n \"total\": <sum of above, max 100>,\n \"strengths\": [\"specific strength 1\", \"specific strength 2\"],\n \"weaknesses\": [\"specific weakness 1\", \"specific weakness 2\"],\n \"one_line_verdict\": \"<single brutally honest sentence>\"\n}\n\nBe brutally honest. Judge purely on visual design principles. Do not use brand recognition. Return JSON only \u2014 no prose, no explanation, no markdown code fences.",
"inputType": "base64",
"binaryPropertyName": "Your_App_Screenshots",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 2.1,
"position": [
1216,
16
],
"id": "5f524fcf-95a1-4c23-9324-18ffca4f5dcc",
"name": "Analyze Your App",
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"resource": "image",
"operation": "analyze",
"modelId": {
"__rl": true,
"value": "gpt-4o-mini",
"mode": "list",
"cachedResultName": "GPT-4O-MINI"
},
"text": "=You are a senior visual ASO consultant analyzing app store screenshots.\n\nThis is a screenshot from a mobile app's Google Play listing. Analyze it on these criteria and return ONLY a JSON object with no other text:\n\n{\n \"hook_strength\": <number 1-25 \u2014 does it stop the scroll in 1 second?>,\n \"visual_hierarchy\": <number 1-25 \u2014 does the eye flow naturally?>,\n \"feature_communication\": <number 1-25 \u2014 is it clear what the app does?>,\n \"brand_consistency\": <number 1-25 \u2014 color/font/mood quality>,\n \"total\": <sum of above, max 100>,\n \"strengths\": [\"specific strength 1\", \"specific strength 2\"],\n \"weaknesses\": [\"specific weakness 1\", \"specific weakness 2\"],\n \"one_line_verdict\": \"<single brutally honest sentence>\"\n}\n\nBe brutally honest. Judge purely on visual design principles. Do not use brand recognition. Return JSON only \u2014 no prose, no explanation, no markdown code fences.",
"inputType": "base64",
"binaryPropertyName": "Competitor_App_Screenshots",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 2.1,
"position": [
1696,
16
],
"id": "be38e003-5df5-452e-bd53-1b7ac8390220",
"name": "Analyze Competitor",
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Get the form submission node which holds the original binaries\nconst formNode = $('On form submission').first();\n\n// Get all current items flowing through\nconst items = $input.all();\n\n// Build clean output items from scratch\nconst output = [];\n\nfor (const item of items) {\n // Build a fresh, properly structured item\n const newItem = {\n json: (item.json && typeof item.json === 'object' && !Array.isArray(item.json)) \n ? item.json \n : {},\n binary: item.binary || {}\n };\n \n // Copy ALL binary keys from the form trigger\n if (formNode.binary) {\n for (const key in formNode.binary) {\n newItem.binary[key] = formNode.binary[key];\n }\n }\n \n output.push(newItem);\n}\n\nreturn output;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
592,
16
],
"id": "bfd87306-ade9-4640-8f3f-07813e225ddb",
"name": "Attach Screenshots 1"
},
{
"parameters": {
"jsCode": "// Get the form submission node which holds the original binaries\nconst formNode = $('On form submission').first();\n\n// Get all current items flowing through\nconst items = $input.all();\n\n// Build clean output items from scratch\nconst output = [];\n\nfor (const item of items) {\n // Build a fresh, properly structured item\n const newItem = {\n json: (item.json && typeof item.json === 'object' && !Array.isArray(item.json)) \n ? item.json \n : {},\n binary: item.binary || {}\n };\n \n // Copy ALL binary keys from the form trigger\n if (formNode.binary) {\n for (const key in formNode.binary) {\n newItem.binary[key] = formNode.binary[key];\n }\n }\n \n output.push(newItem);\n}\n\nreturn output;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1488,
16
],
"id": "29f2dfa4-27a7-45d9-abd1-852b7720ed7d",
"name": "Attach Screenshots 2"
},
{
"parameters": {
"resource": "image",
"operation": "analyze",
"modelId": {
"__rl": true,
"value": "gpt-4o-mini",
"mode": "list",
"cachedResultName": "GPT-4O-MINI"
},
"text": "=You are a screenshot verification assistant. The user claims this screenshot is from a Google Play app called \"{{ $('On form submission').item.json['App Name'] }}\".\n\nYour task: determine if the screenshot actually shows that app's interface, or if it shows something completely different.\n\nIMPORTANT GUIDELINES:\n- For well-known apps (Spotify, Instagram, TikTok, etc), recognize their distinctive UI elements (colors, logos, layout patterns)\n- For lesser-known/indie apps, you may not recognize them \u2014 in that case, check if the screenshot looks like a legitimate mobile app screenshot at all (UI elements, mobile dimensions, app-like content)\n- A meme, photo, texture, document, or random image is NOT a valid app screenshot\n- A screenshot from a CLEARLY different famous app (e.g., named \"Spotify\" but shows Instagram's UI) is a mismatch\n\nReturn ONLY this JSON, nothing else:\n{\n \"is_valid_screenshot\": true/false,\n \"appears_to_match_app\": true/false,\n \"confidence\": 0-100,\n \"what_i_see\": \"brief description of what's actually in the image\",\n \"verdict\": \"match\" or \"mismatch\" or \"unrecognizable\" or \"not_a_screenshot\"\n}\n\nBe lenient with indie apps you don't recognize \u2014 set appears_to_match_app to true if it's a plausible mobile app screenshot. Be strict only when you can clearly tell it's the WRONG well-known app or not an app screenshot at all.",
"inputType": "base64",
"binaryPropertyName": "=Your_App_Screenshots",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 2.1,
"position": [
816,
16
],
"id": "7e643308-d17c-45a8-8e1f-c4fbceac6dfa",
"name": "Verify App Match",
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const formNode = $('On form submission').first();\nconst items = $input.all();\nconst output = [];\n\nfor (const item of items) {\n const newItem = {\n json: (item.json && typeof item.json === 'object' && !Array.isArray(item.json)) \n ? item.json \n : {},\n binary: item.binary || {}\n };\n \n if (formNode.binary) {\n for (const key in formNode.binary) {\n newItem.binary[key] = formNode.binary[key];\n }\n }\n \n output.push(newItem);\n}\n\nreturn output;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1024,
192
],
"id": "ee0f850d-0798-4066-a08f-661dbb440087",
"name": "Attach Screenshots 3"
},
{
"parameters": {
"httpMethod": "POST",
"path": "aso-analyze",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-192,
624
],
"id": "bbd450e9-6c9d-48e2-9297-c564c3663325",
"name": "Webhook"
}
],
"connections": {
"On form submission": {
"main": [
[
{
"node": "Check App Exists",
"type": "main",
"index": 0
}
]
]
},
"Scrape Google Play": {
"main": [
[
{
"node": "Attach Screenshots 1",
"type": "main",
"index": 0
}
]
]
},
"Message a model": {
"main": [
[
{
"node": "Append row in sheet",
"type": "main",
"index": 0
}
]
]
},
"App Exists?": {
"main": [
[
{
"node": "Scrape Google Play",
"type": "main",
"index": 0
}
],
[
{
"node": "Form",
"type": "main",
"index": 0
}
]
]
},
"Append row in sheet": {
"main": [
[
{
"node": "Markdown",
"type": "main",
"index": 0
}
]
]
},
"Check App Exists": {
"main": [
[
{
"node": "App Exists?",
"type": "main",
"index": 0
}
]
]
},
"Send a message": {
"main": [
[
{
"node": "Form1",
"type": "main",
"index": 0
}
]
]
},
"Markdown": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
},
"Analyze Your App": {
"main": [
[
{
"node": "Attach Screenshots 2",
"type": "main",
"index": 0
}
]
]
},
"Analyze Competitor": {
"main": [
[
{
"node": "Message a model",
"type": "main",
"index": 0
}
]
]
},
"Attach Screenshots 1": {
"main": [
[
{
"node": "Verify App Match",
"type": "main",
"index": 0
}
]
]
},
"Attach Screenshots 2": {
"main": [
[
{
"node": "Analyze Competitor",
"type": "main",
"index": 0
}
]
]
},
"Verify App Match": {
"main": [
[
{
"node": "Attach Screenshots 3",
"type": "main",
"index": 0
}
]
]
},
"Attach Screenshots 3": {
"main": [
[
{
"node": "Analyze Your App",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate"
},
"versionId": "07ca48de-0976-45ba-9f78-27bfd89ef260",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "7djSuITOEWUFkj0f",
"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.
gmailOAuth2googleSheetsOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow streamlines App Store Optimisation (ASO) by analysing submitted app details to deliver actionable insights on visibility and performance, helping mobile developers and marketers enhance their app's discoverability without manual research. It processes form submissions to scrape Google Play data via HTTP requests, leverages OpenAI for intelligent analysis of keywords and rankings, and logs results directly into Google Sheets for easy tracking. The key step involves the AI-powered evaluation that generates tailored recommendations, saving hours of tedious analysis.
Use this workflow when launching or optimising apps on Google Play and needing quick, data-driven ASO feedback from user-submitted details. Avoid it for iOS-exclusive apps or scenarios requiring real-time monitoring beyond periodic submissions. Common variations include adapting the HTTP requests for Apple App Store scraping or integrating Gmail notifications for instant report delivery.
About this workflow
ASO Analyzer. Uses formTrigger, httpRequest, openAi, googleSheets. Event-driven trigger; 17 nodes.
Source: https://github.com/Muhammad-Abu-Bakar/aso-analyzer/blob/main/workflow/aso-analyzer-workflow.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.
Wait Http. Uses stickyNote, httpRequest, lmChatOpenAi, googleSheets. Event-driven trigger; 17 nodes.
Create viral TikTok videos effortlessly — no editing skills required!
n8n Graphic Design Team. Uses googleSheets, googleDrive, httpRequest, outputParserStructured. Event-driven trigger; 37 nodes.
Turn any topic into a ready-to-study Anki deck. This workflow generates vocabulary flashcards with AI images and native pronunciation, then sends the .apkg file straight to your inbox.
Filter Summarize. Uses googleSheetsTool, formTrigger, stickyNote, form. Event-driven trigger; 20 nodes.