- type: group
steps:
- type: ask
param: basic-choice
message: >-
⚡️ Select any input for content generation or select an option.
💡 Claude 3.5 Sonnet produces better quality but is slower.
🤖 I'll do it all automatically and let you know when I need your input
during the process.
options:
- label: ✅ USE THIS VIDEO
value: video
- label: 📌 KEYWORD OR TOPIC
value: keywords
- label: 📝 TEXT
value: text
- label: 🌐 OTHER URL
value: url
- $custom
default: ''
optionsInvalid: false
- type: jump
to: START VIDEO
condition: '{{basic-choice}} = video'
- to: START URL
condition: '{{basic-choice}} = url'
type: jump
- to: START TEXT
condition: '{{basic-choice}} = text'
type: jump
- to: START KEYWORDS
condition: '{{basic-choice}} = keywords'
type: jump
- steps:
- steps:
- type: navigate
url: '{{basic-choice}}'
silent: true
waitForIdle: false
- type: jump
to: START VIDEO
condition: '{{basic-choice}} =~ ^https:\/\/www\.youtube\.com\/watch.*'
label: YT VIDEO
type: group
- steps:
- type: calc
func: set
param: webpage
format: ''
value: '{{basic-choice}}'
- to: TRY TO FETCH
type: jump
condition: '{{basic-choice}} =~ ^(?!.*youtube).*https?:\/\/.*'
label: OTHER URL
type: group
- steps:
- param: context
type: calc
func: set
format: ''
value: '{{basic-choice}}'
- to: FORM QUERY MESSAGE
type: jump
condition: '{{basic-choice}} =~ [\s\S]{121,}'
label: TO TEXT (>121)
type: group
- steps:
- param: query
type: calc
func: set
format: ''
value: '{{basic-choice}}'
- to: KEYWORDS-OPTION
type: jump
condition: '{{basic-choice}} =~ ^[\s\S]{1,120}$'
label: TO KEYWORDS (<120)
type: group
condition: '{{basic-choice-option}} = $custom'
type: group
label: ⚙️ YOUTUBE VID MENU
condition: '{{url}} =~ ^https:\/\/www\.youtube\.com\/watch.*'
- steps:
- message: >-
⚡️ Submit any input for content generation or select an option.
💡 Claude 3.5 Sonnet produces better quality but is slower.
🤖 I'll do it all automatically and let you know when I need your input
during the process.
options:
- label: ✅ THIS WEBPAGE
value: page
- label: 📌 KEYWORD OR TOPIC
value: keywords
- label: 📝 TEXT
value: text
- label: 🌐 OTHER URL
value: url
- label: 📹 YT VIDEO
value: video
- $custom
type: ask
param: basic-choice
default: ''
optionsInvalid: false
- type: jump
to: START VIDEO
condition: '{{basic-choice}} = video'
- type: jump
to: START URL
condition: '{{basic-choice}} = url'
- type: jump
to: START TEXT
condition: '{{basic-choice}} = text'
- type: jump
to: START KEYWORDS
condition: '{{basic-choice}} = keywords'
- to: START PAGE
condition: '{{basic-choice}} = page'
type: jump
- steps:
- steps:
- type: navigate
url: '{{basic-choice}}'
waitForIdle: false
silent: true
- type: jump
to: START VIDEO
type: group
condition: '{{basic-choice}} =~ ^https:\/\/www\.youtube\.com\/watch.*'
label: YT VIDEO
- steps:
- type: calc
func: set
param: webpage
format: ''
value: '{{basic-choice}}'
- type: jump
to: TRY TO FETCH
type: group
condition: '{{basic-choice}} =~ ^(?!.*youtube).*https?:\/\/.*'
label: OTHER URL
- steps:
- type: calc
func: set
param: context
format: ''
value: '{{basic-choice}}'
- type: jump
to: FORM QUERY MESSAGE
type: group
condition: '{{basic-choice}} =~ [\s\S]{121,}'
label: TO TEXT (>121)
- steps:
- type: calc
func: set
param: query
format: ''
value: '{{basic-choice}}'
- type: jump
to: KEYWORDS-OPTION
type: group
condition: '{{basic-choice}} =~ ^[\s\S]{1,120}$'
label: TO KEYWORDS (<120)
- steps:
- type: jump
to: START PAGE
condition: '{{basic-choice}} = {{page}}'
label: TO {{PAGE}}
type: group
type: group
condition: '{{basic-choice-option}} = $custom'
label: ⚙️ ANY PAGE MENU
type: group
- steps:
- message: 💬 Enter Keyword or Topic
options: null
type: ask
param: query
default: ''
- param: keywords-option
options:
- label: ⚡️ QUICK
value: quick
- label: 🦾 ADVANCED
value: advanced
type: ask
message: ''
default: ''
optionsInvalid: false
label: KEYWORDS-OPTION
- steps:
- param: information
value: '{{serp {{query}}}}'
type: calc
func: set
format: ''
- func: serp.extract-links
to: links
type: calc
from: information
- type: say
message: |-
✅ URLs extracted:
- [{{links.0.title}}]({{links.0.url}})
- [{{links.1.title}}]({{links.1.url}})
- [{{links.2.title}}]({{links.2.url}})
- [{{links.3.title}}]({{links.3.url}})
- [{{links.4.title}}]({{links.4.url}})
- [{{links.5.title}}]({{links.5.url}})
- [{{links.6.title}}]({{links.6.url}})
- [{{links.7.title}}]({{links.7.url}})
- steps:
- param: startpage
value: '{{url}}'
type: calc
func: set
format: ''
- steps:
- url: '{{links.0.url}}'
type: navigate
waitForIdle: false
silent: true
- param: pagetext
value: '{{page}}'
type: calc
func: set
format: ''
- type: js
code: |2-
function extractMarkdownHeaders(args) {
const pagetext = args.pagetext;
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
const matches = pagetext.match(headersRegex);
if (matches) {
const headers = matches.map(header => `"${header.trim()}"`).join(', ');
console.log('Markdown headers:', headers);
return headers;
} else {
console.log('No Markdown headers found.');
return ' ';
}
}
return extractMarkdownHeaders(args)
param: singleoutline
label: HEADINGS EXTRACTION
args: pagetext
silent: true
- func: list-add
index: last
list: headings
type: calc
item: singleoutline
- param: relevant
value: '{{page {{query}} limit=15%}}'
type: calc
func: set
format: ''
- code: |
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// DELETE H1-H4
let cleanedText = text.replace(headersRegex, '');
// DELETE SHORT LINES
cleanedText = cleanedText.split('\n').filter(line => line.length >= 25).join('\n');
// DELETE \n
return cleanedText.replace(/\n/g, ' ');
}
return cleanText(args.relevant);
label: CONTEXT EXTRACTION
type: js
args: relevant
param: relevant
silent: true
- list: cleantext
type: calc
func: list-add
index: last
item: relevant
label: 1ST URL
type: group
- steps:
- url: '{{links.1.url}}'
type: navigate
waitForIdle: false
silent: true
- type: calc
func: set
param: pagetext
format: ''
value: '{{page}}'
- type: js
code: |2-
function extractMarkdownHeaders(args) {
const pagetext = args.pagetext;
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
const matches = pagetext.match(headersRegex);
if (matches) {
const headers = matches.map(header => `"${header.trim()}"`).join(', ');
console.log('Markdown headers:', headers);
return headers;
} else {
console.log('No Markdown headers found.');
return ' ';
}
}
return extractMarkdownHeaders(args)
args: pagetext
param: singleoutline
label: HEADINGS EXTRACTION
silent: true
- type: calc
func: list-add
index: last
list: headings
item: singleoutline
- type: calc
func: set
param: relevant
format: ''
value: '{{page {{query}} limit=15%}}'
- type: js
code: |
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// DELETE H1-H4
let cleanedText = text.replace(headersRegex, '');
// DELETE SHORT LINES
cleanedText = cleanedText.split('\n').filter(line => line.length >= 25).join('\n');
// DELETE \n
return cleanedText.replace(/\n/g, ' ');
}
return cleanText(args.relevant);
args: relevant
param: relevant
label: CONTEXT EXTRACTION
silent: true
- type: calc
func: list-add
index: last
list: cleantext
item: relevant
label: 2ND URL
type: group
- steps:
- url: '{{links.3.url}}'
type: navigate
waitForIdle: false
silent: true
- type: calc
func: set
param: pagetext
format: ''
value: '{{page}}'
- type: js
code: |2-
function extractMarkdownHeaders(args) {
const pagetext = args.pagetext;
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
const matches = pagetext.match(headersRegex);
if (matches) {
const headers = matches.map(header => `"${header.trim()}"`).join(', ');
console.log('Markdown headers:', headers);
return headers;
} else {
console.log('No Markdown headers found.');
return ' ';
}
}
return extractMarkdownHeaders(args)
args: pagetext
param: singleoutline
label: HEADINGS EXTRACTION
silent: true
- type: calc
func: list-add
index: last
list: headings
item: singleoutline
- type: calc
func: set
param: relevant
format: ''
value: '{{page {{query}} limit=15%}}'
- type: js
code: |
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// DELETE H1-H4
let cleanedText = text.replace(headersRegex, '');
// DELETE SHORT LINES
cleanedText = cleanedText.split('\n').filter(line => line.length >= 25).join('\n');
// DELETE \n
return cleanedText.replace(/\n/g, ' ');
}
return cleanText(args.relevant);
args: relevant
param: relevant
label: CONTEXT EXTRACTION
silent: true
- type: calc
func: list-add
index: last
list: cleantext
item: relevant
label: 3RD URL
type: group
- url: '{{startpage}}'
type: navigate
waitForIdle: false
silent: true
label: HEADINGS AND CONTEXT
type: group
- message: ⏳ Preparing context, wait a bit...
type: say
- type: gpt
prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
Act as a very proficient SEO and high end copywriter.
I want you to combine three texts into one, covering all important
details.
- Focus on creating in-depth, informative paragraphs. Ensure that
the content is factually accurate and verifiable.
- Keep as much useful information as you can.
- Avoid filler phrases and notes.
- Do not repeat any instructions or my task.
- Respond only with the combined text, without including any notes.
[TEXTS TO COMBINE]:
1. {{cleantext.0}}
2. {{cleantext.1}}
3. {{cleantext.2}}
[INFORMATIVE COMBINED TEXT]:
label: CREATE CONTEXT
param: context
silent: true
- prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
Act as a very proficient SEO and high end copywriter.
I want you to ntegrate all of the URLs into relevant locations in
[TEXT]using Markdown formatting: [title](url).
- [{{links.0.title}}]({{links.0.url}}): {{links.0.description}}
- [{{links.1.title}}]({{links.1.url}}): {{links.1.description}}
- [{{links.2.title}}]({{links.2.url}}): {{links.2.description}}
- [{{links.3.title}}]({{links.3.url}}): {{links.3.description}}
- [{{links.4.title}}]({{links.4.url}}): {{links.4.description}}
- [{{links.5.title}}]({{links.5.url}}): {{links.5.description}}
- [{{links.6.title}}]({{links.6.url}}): {{links.6.description}}
- [{{links.7.title}}]({{links.7.url}}): {{links.7.description}}
Instructions:
- Do not modify the [TEXT].
- Each URL should be integrated only once.
- Modify the [titles] for better integration.
- Spread the URLs throughout the text.
- Avoid putting too many markdown links in one section.
[TEXT]:
{{context}}
[TEXT WITH MARKDOWN LINKS]:
label: URLS TO CONTEXT
type: gpt
param: context
silent: true
- message: |-
✅ Context generated
```markdown
{{context}}
```
type: say
- prompt: >-
I want you to respond only in {{language}} and output a single list.
Pretend to be a SEO keyword research expert.
Read the [SERP] and [CONTEXT] that I will provide you and find top
20 LSI keywords in SERP and your internal knowledge, each containing
at least 2 words:
- Please identify and list LSI Keywords that are specifically
associated with [MY QUERY].
- When extracting these keywords, focus on finding terms that are
not just relevant in a broad sense but are specifically combined or
contextually linked with [MY QUERY] that I will provide you later.
- Response with only these LSI keywords, separated by commas.
- Do not add any notes, write only comma separated keywords.
- Do not echo my prompt.
[MY QUERY]: {{query}}
[SERP]:
- {{links.0.title}}: {{links.0.description}}
- {{links.1.title}}: {{links.1.description}}
- {{links.2.title}}: {{links.2.description}}
- {{links.3.title}}: {{links.3.description}}
- {{links.4.title}}: {{links.4.description}}
- {{links.5.title}}: {{links.5.description}}
- {{links.6.title}}: {{links.6.description}}
- {{links.7.title}}: {{links.7.description}}
[CONTEXT]:
{{context}}
[ONLY KEYWORDS]:
label: FIND KEYWORDS
type: gpt
param: keywords
silent: true
- message: |-
✅ LSI Keywords extracted from SERP
```markdown
{{keywords}}
```
type: say
condition: '{{keywords-option}} = quick'
label: QUICK SCENARIO
type: group
- steps:
- type: calc
func: set
param: information
format: ''
value: '{{serp {{query}}}}'
- type: calc
func: serp.extract-links
from: information
to: links
- message: |-
☑️ Main Query URLs extracted:
- [{{links.0.title}}]({{links.0.url}})
- [{{links.1.title}}]({{links.1.url}})
- [{{links.2.title}}]({{links.2.url}})
- [{{links.3.title}}]({{links.3.url}})
- [{{links.4.title}}]({{links.4.url}})
- [{{links.5.title}}]({{links.5.url}})
- [{{links.6.title}}]({{links.6.url}})
- [{{links.7.title}}]({{links.7.url}})
type: say
- steps:
- type: calc
func: set
param: startpage
format: ''
value: '{{url}}'
- steps:
- type: navigate
url: '{{links.0.url}}'
waitForIdle: false
silent: true
- type: calc
func: set
param: pagetext
format: ''
value: '{{page}}'
- type: js
code: |2-
function extractMarkdownHeaders(args) {
const pagetext = args.pagetext;
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
const matches = pagetext.match(headersRegex);
if (matches) {
const headers = matches.map(header => `"${header.trim()}"`).join(', ');
console.log('Markdown headers:', headers);
return headers;
} else {
console.log('No Markdown headers found.');
return ' ';
}
}
return extractMarkdownHeaders(args)
args: pagetext
param: singleoutline
label: HEADINGS EXTRACTION
silent: true
- type: calc
func: list-add
index: last
list: headings
item: singleoutline
- type: calc
func: set
param: relevant
format: ''
value: '{{page {{query}} limit=15%}}'
- type: js
code: |
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// DELETE H1-H4
let cleanedText = text.replace(headersRegex, '');
// DELETE SHORT LINES
cleanedText = cleanedText.split('\n').filter(line => line.length >= 25).join('\n');
// DELETE \n
return cleanedText.replace(/\n/g, ' ');
}
return cleanText(args.relevant);
args: relevant
param: relevant
label: CONTEXT EXTRACTION
silent: true
- type: calc
func: list-add
index: last
list: cleantext
item: relevant
type: group
label: 1ST URL
- steps:
- type: navigate
url: '{{links.1.url}}'
waitForIdle: false
silent: true
- type: calc
func: set
param: pagetext
format: ''
value: '{{page}}'
- type: js
code: |2-
function extractMarkdownHeaders(args) {
const pagetext = args.pagetext;
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
const matches = pagetext.match(headersRegex);
if (matches) {
const headers = matches.map(header => `"${header.trim()}"`).join(', ');
console.log('Markdown headers:', headers);
return headers;
} else {
console.log('No Markdown headers found.');
return ' ';
}
}
return extractMarkdownHeaders(args)
args: pagetext
param: singleoutline
label: HEADINGS EXTRACTION
silent: true
- type: calc
func: list-add
index: last
list: headings
item: singleoutline
- type: calc
func: set
param: relevant
format: ''
value: '{{page {{query}} limit=15%}}'
- type: js
code: |
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// DELETE H1-H4
let cleanedText = text.replace(headersRegex, '');
// DELETE SHORT LINES
cleanedText = cleanedText.split('\n').filter(line => line.length >= 25).join('\n');
// DELETE \n
return cleanedText.replace(/\n/g, ' ');
}
return cleanText(args.relevant);
args: relevant
param: relevant
label: CONTEXT EXTRACTION
silent: true
- type: calc
func: list-add
index: last
list: cleantext
item: relevant
type: group
label: 2ND URL
- steps:
- type: navigate
url: '{{links.3.url}}'
waitForIdle: false
silent: true
- type: calc
func: set
param: pagetext
format: ''
value: '{{page}}'
- type: js
code: |2-
function extractMarkdownHeaders(args) {
const pagetext = args.pagetext;
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
const matches = pagetext.match(headersRegex);
if (matches) {
const headers = matches.map(header => `"${header.trim()}"`).join(', ');
console.log('Markdown headers:', headers);
return headers;
} else {
console.log('No Markdown headers found.');
return ' ';
}
}
return extractMarkdownHeaders(args)
args: pagetext
param: singleoutline
label: HEADINGS EXTRACTION
silent: true
- type: calc
func: list-add
index: last
list: headings
item: singleoutline
- type: calc
func: set
param: relevant
format: ''
value: '{{page {{query}} limit=15%}}'
- type: js
code: |
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// DELETE H1-H4
let cleanedText = text.replace(headersRegex, '');
// DELETE SHORT LINES
cleanedText = cleanedText.split('\n').filter(line => line.length >= 25).join('\n');
// DELETE \n
return cleanedText.replace(/\n/g, ' ');
}
return cleanText(args.relevant);
args: relevant
param: relevant
label: CONTEXT EXTRACTION
silent: true
- type: calc
func: list-add
index: last
list: cleantext
item: relevant
type: group
label: 3RD URL
- type: navigate
url: '{{startpage}}'
waitForIdle: false
silent: true
type: group
label: HEADINGS AND CONTEXT
- message: ⏳ Preparing basic context, wait a bit...
type: say
- type: gpt
prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
Act as a very proficient SEO and high end copywriter.
I want you to combine three texts into one, covering all important
details.
- Focus on creating in-depth, informative paragraphs. Ensure that
the content is factually accurate and verifiable.
- Keep as much useful information as you can.
- Avoid filler phrases and notes.
- Do not repeat any instructions or my task.
- Respond only with the combined text, without including any notes.
[TEXTS TO COMBINE]:
1. {{cleantext.0}}
2. {{cleantext.1}}
3. {{cleantext.2}}
[INFORMATIVE COMBINED TEXT]:
param: context
label: CREATE CONTEXT
silent: true
- message: |-
☑️ Basic context generated
```markdown
{{context}}
```
type: say
- type: gpt
prompt: >-
I want you to respond only in {{language}} and output a single list.
Pretend to be a SEO keyword research expert.
Read the [SERP] and [CONTEXT] that I will provide you and find top
20 LSI keywords in SERP and your internal knowledge, each containing
at least 2 words:
- Please identify and list LSI Keywords that are specifically
associated with [MY QUERY].
- When extracting these keywords, focus on finding terms that are
not just relevant in a broad sense but are specifically combined or
contextually linked with [MY QUERY] that I will provide you later.
- Response with only these LSI keywords, separated by commas.
- Do not add any notes, write only comma separated keywords.
- Do not echo my prompt.
[MY QUERY]: {{query}}
[SERP]:
- {{links.0.title}}: {{links.0.description}}
- {{links.1.title}}: {{links.1.description}}
- {{links.2.title}}: {{links.2.description}}
- {{links.3.title}}: {{links.3.description}}
- {{links.4.title}}: {{links.4.description}}
- {{links.5.title}}: {{links.5.description}}
- {{links.6.title}}: {{links.6.description}}
- {{links.7.title}}: {{links.7.description}}
[CONTEXT]:
{{context}}
[ONLY KEYWORDS]:
param: keywords
label: FIND KEYWORDS
silent: true
- message: |-
☑️ Basic LSI Keywords extracted from SERP
```markdown
{{keywords}}
```
type: say
- message: ⏳ Generating 2 clarifying SERP queries...
type: say
- prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
You are a Research Agent. I need you to break down my search query
into two clarifying queries, the answers to which are necessary to
form a detailed response to the original search query.
Follow the instructions:
- Clarifying queries should include key words from the original
query to enhance readability and precision.
- Do not number the clarifying queries.
- The new clarifying queries should be brief, less than 6 words
each.
- Your response should consist of two lines - one question per line.
- Write nothing other than the clarifying questions.
- Do not repeat my command and instructions.
- Do not put your сlarifying queries in quotes.
My search query: {{query}}
2 brief clarifying queries:
label: FORM MINI QUERIES
param: queries
type: gpt
silent: true
- func: split
to: queries-list
delimiter: |+
type: calc
param: queries
- func: list-filter
match: empty
matched: remove
type: calc
list: queries-list
- message: |-
☑️ Clarifying queries generated
```markdown
{{queries}}
```
type: say
- message: ⏳ Researching extra information...
type: say
- steps:
- value: '{{serp {{queries-list.0}}}}'
type: calc
func: set
param: information
format: ''
- to: research1
type: calc
func: serp.extract-links
from: information
label: 1ST RESEARCH
type: group
- steps:
- value: '{{serp {{queries-list.1}}}}'
type: calc
func: set
param: information
format: ''
- to: research2
type: calc
func: serp.extract-links
from: information
label: 2ND RESEARCH
type: group
- message: |-
✅ Extra URLs added to research:
- [{{research1.0.title}}]({{research1.0.url}})
- [{{research1.1.title}}]({{research1.1.url}})
- [{{research1.2.title}}]({{research1.2.url}})
- [{{research1.3.title}}]({{research1.3.url}})
- [{{research2.0.title}}]({{research2.0.url}})
- [{{research2.1.title}}]({{research2.1.url}})
- [{{research2.2.title}}]({{research2.2url}})
- [{{research2.3.title}}]({{research2.3.url}})
type: say
- message: ⏳ Updating context, wait a bit...
type: say
- param: newcontext
value: >
{{research1.0.title}}: {{page {{query}} {{research1.0.url}}
limit=5%}}
{{research1.1.title}}: {{page {{query}} {{research1.1.url}}
limit=5%}}
{{research1.2.title}}: {{page {{query}} {{research1.2.url}}
limit=5%}}
{{research2.0.title}}: {{page {{query}} {{research2.0.url}}
limit=5%}}
{{research2.1.title}}: {{page {{query}} {{research2.2.url}}
limit=5%}}
{{research2.2.title}}: {{page {{query}} {{research2.2.url}}
limit=5%}}
label: COMBINE NEW INFO
type: calc
func: set
format: ''
- code: |
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// DELETE H1-H4
let cleanedText = text.replace(headersRegex, '');
// DELETE SHORT LINES
cleanedText = cleanedText.split('\n').filter(line => line.length >= 25).join('\n');
// DELETE \n
return cleanedText.replace(/\n/g, ' ');
}
return cleanText(args.newcontext);
type: js
args: newcontext
param: newcontext
silent: true
- prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
Act as a very proficient SEO and high end copywriter.
I want you to combine [OLD INFORMATION] with [NEW INFORMATION],
covering all important details.
- Do not delete any data from [OLD INFORMATION]; instead, complement
it with [NEW INFORMATION].
- Focus on creating in-depth, informative paragraphs. Ensure that
the content is factually accurate and verifiable.
- Keep as much useful information as you can.
- Avoid filler phrases and notes.
- Do not repeat any instructions or my task.
- Respond only with the combined text, without including any notes.
[OLD INFORMATION]:
{{context}}
[NEW INFORMATION]:
{{newcontext}}
[INFORMATIVE COMBINED TEXT]:
label: CONTEXT UPDATE
type: gpt
param: context
silent: true
- message: |-
✅ Context updated
```markdown
{{context}}
```
type: say
- message: ⏳ Updating keywords list, wait a bit...
type: say
- prompt: >-
I want you to respond only in {{language}} and output a single list.
Pretend you are an SEO keyword research expert.
I want you to add new LSI keywords to the [KEYWORDS LIST].
- Read the [KEYWORDS LIST] and new [SERP INFORMATION] that I will
provide to add some new LSI keywords to the list.
- Do not delete any keywords from [KEYWORDS LIST]..
- Please identify and add only new LSI Keywords that are
specifically associated with [MY QUERY].
- When extracting these keywords from the [SERP INFORMATION], focus
on finding terms that are not just relevant in a broad sense but are
specifically combined or contextually linked with [MY QUERY] that I
will provide you later.
- Response with only the [KEYWORDS LIST] with LSI keywords added in
the end and separated by commas.
- Do not add any notes.
- Do not echo my prompt.
[MY QUERY]: {{query}}
[OLD KEYWORDS LIST]: {{keywords}}
[SERP INFORMATION]:
- {{research1.0.title}}: {{research1.0.description}}
- {{research1.1.title}}: {{research1.1.description}}
- {{research1.2.title}}: {{research1.2.description}}
- {{research1.3.title}}: {{research1.3.description}}
- {{research2.0.title}}: {{research2.0.description}}
- {{research2.1.title}}:{{research2.1.description}}
- {{research2.2.title}}: {{research2.2.description}}
- {{research2.3.title}}: {{research2.3.description}}
[KEYWORDS LIST with new LSI keywords in the end]:
label: FIND NEW KEYWORDS
type: gpt
param: keywords
silent: true
- message: |-
✅ LSI KW list updated
```markdown
{{keywords}}
```
type: say
condition: '{{keywords-option}} = advanced'
label: ADVANCED
type: group
- steps:
- message: ⏳ Preparing outline, wait a bit...
type: say
- prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
I want you to act as a very proficient SEO and high end copywriter
and a blog post brief outline and a H1 blog title.
- I will provide you with the top SERP [OUTLINES] and [KEYWORDS]
from the SERP.
- Use [CONTEXT], [KEYWORDS] and [OUTLINES] as your outline basis.
- Use concise, keyword-rich headings and subheadings.
- Start with the H1 blog title, and do not use h1 anywhere else.
- I need an outline in my format, without section contents.
- Do not use more than 4 sections, introduction and conclusion
sections included.
- Avoid naming the First section simply as 'Introduction', and do
not title the Last section merely as 'Conclusion'.
- Do not use words 'Introduction' and 'Conclusion' in your outline.
- There shoud be no subsections or bullet points in the introduction
and conclusion sections.
- Display the response in markdown rendered format.
- Do not use generic filler phrases or bullet points.
- Use useful subsections in the 2nd and 3rd Sections with
keyword-rich titles.
- Do not repeat the same content over again.
[OUTPUT STRUCTURE]:
# Blog title
## First section title. (No subsections needed)
## Section title.
### [Subsection title]
### [Subsection title]
... [Do not use more than 3 subsections ]
## Section title.
### [Subsection title]
### [Subsection title]
... [Do not use more than 3 subsections ]
## Last section title. (No subsections needed).
[OUTLINES]:
- {{headings.0}}
- {{headings.1}}
- {{headings.2}}
[KEYWORDS]:
{{keywords}}
[CONTEXT]:
{{context}}
[BRIEF BLOG OUTLINE]:
param: outline
label: CREATE OUTLINE
type: gpt
silent: true
- steps:
- code: |
function cleanMarkdownText(text) {
const lines = text.split('\n');
const cleanedLines = [];
let skip = false;
for (let line of lines) {
// Check if the line starts with H1-H4, "-", or any digit
if (line.match(/^#{1,4} /) || line.startsWith('-') || line.match(/^[0-9]/)) {
skip = false;
} else {
// If not, set skip to true and skip this line
skip = true;
}
// If not skipping, add the line to cleanedLines
if (!skip) cleanedLines.push(line);
}
return cleanedLines.join('\n');
}
return cleanMarkdownText(args.outline);
label: DELETE TEXT LINES
type: js
args: outline
param: outline
silent: true
- func: replace
regex: /\n(?m)^\#\s(?!.*^\#\s)/gm
template: |-
##
label: 'CHECK: DOUBLE H1'
type: calc
to: outline
param: outline
- regex: '/(Conclusion: |Introduction: )/gm'
label: 'CONCL: OR INTROD:'
type: calc
func: replace
to: outline
param: outline
template: ''
- regex: /(##|#) Conclusion/gm
template: '## Final Thoughts'
label: '"#|## CONCLUSION: "'
type: calc
func: replace
to: outline
param: outline
- regex: /^- /gm
template: '### '
label: DROP BULLET POINTS
type: calc
func: replace
to: outline
param: outline
- code: |
function checkText(args) {
// Regular expression to find h2 headers
const h2HeaderRegex = /^##\s+([^\#]+)$/gm;
// Find all h2 headers
const h2Headers = [...args.outline.matchAll(h2HeaderRegex)];
// Check for the absence of 'Conclusion' or 'Introduction' in the h2 header lines
const noKeywordsInH2Headers = h2Headers.every(([_, title]) => {
return !/Conclusion|Introduction/.test(title);
});
// Check the total number of h2 headers
const totalH2Count = h2Headers.length;
const hasLessThanFiveH2 = totalH2Count < 6;
// Return True if conditions are met
return noKeywordsInH2Headers && hasLessThanFiveH2;
}
return checkText(args);
param: outline-check
label: CHECK OUTLINE
type: js
args: outline
silent: true
- steps:
- message: ⏳️ Improving outline, wait a bit...
type: say
- prompt: >-
I want you to act as a highly proficient SEO expert and
top-tier copywriter, and rewrite a blog outline along with
an H1 blog title, adhering to the following rules:
- Rewrite only those parts of the Outline that do not comply
with the rules, but do not alter the rest of the text.
- I need an outline in my format, without section contents.
- The response should start with the H1 blog title.
- The outline should contain no more than 4 sections,
including introduction and conclusion sections.
- Avoid simply naming the Introduction section as
'Introduction', and do not title the Conclusion section as
'Conclusion'.
- There should be no words 'Introduction' and 'Conclusion'
in the outline.
- The outline should be formatted using markdown features.
Instructions:
- Rewrite only the parts, that are not
- Do not rewrite the parts of the outline that already
follow the rules.
- Display the response in a markdown-rendered format.
- Do not use generic filler phrases and bullet points.
- Refrain from repeating the same content.
- Only output the H1 title and the Outline."
[FOLLOW THE OUTPUT FORMAT]:
# Blog title
## Introduction section title. (No subsections needed)
## Section title.
### [Subsection title]
### [Subsection title]
... [Do not use more than 3 subsections ]
## Section title.
### [Subsection title]
### [Subsection title]
... [Do not use more than 3 subsections ]
## Conclusion section title. (No subsections needed).
[KEYWORDS THAT COULD BE USED IN OUTLINE]:
{{keywords}}
[OLD OUTLINE]
{{outline}}
[BLOG OUTLINE]:
label: RE-DO OUTLINE
type: gpt
param: outline
silent: true
- type: jump
to: CHECK OUTLINE
condition: '{{outline-check}} = false'
label: REWRITE OUTLINE
type: group
label: OUTLINE CHECK
type: group
- message: |-
✅ Outline generated
```markdown
{{outline}}
```
type: say
label: FINAL OUTLINE
type: group
- to: CONTENT OPTIONS
type: jump
type: group
label: START KEYWORDS
- steps:
- steps:
- steps:
- message: 💬 Please provide a URL.
type: ask
param: webpage
options: null
default: ''
- steps:
- message: ⏳ Trying to fetch {{webpage}}.
type: say
- value: '{{page {{webpage}}}}'
type: calc
func: set
param: pagetext
format: ''
- code: |-
function removeReferencesSection(args) {
// Regular expression that matches the References section
const regex = /^References[\s\S]{0,250}\^[\s\S]*/m;
// Replace the found text with an empty string
args.pagetext = args.pagetext.replace(regex, '');
// Return the updated text
return args.pagetext;
}
return removeReferencesSection(args)
label: WIKI PAGE CLEAN
type: js
args: pagetext
param: pagetext
silent: true
- code: |-
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// First step: Split the text into lines
let lines = text.split('\n');
// Second step: Filter lines, excluding short ones that are not headers
lines = lines.filter(line => line.length >= 25 || headersRegex.test(line));
// Third step: Join the lines back into text, replacing \n with spaces
return lines.join(' ').replace(/\n/g, ' ');
}
return cleanText(args.pagetext);
type: js
args: pagetext
param: pagetext
label: CONTEXT EXTRACTION
silent: true
- to: NAVIGATE EXTRACT
condition: '{{pagetext}} =~ (?:^|[\r\n])[\s\S]{1,50}(?![\s\S])'
type: jump
type: group
label: TRY TO FETCH
- steps:
- message: 😢 Impossible to fetch, navigating to the page...
type: say
- param: currentpage
type: calc
func: set
format: ''
value: '{{url}}'
- url: '{{webpage}}'
type: navigate
waitForIdle: false
silent: true
- type: calc
func: set
param: pagetext
format: ''
value: '{{page}}'
- type: js
code: |-
function removeReferencesSection(args) {
// Regular expression that matches the References section
const regex = /^References[\s\S]{0,250}\^[\s\S]*/m;
// Replace the found text with an empty string
args.pagetext = args.pagetext.replace(regex, '');
// Return the updated text
return args.pagetext;
}
return removeReferencesSection(args)
args: pagetext
param: pagetext
label: WIKI PAGE CLEAN
silent: true
- type: js
code: |-
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// First step: Split the text into lines
let lines = text.split('\n');
// Second step: Filter lines, excluding short ones that are not headers
lines = lines.filter(line => line.length >= 25 || headersRegex.test(line));
// Third step: Join the lines back into text, replacing \n with spaces
return lines.join(' ').replace(/\n/g, ' ');
}
return cleanText(args.pagetext);
args: pagetext
param: pagetext
label: CONTEXT EXTRACTION
silent: true
- message: |-
⛔️ Sorry, the {{domain}} can't be automated.
Visit the page and select 'USE THIS PAGE' option.
label: FAIL MESSAGE
type: say
condition: '{{pagetext}} =~ (?:^|[\r\n])[\s\S]{1,50}(?![\s\S])'
- type: stop
label: FAIL STOP
condition: '{{pagetext}} =~ (?:^|[\r\n])[\s\S]{1,50}(?![\s\S])'
- url: '{{currentpage}}'
type: navigate
waitForIdle: false
silent: true
type: group
label: NAVIGATE EXTRACT
- to: BASIC PAGE CONTEXT
type: jump
type: group
label: START URL
- steps:
- message: 💬 Paste text or hit Enter to use the webpage.
type: ask
param: context
options: null
default: '{{page}}'
- to: PAGE CALC
condition: '{{context}} = {{page}}'
type: jump
- type: jump
to: FORM QUERY MESSAGE
type: group
label: START TEXT
- steps:
- value: '{{transcript}}'
type: calc
func: set
param: pagetext
format: ''
- steps:
- message: >-
🚫 It looks as if the video has no text transcript, or I
could not fetch it from the page.
type: say
- type: stop
condition: '{{transcript}} ='
type: group
- message: >-
⏳ Parsing video from the page… Long videos may take a few
seconds to parse.
type: say
- to: BASIC CREATE CONTEXT
type: jump
type: group
label: START VIDEO
- steps:
- type: calc
func: set
param: pagetext
format: ''
value: '{{page}}'
label: PAGE CALC
- type: js
code: |-
function removeReferencesSection(args) {
// Regular expression that matches the References section
const regex = /^References[\s\S]{0,250}\^[\s\S]*/m;
// Replace the found text with an empty string
args.pagetext = args.pagetext.replace(regex, '');
// Return the updated text
return args.pagetext;
}
return removeReferencesSection(args)
args: pagetext
param: pagetext
label: WIKI PAGE CLEAN
silent: true
- type: js
code: |-
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// First step: Split the text into lines
let lines = text.split('\n');
// Second step: Filter lines, excluding short ones that are not headers
lines = lines.filter(line => line.length >= 25 || headersRegex.test(line));
// Third step: Join the lines back into text, replacing \n with spaces
return lines.join(' ').replace(/\n/g, ' ');
}
return cleanText(args.pagetext);
args: pagetext
param: pagetext
label: CONTEXT EXTRACTION
silent: true
- type: jump
to: BASIC PAGE CONTEXT
type: group
label: START PAGE
- type: say
message: ⏳ Preparing basic context, wait a bit...
label: BASIC PAGE CONTEXT
- prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
Act as a very proficient SEO and high end copywriter.
I want you read my [TEXT] and summarize it , covering all important
details.
- Focus on creating in-depth, informative paragraphs.
- Ensure that the content is factually accurate and verifiable.
- Keep as much useful information as you can.
- Avoid filler phrases and notes.
- Do not repeat any instructions or my task.
- Respond only with the informative summary text, without including
any notes.
[TEXT]:
{{chunk}}
[INFORMATIVE SUMMARY TEXT]:
chunkify:
text: '{{pagetext}}'
empty: ''
type: gpt
param: context
label: BASIC CREATE CONTEXT
silent: true
- message: |-
☑️ Basic context generated:
```markdown
{{context}}
```
type: say
- message: ⏳ Generating research query...
type: say
label: FORM QUERY MESSAGE
- prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
Act as a text analysis expert.
Identify the key topic of the provided [TEXT].
- Extract the essence of the text and summarize it in a concise,
four-word sentence.
- This four-word sentence should capture the core idea or theme of
the text clearly and accurately.
- Your response should consist of one line.
- Write nothing other than the four-word sentence.
- Do not repeat my command and instructions.
- Do not put your answer in quotes.
[TEXT]: {{context}}
Text key topic in few words:
label: FORM QUERY
type: gpt
param: query
silent: true
- message: |-
☑️ Research query generated:
```markdown
{{query}}
```
type: say
- type: calc
func: set
param: information
format: ''
value: '{{serp {{query}}}}'
- type: calc
func: serp.extract-links
from: information
to: links
- message: |-
☑️ SERP extracted:
- [{{links.0.title}}]({{links.0.url}}): {{links.0.description}}
- [{{links.1.title}}]({{links.1.url}}): {{links.1.description}}
- [{{links.2.title}}]({{links.2.url}}): {{links.2.description}}
- [{{links.3.title}}]({{links.3.url}}): {{links.3.description}}
- [{{links.4.title}}]({{links.4.url}}): {{links.4.description}}
- [{{links.5.title}}]({{links.5.url}}): {{links.5.description}}
- [{{links.6.title}}]({{links.6.url}}): {{links.6.description}}
- [{{links.7.title}}]({{links.7.url}}): {{links.7.description}}
type: say
- type: say
message: ⏳ Updating context, wait a bit...
- value: |
- {{links.0.title}}: {{page {{query}} {{links.0.url}} limit=5%}}
- {{links.1.title}}: {{page {{query}} {{links.1.url}} limit=5%}}
- {{links.2.title}}: {{page {{query}} {{links.2.url}} limit=5%}}
- {{links.3.title}}: {{page {{query}} {{links.3.url}} limit=5%}}
type: calc
func: set
param: newcontext
format: ''
label: COMBINE NEW INFO
- type: js
code: |
function cleanText(text) {
const headersRegex = /^(\#{1,4}\s.*?)(?=\n|$)/gm;
// DELETE H1-H4
let cleanedText = text.replace(headersRegex, '');
// DELETE SHORT LINES
cleanedText = cleanedText.split('\n').filter(line => line.length >= 25).join('\n');
// DELETE \n
return cleanedText.replace(/\n/g, ' ');
}
return cleanText(args.newcontext);
args: newcontext
param: newcontext
silent: true
- prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
Act as a very proficient SEO and high end copywriter.
I want you to combine [OLD INFORMATION] with [NEW INFORMATION],
covering all important details.
- Do not delete any data from [OLD INFORMATION]; instead, complement
it with [NEW INFORMATION] related to [MY QUERY].
- Focus on creating in-depth, informative paragraphs. Ensure that
the content is factually accurate and verifiable.
- Keep as much useful information as you can.
- Avoid filler phrases and notes.
- Do not repeat any instructions or my task.
- Respond only with the combined text, without including any notes.
[MY QUERY]: {{query}}
[OLD INFORMATION]:
{{context}}
[NEW INFORMATION]:
{{newcontext}}
[INFORMATIVE SUMMARY TEXT]:
type: gpt
param: context
label: CONTEXT UPDATE
silent: true
- prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
Act as a very proficient SEO and high end copywriter.
I want you to integrate all of the URLs into relevant locations in
[TEXT]using Markdown formatting: [title](url).
- [{{links.0.title}}]({{links.0.url}}): {{links.0.description}}
- [{{links.1.title}}]({{links.1.url}}): {{links.1.description}}
- [{{links.2.title}}]({{links.2.url}}): {{links.2.description}}
- [{{links.3.title}}]({{links.3.url}}): {{links.3.description}}
- [{{links.4.title}}]({{links.4.url}}): {{links.4.description}}
- [{{links.5.title}}]({{links.5.url}}): {{links.5.description}}
- [{{links.6.title}}]({{links.6.url}}): {{links.6.description}}
- [{{links.7.title}}]({{links.7.url}}): {{links.7.description}}
Instructions:
- Do not modify the [TEXT].
- Each URL should be integrated only once.
- Modify the [titles] for better integration.
- Spread the URLs throughout the text.
- Avoid putting too many markdown links in one section.
[TEXT]:
{{context}}
[TEXT WITH MARKDOWN LINKS]:
label: 'NOT USED: URLS TO CONTEXT'
condition: '{{NOT}} = USED'
type: gpt
param: context
silent: true
- message: |-
✅ Context updated:
```markdown
{{context}}
```
type: say
- message: ⏳ Generating LSI keywords list, wait a bit...
type: say
- type: gpt
prompt: >-
I want you to respond only in {{language}} and output a single list.
Pretend to be a SEO keyword research expert.
Read the [SERP] and [CONTEXT] that I will provide you and find top
20 LSI keywords in SERP and your internal knowledge, each containing
at least 2 words:
- Please identify and list LSI Keywords that are specifically
associated with [MY QUERY].
- When extracting these keywords, focus on finding terms that are
not just relevant in a broad sense but are specifically combined or
contextually linked with [MY QUERY] that I will provide you later.
- Response with only these LSI keywords, separated by commas.
- Do not add any notes, write only comma separated keywords.
- Do not echo my prompt.
[MY QUERY]: {{query}}
[SERP]:
- {{links.0.title}}: {{links.0.description}}
- {{links.1.title}}: {{links.1.description}}
- {{links.2.title}}: {{links.2.description}}
- {{links.3.title}}: {{links.3.description}}
- {{links.4.title}}: {{links.4.description}}
- {{links.5.title}}: {{links.5.description}}
- {{links.6.title}}: {{links.6.description}}
- {{links.7.title}}: {{links.7.description}}
[CONTEXT]:
{{context}}
[ONLY KEYWORDS]:
param: keywords
label: FIND KEYWORDS
silent: true
- message: |-
✅ LSI KW list generated:
```markdown
{{keywords}}
```
type: say
- type: say
message: ⏳ Preparing outline, wait a bit...
- prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
I want you to act as a very proficient SEO and high end copywriter
and a blog post brief outline and a H1 blog title.
- I will provide you with the [CONTEXT] and [KEYWORDS] from the
SERP. Use it as your outline basis.
- Use concise, keyword-rich headings and subheadings.
- Start with the H1 blog title, and do not use h1 anywhere else.
- I need an outline in my format, without section contents.
- Do not use more than 4 sections, introduction and conclusion
sections included.
- Avoid naming the Introduction section simply as 'Introduction',
and do not title the Conclusion section merely as 'Conclusion'.
- Do not use words 'Introduction' and 'Conclusion' in your outline.
- There shoud be no subsections or bullet points in the introduction
and conclusion sections.
- Display the response in markdown rendered format.
- Do not use generic filler phrases or bullet points.
- Use useful subsections in the 2nd and 3rd Sections with
keyword-rich titles.
- Do not repeat the same content over again.
[OUTPUT STRUCTURE]:
# Blog title
## Introduction section title. (No subsections needed)
## Section title.
### [Subsection title]
### [Subsection title]
... [Do not use more than 3 subsections ]
## Section title.
### [Subsection title]
### [Subsection title]
... [Do not use more than 3 subsections ]
## Conclusion section title. (No subsections needed).
[KEYWORDS]:
{{keywords}}
[CONTEXT]:
{{context}}
[BRIEF BLOG OUTLINE]:
type: gpt
param: outline
label: CREATE OUTLINE
silent: true
- steps:
- type: js
code: |
function cleanMarkdownText(text) {
const lines = text.split('\n');
const cleanedLines = [];
let skip = false;
for (let line of lines) {
// Check if the line starts with H1-H4, "-", or any digit
if (line.match(/^#{1,4} /) || line.startsWith('-') || line.match(/^[0-9]/)) {
skip = false;
} else {
// If not, set skip to true and skip this line
skip = true;
}
// If not skipping, add the line to cleanedLines
if (!skip) cleanedLines.push(line);
}
return cleanedLines.join('\n');
}
return cleanMarkdownText(args.outline);
args: outline
param: outline
label: DELETE TEXT LINES
silent: true
- type: calc
func: replace
to: outline
param: outline
regex: /\n(?m)^\#\s(?!.*^\#\s)/gm
template: |-
##
label: 'CHECK: DOUBLE H1'
- type: calc
func: replace
to: outline
param: outline
regex: '/(Conclusion: |Introduction: )/gm'
template: ''
label: 'CONCL: OR INTROD:'
- type: calc
func: replace
to: outline
param: outline
regex: /(##|#) Conclusion/gm
template: '## Final Thoughts'
label: '"#|## CONCLUSION: "'
- template: '###'
type: calc
func: replace
to: outline
param: outline
regex: /^- /gm
label: DROP BULLET POINTS
- type: js
code: |
function checkText(args) {
// Regular expression to find h2 headers
const h2HeaderRegex = /^##\s+([^\#]+)$/gm;
// Find all h2 headers
const h2Headers = [...args.outline.matchAll(h2HeaderRegex)];
// Check for the absence of 'Conclusion' or 'Introduction' in the h2 header lines
const noKeywordsInH2Headers = h2Headers.every(([_, title]) => {
return !/Conclusion|Introduction/.test(title);
});
// Check the total number of h2 headers
const totalH2Count = h2Headers.length;
const hasLessThanFiveH2 = totalH2Count < 6;
// Return True if conditions are met
return noKeywordsInH2Headers && hasLessThanFiveH2;
}
return checkText(args);
args: outline
param: outline-check
label: CHECK OUTLINE
silent: true
- steps:
- type: say
message: ⏳️ Improving outline, wait a bit...
- type: gpt
prompt: >-
I want you to act as a highly proficient SEO expert and
top-tier copywriter, and rewrite a blog outline along with
an H1 blog title, adhering to the following rules:
- Rewrite only those parts of the Outline that do not comply
with the rules, but do not alter the rest of the text.
- I need an outline in my format, without section contents.
- The response should start with the H1 blog title.
- The outline should contain no more than 4 sections,
including introduction and conclusion sections.
- Avoid simply naming the Introduction section as
'Introduction', and do not title the Conclusion section as
'Conclusion'.
- There should be no words 'Introduction' and 'Conclusion'
in the outline.
- The outline should be formatted using markdown features.
Instructions:
- Rewrite only the parts, that are not
- Do not rewrite the parts of the outline that already
follow the rules.
- Display the response in a markdown-rendered format.
- Do not use generic filler phrases and bullet points.
- Refrain from repeating the same content.
- Only output the H1 title and the Outline."
[FOLLOW THE OUTPUT FORMAT]:
# Blog title
## Introduction section title. (No subsections needed)
## Section title.
### [Subsection title]
### [Subsection title]
... [Do not use more than 3 subsections ]
## Section title.
### [Subsection title]
### [Subsection title]
... [Do not use more than 3 subsections ]
## Conclusion section title. (No subsections needed).
[KEYWORDS THAT COULD BE USED IN OUTLINE]:
{{keywords}}
[OLD OUTLINE]
{{outline}}
[BLOG OUTLINE]:
label: RE-DO OUTLINE
param: outline
silent: true
- type: jump
to: CHECK OUTLINE
type: group
condition: '{{outline-check}} = false'
label: REWRITE OUTLINE
type: group
label: OUTLINE CHECK
- type: say
message: |-
✅ Outline generated
```markdown
{{outline}}
```
label: COMBO SCENARIO
type: group
- type: jump
to: CONTENT OPTIONS
label: TEXT,PAGE,URL,VID
type: group
- param: blog-option
options:
- label: 📝 BLOG POST
value: blogpost
- label: 📚 LONG-READ
value: longread
- label: 🧩 EDIT INPUTS
value: editinputs
type: ask
message: ''
default: ''
optionsInvalid: false
label: CONTENT OPTIONS
- steps:
- message: ⏳ Generating blog post...
type: say
- prompt: >-
Please ignore all previous instructions and respond only in
{{language}}.
As a skilled SEO expert and high-end copywriter, I need you to create a
comprehensive, detail-rich 1000 words blog post, based on my [OUTLINE]
and [INFORMATION], adhering to Google's E-A-T guidelines, with the goal
of ranking high on Google.
- Utilize both your inherent knowledge and any additional information I
provided.
- Do not rephrase the [OUTLINE].
- Use an H1 tag from [OUTLINE] for the blogs's title, H2s for main
sections, and H3s for sub-sections.
- Save all the integrated markdown-formatted links from [INFORMATION] to
your blog post and add the [additional URLs], place them into random
locations.
- Focus on creating in-depth, informative paragraphs
- Use the [KEYWORDS]: {{keywords}}
- The blog post should be in fully rendered Markdown format.
- Refrain from using general phrases like 'END OF BLOG POST' or similar.
- Do not echo my prompt.
Integrate some of the [additional URLs] into relevant locations using
Markdown formatting: [title](url):
- [{{links.0.title}}]({{links.0.url}})
- [{{links.1.title}}]({{links.1.url}})
- [{{links.2.title}}]({{links.2.url}})
- [{{links.3.title}}]({{links.3.url}})
- [{{links.4.title}}]({{links.5.url}})
[OUTLINE]:
{{outline}}
[INFORMATION]: {{context}}
1000 words blog post:
param: result
type: gpt
silent: true
- prompt: >-
Please ignore all previous instructions.
The output should be in {{language}}.
Act as a very proficient SEO and high end copywriter.
I want you to integrate all of the URLs into relevant locations in
[TEXT] using Markdown formatting: [title](url).
- [{{links.0.title}}]({{links.0.url}})
- [{{links.1.title}}]({{links.1.url}})
- [{{links.2.title}}]({{links.2.url}})
- [{{links.3.title}}]({{links.3.url}})
- [{{links.4.title}}]({{links.4.url}})
- [{{links.5.title}}]({{links.5.url}})
- [{{links.6.title}}]({{links.6.url}})
- [{{links.7.title}}]({{links.7.url}})
Instructions:
- Do not modify the [TEXT].
- Do not try to find the other links in your internal knowledge base.
- Each URL should be integrated only once.
- Modify the [titles] for better integration.
- Spread the URLs throughout the text.
- Avoid putting too many markdown links in one section.
[TEXT]:
{{result}}
[TEXT WITH MARKDOWN LINKS]:
label: URLS BLOG POST
type: gpt
param: result
silent: true
- message: '{{result}}'
type: say
label: BLOG POST
condition: '{{blog-option}} = blogpost'
type: group
- steps:
- code: |
function extractH1Heading(args) {
// Extracting H1 header in HTML
const parser = new DOMParser();
const doc = parser.parseFromString(args.outline, 'text/html');
const htmlH1Element = doc.querySelector('h1');
let result = '';
// If an H1 is found in HTML, use it
if (htmlH1Element) {
result = "# " + htmlH1Element.textContent.trim();
} else {
// Extracting H1 header in Markdown
const markdownH1Match = args.outline.match(/(^|\n)# (.*?)(\n|$)/);
if (markdownH1Match) {
result = "# " + markdownH1Match[2].trim();
}
}
return result;
}
// Returning the result at the end of the function
return extractH1Heading(args);
param: blog-title
label: H1
type: js
args: outline
silent: true
- code: |
function extractH2Sections(args) {
// Function to check if a line is an H2 heading in Markdown
function isMarkdownH2(line) {
return /^## [^\n]+/.test(line);
}
// Function to check if a line is not an H1 heading in Markdown
function isNotMarkdownH1(line) {
return !/^# [^\n]+/.test(line);
}
// Extract content from Markdown
function extractMarkdown() {
const lines = args.outline.split('\n');
let content = '';
let h2Count = 0;
for (let i = 0; i < lines.length; i++) {
if (isMarkdownH2(lines[i])) {
h2Count++;
if (h2Count <= 2) {
content += lines[i] + '\n';
}
} else if (h2Count <= 2 && isNotMarkdownH1(lines[i])) {
content += lines[i] + '\n';
}
}
return content.trim();
}
// Extract content from HTML
function extractHTML() {
const parser = new DOMParser();
const doc = parser.parseFromString(args.outline, 'text/html');
const elements = Array.from(doc.body.childNodes);
let content = '';
let h2Count = 0;
elements.forEach(element => {
if (element.tagName === 'H2') {
h2Count++;
if (h2Count <= 2) {
content += element.outerHTML;
}
} else if (h2Count <= 2 && element.tagName !== 'H1') {
content += element.outerHTML;
}
});
return content;
}
// Check if the input is HTML or Markdown
if (args.outline.includes('<html>')) {
return extractHTML();
} else {
return extractMarkdown();
}
}
// Returning the result at the end of the function
return extractH2Sections(args);
param: outline1
label: OUTLINE PART 1
type: js
args: outline
silent: true
- code: |
function extractFromThirdH2(args) {
// Function to check if a line is an H2 heading in Markdown
function isMarkdownH2(line) {
return /^## [^\n]+/.test(line);
}
// Function to check if a line is not an H1 heading in Markdown
function isNotMarkdownH1(line) {
return !/^# [^\n]+/.test(line);
}
// Extract content from Markdown
function extractMarkdown() {
const lines = args.outline.split('\n');
let content = '';
let h2Count = 0;
for (let i = 0; i < lines.length; i++) {
if (isMarkdownH2(lines[i])) {
h2Count++;
if (h2Count >= 3) {
content += lines[i] + '\n';
}
} else if (h2Count >= 3 && isNotMarkdownH1(lines[i])) {
content += lines[i] + '\n';
}
}
return content.trim();
}
// Extract content from HTML
function extractHTML() {
const parser = new DOMParser();
const doc = parser.parseFromString(args.outline, 'text/html');
const elements = Array.from(doc.body.childNodes);
let content = '';
let h2Count = 0;
elements.forEach(element => {
if (element.tagName === 'H2') {
h2Count++;
if (h2Count >= 3) {
content += element.outerHTML;
}
} else if (h2Count >= 3 && element.tagName !== 'H1') {
content += element.outerHTML;
}
});
return content;
}
// Check if the input is HTML or Markdown
if (args.outline.includes('<html>')) {
return extractHTML();
} else {
return extractMarkdown();
}
}
// Returning the result at the end of the function
return extractFromThirdH2(args);
param: outline2
label: OUTLINE PART 2
type: js
args: outline
silent: true
- message: ⏳ Generating part 1/2...
type: say
- prompt: >-
Please ignore all previous instructions.
Respond only in {{language}}.
Write a detailed fist segment of a blog post, about 1000 words, adhering
to Google's E-A-T guidelines for high ranking on Google search., based
on my [OUTLINE] and [INFORMATION].
- Stick to the [OUTLINE] provided. Do not add extra segments.
- Do not change the wording of the [OUTLINE].
- Combine your knowledge with the [INFORMATION] given.
- Write the post in Markdown, using H2 and H3 tags for headings and
subheadings.
- Focus on creating in-depth, informative paragraphs. Ensure that the
content is factually accurate and verifiable, enhancing the Expertise,
Authoritativeness, and Trustworthiness of the post.
- Incorporate the provided [KEYWORDS] naturally into the content.
- Ensure the content is unique and high-quality. Avoid using fillers or
generic phrases.
- Refrain from using general phrases like 'END OF BLOG POST' or similar.
- Do not write the H1 title. Follow the [OUTLINE].
- Ensure no repetition or echoing of the prompt.
Integrate all of the URLs into relevant locations using Markdown
formatting: [title](url).
- [{{links.0.description}}]({{links.0.url}})
- [{{links.1.description}}]({{links.1.url}})
- [{{links.2.description}}]({{links.2.url}})
- [{{links.3.description}}]({{links.3.url}})
Do not place URLs in the titles.
Each URL should be embedded only once.
Modify the titles for better integration.
Spread the URLs throughout the text. Avoid putting too many in one
section.
[KEYWORDS]: {{keywords}}
[OUTLINE]:
{{outline1}}
[INFORMATION]: {{context}}
[blog post part with integrated URLs]:
param: part1
label: PART 1
type: gpt
silent: true
isolated: true
- regex: /^---\n.*$/gm
label: DELETE FOOTER 1
type: calc
func: replace
to: part1
param: part1
template: ''
- regex: /^Stay tuned.*/gm
label: 'DEL: STAY TUNED'
type: calc
func: replace
to: part1
param: part1
template: ''
- regex: /\[[^\]]+\]\(#\S*\)
label: DELETE PART 2 LINK
type: calc
func: replace
to: part1
param: part1
template: ''
- message: ⏳ Generating part 2/2...
type: say
- prompt: >-
Please ignore all previous instructions and respond only in
{{language}}.
Write a detailed second and the last segment of a blog post, about 1000
words, adhering to Google's E-A-T guidelines for high ranking on Google
search., based on my [OUTLINE] and [INFORMATION].
- Stick to the [OUTLINE] provided. Do not add extra segments.
- Do not change the wording of the [OUTLINE].
- Combine your knowledge with the [INFORMATION] given.
- Write the post in Markdown, using H2 and H3 tags for headings and
subheadings.
- Focus on creating in-depth, informative paragraphs. Ensure that the
content is factually accurate and verifiable, enhancing the Expertise,
Authoritativeness, and Trustworthiness of the post.
- Incorporate the provided [KEYWORDS] naturally into the content.
- Ensure the content is unique and high-quality. Avoid using fillers or
generic phrases.
- Refrain from using general phrases like 'END OF BLOG POST' or similar.
- Ensure no repetition or echoing of the prompt.
Integrate all of the URLs into random relevant locations using Markdown
formatting: [title](url).
- [{{links.4.description}}]({{links.4.url}})
- [{{links5.description}}]({{links.5.url}})
- [{{links.6.description}}]({{links.6.url}})
- [{{links.7.description}}]({{links.7.url}})
Do not place URLs in the titles.
Each URL should be embedded only once.
Modify the titles for better integration.
Spread the URLs throughout the text. Avoid putting too many in one
section.
[KEYWORDS]: {{keywords}}
[OUTLINE]:
{{outline2}}
[INFORMATION]: {{context}}
[blog post part with integrated URLs]:
param: part2
label: PART 2
type: gpt
silent: true
- label: DELETE FOOTER 2
type: calc
func: replace
to: part2
param: part2
regex: /^---\n.*$/gm
template: ''
- label: DELETE PART 1 LINK
type: calc
func: replace
to: part2
param: part2
regex: /\[[^\]]+\]\(#\S*\)
template: ''
- steps:
- message: 🎯 Almost done! Creating the meta description...
type: say
- prompt: >-
Please ignore all previous instructions. Respond only in
{{language}}.
I want you to act as a proficient SEO and high end copy writer.
I want you to summarize the [TEXT] into a brief meta description,
which must be under 160 characters long (~20 words maximum).
- Please include only the meta description in your response, without
any additional words, notes, or comments.
- Do not write words "Meta description" in the beginning.
- Do now write anything, but the meta description text itself.
- Do not put your response in quotation marks.
[TEXT]:
{{context}}
[USE KEYWORDS]:
{{keywords}}
Meta Description under 160 characters:
param: meta
type: gpt
silent: true
isolated: true
- regex: '"'
type: calc
func: replace
to: meta
param: meta
template: ''
- regex: 'Meta description:'
type: calc
func: replace
to: meta
param: meta
template: ''
- regex: Meta description
type: calc
func: replace
to: meta
param: meta
template: ''
label: META DESCRIPTION
type: group
- message: |-
{{blog-title}}
META DESCRIPTION: {{meta}}
{{part1}}
{{part2}}
type: say
- type: calc
func: set
param: result
format: ''
value: |-
{{blog-title}}
META DESCRIPTION: {{meta}}
{{part1}}
{{part2}}
label: LONG-READ
condition: '{{blog-option}} = longread'
type: group
- steps:
- message: |-
## 1️⃣ Outline:
```markdown
{{outline}}
```
## 2️⃣ LSI Keywords:
```markdown
{{keywords}}
```
## 3️⃣ External Links:
```markdown
- [{{links.0.title}}]({{links.0.url}})
- [{{links.1.title}}]({{links.1.url}})
- [{{links.2.title}}]({{links.2.url}})
- [{{links.3.title}}]({{links.3.url}})
- [{{links.4.title}}]({{links.4.url}})
- [{{links.5.title}}]({{links.5.url}})
- [{{links.6.title}}]({{links.6.url}})
- [{{links.7.title}}]({{links.7.url}})
```
## 4️⃣ Context:
```markdown
{{context}}
```
label: SAY INPUTS
type: say
- param: change-input
message: >-
🔼 Please look at the inputs above and let me know what you would like
to change.
options:
- label: ✅ ALL GOOD
value: ok
- label: 1️⃣ OUTLINE
value: outline
- label: 2️⃣ KEYWORDS
value: keywords
- label: 3️⃣ EXTERNAL LINKS
value: links
- label: 4️⃣ CONTEXT
value: context
type: ask
default: ''
optionsInvalid: false
- condition: '{{change-input}} = ok'
type: jump
to: CONTENT OPTIONS
- steps:
- message: >-
💬 Provide a new outline for me, following the format of the
previous one:
```markdown
{{outline}}
```
type: ask
param: outline
options: null
default: ''
- message: ✅ Outline saved!
type: say
- type: jump
to: SAY INPUTS
condition: '{{change-input}} = outline'
type: group
label: 1️⃣ OUTLINE
- steps:
- message: >-
💬 Provide a new keywords for me, following the format of the
previous:
```markdown
{{keywords}}
```
type: ask
param: keywords
options: null
default: ''
- message: '✅ Keywords saved! '
type: say
- type: jump
to: SAY INPUTS
condition: '{{change-input}} = keywords'
label: 2️⃣ LSI KEYWORDS
type: group
- steps:
- message: 💬 I'll find the top SERP URLs myself; just write me your query.
label: NEW URL SEARCH
type: ask
param: query
options: null
default: ''
- type: calc
func: set
param: information
format: ''
value: '{{serp {{query}}}}'
- type: calc
func: serp.extract-links
from: information
to: links
- message: |-
☑️ URLs extracted:
- [{{links.0.title}}]({{links.0.url}})
- [{{links.1.title}}]({{links.1.url}})
- [{{links.2.title}}]({{links.2.url}})
- [{{links.3.title}}]({{links.3.url}})
- [{{links.4.title}}]({{links.4.url}})
- [{{links.5.title}}]({{links.5.url}})
- [{{links.6.title}}]({{links.6.url}})
- [{{links.7.title}}]({{links.7.url}})
type: say
- param: url-redo
options:
- label: ✅ SAVE
value: 'yes'
- label: ⛔ NEW SEARCH
value: 'no'
type: ask
message: ''
default: ''
optionsInvalid: false
- condition: '{{url-redo}} = no'
type: jump
to: NEW URL SEARCH
- message: '✅ Saved! '
condition: '{{url-redo}} = yes'
type: say
- type: jump
to: SAY INPUTS
condition: '{{change-input}} = links'
type: group
label: 3️⃣ EXTERNAL LINKS
- steps:
- message: 💬 Provide a new relevant text and I will save it.
type: ask
param: context
options: null
default: ''
- message: '✅ Context saved! '
type: say
- type: jump
to: SAY INPUTS
condition: '{{change-input}} = context'
type: group
label: 4️⃣ CONTEXT
label: EDIT INPUTS
condition: '{{blog-option}} = editinputs'
type: group
- steps:
- param: refine-menu
options:
- label: ✅ DONE
value: done
- label: ✴️ REFINE
value: refine
- label: ♻️ EDIT INPUTS & REDO
value: edit-inputs
- label: 🔐 SAVE TO JSON
value: save
- label: 📚 SHOW JSON
value: show-array
- label: 📦 EXPORT
value: export
label: REFINE-MENU
type: ask
message: ''
default: ''
optionsInvalid: false
- condition: '{{refine-menu}} = done'
type: stop
label: ✅ DONE
- steps:
- param: instructions
message: 💬 What changes would you like me to make?
type: ask
options: null
default: ''
- prompt: >-
Please ignore all previous instructions. The output should be in
{{language}}.
I want you to act as a very proficient SEO and high end copy writer.
I want you to make changes to the [BLOG POST]. Please do not output
anything but the revised [BLOG POST].
- Do not echo my command.
- Do not put quotes around the revised text.
- Do not write any Notes for me.
- I only need the rewritten text and nothing more.
- If I said to delete a certain part of the text, you should delete
only that one.
[CHANGES TO MAKE]: {{instructions}}
[BLOG POST:
{{result}}
Rewritten blog post:
type: gpt
param: result
isolated: true
- type: jump
to: REFINE-MENU
condition: '{{refine-menu}} = refine'
type: group
label: ✴️ REFINE
- steps:
- type: jump
to: SAY INPUTS
condition: '{{refine-menu}} = edit-inputs'
type: group
label: ♻️ EDIT INPUTS & REDO
- steps:
- message: ✅ The Blog Post is saved in the {{g.blogposts}} global parameter.
type: say
interpolate: false
- list: g.blogposts
type: calc
func: list-add
index: last
item: result
- type: jump
to: REFINE-MENU
condition: '{{refine-menu}} = save'
label: ' 🔐 SAVE TO ARRAY'
type: group
- steps:
- message: '{{g.blogposts}}'
type: say
- type: jump
to: REFINE-MENU
condition: '{{refine-menu}} = show-array'
label: ' 📚 SHOW ARRAY'
type: group
- what: param
condition: '{{refine-menu}} = export'
type: export
param: result
label: REFINE MENU
type: group
This automation command is created by a community member. HARPA AI team does not audit community commands.
Please review the command carefully and only install if you trust the creator.
All rights reserved © HARPA AI TECHNOLOGIES LLC, 2021 — 2024
Designed and engineered in Finland 🇫🇮