Opening Problem Statement
Meet Javier, a content curator who manages multiple blogs and news sources daily. Every time he finds an interesting article on his favorite RSS feeds, he manually copies snippets, downloads images, and posts updates to his BlueSky profile. This task takes over 2 hours daily, and Javier often forgets to post timely, losing engagement and missing traffic opportunities. The manual process is repetitive, error-prone, and time-consuming, especially when handling images and authenticating securely to BlueSky.
Javier needs an automated solution that converts RSS feed updates into engaging BlueSky posts, including embedded images and consistent timestamps, with little intervention. He also wants to keep his credentials safe and workflows easy to manage without deep coding knowledge.
What This Automation Does ⚙️
This n8n workflow solves Javier’s problem by automating the entire process of publishing new RSS feed items as BlueSky posts. When it runs, it:
- Monitors an RSS feed live and triggers on new feed items every minute.
- Authenticates with BlueSky via a secure app password session to get an access token.
- Downloads the feed item’s featured image automatically.
- Uploads the downloaded image to BlueSky as a blob for embedding.
- Creates a new BlueSky post with the feed’s title, snippet content (up to 200 characters), link, and uploaded image embedded.
- Tags posts with language metadata for Spanish (es-ES) support and accurate timestamps based on current date time.
With this automated pipeline, Javier can save over 14 hours weekly and eliminate manual errors in posting.
Prerequisites ⚙️
- n8n account with access to create workflows.
- BlueSky account with an app password for authentication 🔐.
- RSS feed URL to monitor for new content updates 📄.
- Basic familiarity with HTTP requests (handled in workflow nodes).
Step-by-Step Guide to Building This Workflow
Step 1: Set Up the RSS Feed Trigger
Navigate in n8n: Nodes → RSS Feed Read Trigger → Configure
Enter your RSS feed URL in the feedUrl parameter. For example, https://example.com/feed.
Set the polling interval to every minute to get real-time updates.
You should see RSS feed items appear as they trigger new flow runs.
Common mistake: Forgetting to enter a valid feed URL will cause no triggers.
Step 2: Create BlueSky Session HTTP Request
Add an HTTP Request node and name it Create Session.
Set the URL to https://bsky.social/xrpc/com.atproto.server.createSession and method to POST.
Under Body Parameters, add:
identifier: Your BlueSky username.password: Your app password from BlueSky.
This node authenticates you and returns an access token.
Common mistake: Using normal account password instead of app password leads to authentication failure.
Step 3: Get Current DateTime
Add a DateTime node named Get current datetime immediately after Create Session.
This adds a timestamp for the post’s creation using the system’s current datetime.
Step 4: Download Image from RSS Feed
Add an HTTP Request node named Download image.
Set the URL to:
={{ $('RSS Feed Trigger').item.json.enclosure.url }}Set
response format to file to ensure we download the binary image content.
This downloads the image referenced in the feed for upload to BlueSky.
Common mistake: Not setting the response format to file results in JSON output instead of binary image.
Step 5: Upload Image to BlueSky
Add an HTTP Request node named Upload image.
Set the URL to https://bsky.social/xrpc/com.atproto.repo.uploadBlob with method POST.
Configure the node to send binaryData with the image data field set to data.
Add headers:
Authorization: Bearer token obtained fromCreate Session.Content-Type: Copied from the feed’s file type, e.g., image/jpeg.
This uploads the image and returns a reference usable in the post.
Step 6: Create BlueSky Post with Content and Image
Add another HTTP Request node named Create Post.
Set the URL to https://bsky.social/xrpc/com.atproto.repo.createRecord with method POST.
Under JSON Body, compose the post JSON payload dynamically pulling from prior nodes:
{
"repo": "{{ $node['Create Session'].json['did'] }}",
"collection": "app.bsky.feed.post",
"record": {
"text": {{ JSON.stringify($node['RSS Feed Trigger'].json['content:encodedSnippet']) }},
"$type": "app.bsky.feed.post",
"embed": {
"$type": "app.bsky.embed.external",
"external": {
"uri": "{{ $node['RSS Feed Trigger'].json['link'] }}",
"title": "{{ $node['RSS Feed Trigger'].json['lintitlek'] }}",
"description": "{{ $node['RSS Feed Trigger'].json['contentSnippet'] }}",
"thumb": {
"$type": "{{ $json.blob.$type }}",
"ref": {
"$link": "{{ $json['blob']['ref']['$link'] }}"
},
"mimeType": "{{ $json.blob.mimeType }}",
"size": {{ $json.blob.size }}
}
}
},
"createdAt": "{{ $node['Get current datetime'].json['currentDate'] }}",
"langs": [ "es-ES" ]
}
}
Add Authorization header as Bearer token again.
This node creates a BlueSky post embedding content text, a clickable link, and the uploaded image with metadata.
Customizations ✏️
- Change post language: In the
Create Postnode, modify the"langs"array to["en-US"]or any other ISO locale to suit your audience. - Adjust polling interval: In the
RSS Feed Triggernode, change polling from every minute to every 10 minutes if your feed updates less often, saving API calls. - Customize post text: Modify body JSON in
Create Postnode to truncate content to 100 characters or add hashtags by editingtextfield script. - Set custom image URL: Override the default image URL in the
Download imagenode by typing a static image URL if the feed lacks images or needs branding. - Add multiple languages: Extend
"langs"field with multiple ISO codes to post multilingual content.
Troubleshooting 🔧
Problem: “Authentication failed” in Create Session node.
Cause: Using normal login password instead of BlueSky app password.
Solution: Create an app password in BlueSky settings and update credentials in Create Session node.
Problem: Image does not upload, HTTP Request Upload image node returns error.
Cause: Binary data not correctly passed or Content-Type header missing/wrong.
Solution: Ensure Download image node outputs binary data, set correct Content-Type header in Upload image node using feed’s enclosure.type, and connect nodes correctly.
Pre-Production Checklist ✅
- Verify BlueSky app password and username in
Create Sessionnode. - Confirm valid RSS feed URL that regularly updates.
- Test pipeline manually by pushing a new RSS feed item.
- Ensure image URLs in feed are accessible and not blocked.
- Check each HTTP Request node returns expected status and data.
Deployment Guide
Once all nodes are configured and tested, activate the workflow in n8n. The workflow will run automatically on the schedule set by the RSS Feed Trigger node.
Monitor executions in n8n’s dashboard to track successful posts or any failures. Logs will help identify issues with authentication or content upload.
FAQs
Q: Can I use a different social platform instead of BlueSky?
A: This workflow uses BlueSky’s API specifically. For other platforms, you’d need to adjust HTTP requests and authentication accordingly.
Q: Does this workflow consume API credits or have usage limits?
A: BlueSky API limits depend on your account type. Polling frequently may affect usage; adjust polling intervals as needed.
Q: Is my BlueSky password safe in this workflow?
A: Yes, use an app password instead of your main password, and store credentials securely in n8n.
Conclusion
By following this guide, you have automated the tedious manual task of sharing RSS feed updates to BlueSky, which saves you hours weekly and ensures timely, engaging posts with images and links. With this, Javier (and you!) can focus on curating content rather than posting it.
Next steps could include expanding to multi-language content, adding analytics tracking for post engagement, or automating cross-posting to other social platforms from the same feed.
Automation like this brings clarity and efficiency to your content workflow, empowering you to grow your audience effortlessly.