This commit is contained in:
nusquama
2026-02-18 12:03:08 +08:00
parent 021120b446
commit ab030ec47d
@@ -0,0 +1,383 @@
Repurpose viral content into AI visuals and post to Instagram and Facebook with Blotato
https://n8nworkflows.xyz/workflows/repurpose-viral-content-into-ai-visuals-and-post-to-instagram-and-facebook-with-blotato-13340
# Repurpose viral content into AI visuals and post to Instagram and Facebook with Blotato
disclaimer Le texte fourni provient exclusivement dun workflow automatisé réalisé avec n8n, un outil dintégration et dautomatisation. Ce traitement respecte strictement les politiques de contenu en vigueur et ne contient aucun élément illégal, offensant ou protégé. Toutes les données manipulées sont légales et publiques.
## 1. Workflow Overview
**Title:** Repurpose viral content into AI visuals and post to Instagram and Facebook with Blotato
**Workflow name (internal):** Automatically Repurpose Viral Content
**Purpose:**
This workflow accepts a public content URL (blog/YouTube/TikTok/etc.), uses Blotato to extract and summarize it into structured Vietnamese content, generates an AI visual/video from that content, then automatically publishes the resulting media to **Instagram** and **Facebook** via Blotato.
**Core pattern:** **Create → Wait → Get → Check → Publish** (asynchronous polling using Wait nodes)
### 1.1 Input Reception (Form Trigger)
Collects a single URL from a user to start the pipeline.
### 1.2 Source Processing (Async job + polling)
Creates a Blotato “Source” extraction job, waits, retrieves status, and routes based on **failed / processing / completed**.
### 1.3 Visual Generation (Async job + polling)
Uses extracted content to create a Blotato “Video” (template-based visual), waits, retrieves status, and loops until rendering is **done**.
### 1.4 Social Media Distribution
Publishes the generated media to Instagram and Facebook accounts configured in Blotato.
---
## 2. Block-by-Block Analysis
### Block 1 — Input Reception
**Overview:** Receives a public content URL through an n8n Form Trigger and passes it into the processing pipeline.
**Nodes involved:** `Submit Content URL` (+ Sticky Notes: `Sticky Note`, `Sticky Note4`)
#### Node: Submit Content URL
- **Type / role:** `n8n-nodes-base.formTrigger` — entry point that creates a webhook-backed form.
- **Key configuration:**
- **Form title:** “URL Input”
- **Description:** “Submit the content source link (Blog, YouTube, TikTok, etc.)”
- **Field:** `URL (Blog, Youtube, tiktok)` (required)
- **Webhook ID:** autogenerated; used internally by n8n to receive submissions.
- **Input / output:**
- **Input:** none (trigger)
- **Output:** JSON containing the submitted field value under the exact label:
- `$json["URL (Blog, Youtube, tiktok)"]`
- **Edge cases / failures:**
- Empty or invalid URL formats (no validation beyond “required”).
- Private/geo-blocked URLs may later fail in Blotato extraction.
- Form label changes will break downstream expressions unless updated.
---
### Block 2 — Source Processing (Create → Wait → Get → Switch)
**Overview:** Submits the URL to Blotato as a “Source” job, waits asynchronously, retrieves the job status, and routes to either continue waiting, proceed to visual generation, or stop on failure.
**Nodes involved:** `Create Source`, `Wait for Source Processing`, `Get source`, `Source Status Switch` (+ Sticky Note: `Sticky Note1`, `Sticky Note4`)
#### Node: Create Source
- **Type / role:** `@blotato/n8n-nodes-blotato.blotato` — creates a Blotato “source” extraction job from the URL.
- **Key configuration (interpreted):**
- **Resource:** `source`
- **Source URL:** expression pulls from form submission
- `={{ $json['URL (Blog, Youtube, tiktok)'] }}`
- **Custom instructions (Vietnamese):**
- “Phân tích và tổng hợp thông tin chính thành content ngắn. (TIều đề và content bằng tiếng việt)”
(Analyze and summarize key info into short content; title and content in Vietnamese.)
- **Credentials:** Blotato API credential: **“Blotato GiangxAI”**
- **Input / output:**
- **Input:** from `Submit Content URL`
- **Output:** a new source job object, including an **id** used later.
- **Edge cases / failures:**
- Blotato auth failure (invalid API key / expired).
- URL not supported or blocked → source job may return `failed`.
- If Blotato returns unexpected fields, downstream `Get source` may break if `id` is missing.
#### Node: Wait for Source Processing
- **Type / role:** `n8n-nodes-base.wait` — delays/persists execution to allow async processing.
- **Key configuration:** defaults (no explicit duration shown; depends on n8n Wait node mode/config UI).
- **Input / output:**
- **Input:** from `Create Source` or from the “processing” loop
- **Output:** forwards the same item after waiting
- **Edge cases / failures:**
- If configured as “Wait for webhook” in UI, it requires external resume calls; if configured as “Time interval”, it just delays. Ensure it matches intended polling design.
- Very long waits can create many waiting executions depending on polling strategy.
#### Node: Get source
- **Type / role:** `@blotato/n8n-nodes-blotato.blotato` — retrieves the current status/result for a source job.
- **Key configuration:**
- **Resource:** `source`
- **Operation:** `get`
- **Source ID:** `={{ $json.id }}`
- Assumes the incoming item contains `id` (from Create Source output and preserved through Wait loops).
- **Credentials:** “Blotato GiangxAI”
- **Input / output:**
- **Input:** from `Wait for Source Processing`
- **Output:** source job with fields such as:
- `status` (used by switch)
- `title`, `content` (used later)
- **Edge cases / failures:**
- If `$json.id` is missing (lost/mapped incorrectly), request fails.
- API may rate-limit frequent polling.
#### Node: Source Status Switch
- **Type / role:** `n8n-nodes-base.switch` — routes based on `$json.status`.
- **Key configuration:**
- Rule outputs (renamed):
- **failed** if `{{$json.status}} == "failed"`
- **completed** if `{{$json.status}} == "completed"`
- **processing** if `{{$json.status}} == "processing"`
- **Connections (important):**
- **failed:** no downstream node connected (execution effectively ends for that item).
- **completed →** `Create visual`
- **processing →** `Wait for Source Processing` (poll loop)
- **Edge cases / failures:**
- Any other status value (e.g., `queued`, `pending`) will not match rules and will be dropped unless switch “fallback” is configured (not shown).
- “failed” path currently has no logging/notification node.
---
### Block 3 — Visual Generation (Create → Wait → Get → If)
**Overview:** Creates a Blotato visual/video using a predefined template, waits for rendering, retrieves the rendering result, and loops until status is done.
**Nodes involved:** `Create visual`, `Wait for Visual Rendering`, `Get visual`, `Visual Status Check` (+ Sticky Note: `Sticky Note2`, `Sticky Note4`)
#### Node: Create visual
- **Type / role:** `@blotato/n8n-nodes-blotato.blotato` — creates a Blotato “video” rendering job from a template.
- **Key configuration:**
- **Resource:** `video`
- **Template:** “Twitter/X style quote cards with minimal style” (templateId stored)
- **Prompt:** `=Viết tiếng việt: {{ $json.content }}`
- Uses extracted source `content` (Vietnamese instruction).
- **Template inputs (static):**
- `theme`: `dark`
- `handle`: `giangxAI.aff`
- `verified`: `false`
- `authorName`: `GiangxAI`
- `aspectRatio`: `1:1`
- `profileImage`: `https://i.ibb.co/kgXBZ8YJ/98ec9d84960922577b18.jpg`
- **Credentials:** “Blotato GiangxAI”
- **Input / output:**
- **Input:** from `Source Status Switch` (completed branch). Must include `$json.content`.
- **Output:** video job object containing something like `item.id` (used later).
- **Edge cases / failures:**
- Missing `$json.content` (if source result schema differs) → prompt becomes incomplete.
- Template could be deleted/changed in Blotato → templateId invalid.
- Render jobs can fail silently unless checked (workflow only checks for `done` later).
#### Node: Wait for Visual Rendering
- **Type / role:** `n8n-nodes-base.wait` — pauses to allow render completion.
- **Input / output:**
- **Input:** from `Create visual` or from the “not done yet” loop
- **Output:** forwards item after waiting
- **Edge cases / failures:**
- Same operational concerns as the source Wait node (polling frequency, wait mode).
#### Node: Get visual
- **Type / role:** `@blotato/n8n-nodes-blotato.blotato` — retrieves the current status/result for a video job.
- **Key configuration:**
- **Resource:** `video`
- **Operation:** `get`
- **Video ID:** `={{ $('Create visual').item.json.item.id }}`
- Explicitly references the `Create visual` nodes output (item-scoped).
- **Credentials:** “Blotato GiangxAI”
- **Input / output:**
- **Input:** from `Wait for Visual Rendering`
- **Output:** `item` object typically containing:
- `item.status` (checked in IF)
- `item.mediaUrl` and/or `item.imageUrls` (used for publishing)
- **Edge cases / failures:**
- If `Create visual` produced multiple items or different structure, `.item.id` may not exist.
- API rate limits if polling too fast.
#### Node: Visual Status Check
- **Type / role:** `n8n-nodes-base.if` — checks whether rendering is complete for all incoming items.
- **Key configuration (single boolean condition):**
- Expression:
```js
{{
$input.all().length === 1
? $json.item.status === 'done'
: $input.all().every(item => item.json.item.status === 'done')
}}
```
- Meaning: if one item, check current item; if many items, require all to be `done`.
- **Connections:**
- **True →** `Publish to Instagram` and `Publish to Facebook`
- **False →** `Wait for Visual Rendering` (poll loop)
- **Edge cases / failures:**
- If Blotato uses a different terminal status (e.g., `completed` instead of `done`), loop never ends.
- If `item.status` is missing, expression evaluates false → infinite loop.
- No timeout / max retries implemented.
---
### Block 4 — Social Media Distribution
**Overview:** Posts the generated media to Instagram and Facebook through Blotato connected accounts.
**Nodes involved:** `Publish to Instagram`, `Publish to Facebook` (+ Sticky Note: `Sticky Note3`, `Sticky Note4`)
#### Node: Publish to Instagram
- **Type / role:** `@blotato/n8n-nodes-blotato.blotato` — publishes a post to an Instagram account managed in Blotato.
- **Key configuration:**
- **Account:** `giangxai.aff` (accountId `25299`)
- **Post text:** `={{ $('Get source').item.json.title }}`
- **Media URLs:**
`={{ $('Get visual').item.json.item?.mediaUrl || $('Get visual').item.json.item?.imageUrls || '' }}`
- Prefers `mediaUrl`; else uses `imageUrls`; else empty string.
- **Credentials:** “Blotato GiangxAI”
- **Input / output:**
- **Input:** from `Visual Status Check` (true)
- **Output:** Blotato publish result (post ID/status depending on API)
- **Edge cases / failures:**
- If media URL resolves to empty string, publish likely fails.
- If `imageUrls` is an array, passing the entire array vs. expected string/list depends on node behavior—verify Blotato node expects a string or array.
- Account permission issues (Instagram connection expired in Blotato).
#### Node: Publish to Facebook
- **Type / role:** `@blotato/n8n-nodes-blotato.blotato` — publishes a post to Facebook (page).
- **Key configuration:**
- **Platform:** `facebook`
- **Account:** `Giang VT` (accountId `16978`)
- **Facebook Page:** `Giang VT` (pageId `688227101036478`)
- **Post text:** `={{ $('Get source').item.json.title }}`
- **Media URLs:** `={{ $('Get visual').item.json.item.imageUrls[0] }}`
- Uses the first image URL specifically.
- **Credentials:** “Blotato GiangxAI”
- **Edge cases / failures:**
- If `imageUrls` is missing/empty, `[0]` becomes `undefined` → publish error.
- Page token/permissions issues (managed inside Blotato).
- If the generated asset is a video (mediaUrl) but `imageUrls` is empty, Facebook publishing will fail in current configuration.
---
## 3. Summary Table
| Node Name | Node Type | Functional Role | Input Node(s) | Output Node(s) | Sticky Note |
|---|---|---|---|---|---|
| Submit Content URL | n8n-nodes-base.formTrigger | Entry form/webhook trigger | — | Create Source | ## URL Input<br>Submit the content source link (Blog, YouTube, TikTok, etc.) |
| Create Source | @blotato/n8n-nodes-blotato.blotato | Create Blotato source extraction job | Submit Content URL | Wait for Source Processing | ## Source Processing<br>Create and retrieve structured content from the provided URL. |
| Wait for Source Processing | n8n-nodes-base.wait | Delay/poll while source processes | Create Source; Source Status Switch (processing) | Get source | ## Source Processing<br>Create and retrieve structured content from the provided URL. |
| Get source | @blotato/n8n-nodes-blotato.blotato | Retrieve source status + extracted content | Wait for Source Processing | Source Status Switch | ## Source Processing<br>Create and retrieve structured content from the provided URL. |
| Source Status Switch | n8n-nodes-base.switch | Route by source job status | Get source | Create visual (completed); Wait for Source Processing (processing) | ## Source Processing<br>Create and retrieve structured content from the provided URL. |
| Create visual | @blotato/n8n-nodes-blotato.blotato | Create Blotato visual/video render job | Source Status Switch (completed) | Wait for Visual Rendering | ## Visual Generation<br>Generate and retrieve AI visual/video based on processed content. |
| Wait for Visual Rendering | n8n-nodes-base.wait | Delay/poll while visual renders | Create visual; Visual Status Check (false) | Get visual | ## Visual Generation<br>Generate and retrieve AI visual/video based on processed content. |
| Get visual | @blotato/n8n-nodes-blotato.blotato | Retrieve render status + media URLs | Wait for Visual Rendering | Visual Status Check | ## Visual Generation<br>Generate and retrieve AI visual/video based on processed content. |
| Visual Status Check | n8n-nodes-base.if | Check render completion; loop or publish | Get visual | Publish to Instagram; Publish to Facebook (true) / Wait for Visual Rendering (false) | ## Visual Generation<br>Generate and retrieve AI visual/video based on processed content. |
| Publish to Instagram | @blotato/n8n-nodes-blotato.blotato | Publish post to Instagram via Blotato account | Visual Status Check (true) | — | ## Social Media Distribution<br>Automatically publish generated content to social platforms |
| Publish to Facebook | @blotato/n8n-nodes-blotato.blotato | Publish post to Facebook Page via Blotato account | Visual Status Check (true) | — | ## Social Media Distribution<br>Automatically publish generated content to social platforms |
| Sticky Note | n8n-nodes-base.stickyNote | Comment/documentation | — | — | ## URL Input<br>Submit the content source link (Blog, YouTube, TikTok, etc.) |
| Sticky Note1 | n8n-nodes-base.stickyNote | Comment/documentation | — | — | ## Source Processing<br>Create and retrieve structured content from the provided URL. |
| Sticky Note2 | n8n-nodes-base.stickyNote | Comment/documentation | — | — | ## Visual Generation<br>Generate and retrieve AI visual/video based on processed content. |
| Sticky Note3 | n8n-nodes-base.stickyNote | Comment/documentation | — | — | ## Social Media Distribution<br>Automatically publish generated content to social platforms |
| Sticky Note4 | n8n-nodes-base.stickyNote | Comment/setup guide | — | — | # 🛠️ Workflow Setup Guide<br><br>Author: [GiangxAI](https://www.youtube.com/@giangxai.official)<br><br>## How it works<br>- A public content URL (Blog, YouTube, TikTok, etc.) is submitted to trigger the workflow<br>- A Source job is created to extract and structure the content<br>- The workflow waits for AI processing and checks extraction status<br>- Structured content is sent to Blotato to create a visual/video<br>- The workflow waits for AI rendering to complete<br>- The generated visual asset is retrieved and validated<br>- The final content is automatically published to:<br> - Instagram<br> - Facebook<br><br>The entire pipeline runs using an async pattern:<br>Create → Wait → Get → Check → Publish<br><br>---<br>## Setup guide [n8n](https://n8n.partnerlinks.io/giangxai)<br>- Configure the **Submit Content URL** node to accept public content links<br>- Connect your **Source extraction API credentials**<br>- Add **[Blotato](https://blotato.com/?ref=giang9s) API credentials** for AI visual generation<br>- Configure Instagram and Facebook credentials for auto publishing<br>- Review status routing logic (failed / completed / processing)<br>- Adjust wait timing based on API processing speed |
---
## 4. Reproducing the Workflow from Scratch
1. **Create a new workflow** in n8n named: *Automatically Repurpose Viral Content* (or your preferred name).
2. **Add trigger node: “Form Trigger”**
- Node type: **Form Trigger**
- Form title: `URL Input`
- Form description: `Submit the content source link (Blog, YouTube, TikTok, etc.)`
- Add one required field:
- Label: `URL (Blog, Youtube, tiktok)`
- Required: true
3. **Add node: “Blotato” → Create Source**
- Node type: **Blotato**
- Resource: `source`
- Operation: create (default for resource in this workflow)
- Source URL expression:
- `{{$json["URL (Blog, Youtube, tiktok)"]}}`
- Custom instructions:
- `Phân tích và tổng hợp thông tin chính thành content ngắn. (TIều đề và content bằng tiếng việt)`
- **Credentials:** create/select a Blotato API credential in n8n (API key from your Blotato account).
4. **Add node: “Wait” → Wait for Source Processing**
- Node type: **Wait**
- Configure a polling delay method (recommended):
- Use a time-based wait (e.g., 1060 seconds) to avoid manual resume.
- (Exact UI option depends on n8n version; ensure it actually resumes automatically.)
5. **Add node: “Blotato” → Get source**
- Node type: **Blotato**
- Resource: `source`
- Operation: `get`
- Source ID expression:
- `{{$json.id}}`
- Credentials: same Blotato API credential.
6. **Add node: “Switch” → Source Status Switch**
- Node type: **Switch**
- Value to evaluate: `{{$json.status}}`
- Add 3 rules (string equals):
- Output “failed”: equals `failed`
- Output “completed”: equals `completed`
- Output “processing”: equals `processing`
7. **Wire the Source polling loop**
- Connect: **Form Trigger → Create Source → Wait for Source Processing → Get source → Source Status Switch**
- From **Source Status Switch**:
- “processing” output → **Wait for Source Processing** (loop)
- “completed” output → next block (Create visual)
- “failed” output → leave unconnected or connect to an error handler node (recommended)
8. **Add node: “Blotato” → Create visual**
- Node type: **Blotato**
- Resource: `video`
- Operation: create (default)
- Template: select **Twitter/X style quote cards with minimal style** (or equivalent) in the node UI
- Prompt expression:
- `Viết tiếng việt: {{ $json.content }}`
- Template inputs (set explicitly):
- theme: `dark`
- handle: `giangxAI.aff` (or yours)
- verified: `false`
- authorName: `GiangxAI` (or yours)
- aspectRatio: `1:1`
- profileImage: a publicly accessible image URL
9. **Add node: “Wait” → Wait for Visual Rendering**
- Node type: **Wait**
- Configure time-based delay appropriate for rendering (e.g., 1590 seconds).
10. **Add node: “Blotato” → Get visual**
- Node type: **Blotato**
- Resource: `video`
- Operation: `get`
- Video ID expression referencing Create visual:
- `{{$('Create visual').item.json.item.id}}`
11. **Add node: “IF” → Visual Status Check**
- Node type: **IF**
- Condition: Boolean “is true” with expression:
- `{{$input.all().length === 1 ? $json.item.status === 'done' : $input.all().every(item => item.json.item.status === 'done') }}`
12. **Wire the Visual polling loop**
- Connect: **Create visual → Wait for Visual Rendering → Get visual → Visual Status Check**
- From **Visual Status Check**:
- **False** → **Wait for Visual Rendering** (loop)
- **True** → publishing nodes
13. **Add node: “Blotato” → Publish to Instagram**
- Node type: **Blotato**
- Select Instagram publishing action (as provided by Blotato node)
- Account: choose your Instagram-connected Blotato account (e.g., `giangxai.aff`)
- Post text expression:
- `{{$('Get source').item.json.title}}`
- Media URLs expression:
- `{{$('Get visual').item.json.item?.mediaUrl || $('Get visual').item.json.item?.imageUrls || ''}}`
14. **Add node: “Blotato” → Publish to Facebook**
- Node type: **Blotato**
- Platform: `facebook`
- Account: choose your Facebook-connected Blotato account
- Facebook Page: select the target page
- Post text expression:
- `{{$('Get source').item.json.title}}`
- Media URL expression:
- `{{$('Get visual').item.json.item.imageUrls[0]}}`
15. **Connect publishing**
- From **Visual Status Check (true)** connect to **Publish to Instagram** and **Publish to Facebook** in parallel.
16. **Credentials checklist**
- **Blotato API credential in n8n** must be configured once and selected on all Blotato nodes.
- Instagram/Facebook permissions are typically managed inside Blotato accounts/pages; ensure those connections are valid in Blotato.
---
## 5. General Notes & Resources
| Note Content | Context or Link |
|---|---|
| Author: GiangxAI | https://www.youtube.com/@giangxai.official |
| Setup guide n8n link | https://n8n.partnerlinks.io/giangxai |
| Blotato link (API + platform) | https://blotato.com/?ref=giang9s |
| Pipeline pattern used | “Create → Wait → Get → Check → Publish” (async polling design) |
| Missing failure handling | Source “failed” branch is unconnected; consider adding notifications/logging and a max-retry/timeout for both polling loops. |