📰 RSS Plugin
The RSS plugin enables distribution of curated content to RSS feeds, allowing you to publish content to your own RSS feed that can be consumed by RSS readers and other applications. This extends the reach of your curated content beyond the curate.fun platform itself.
🔧 Setup Guide
-
Deploy the RSS service to your preferred hosting platform. You can use the RSS Service Template repository which provides a ready-to-deploy RSS service with multiple deployment options.
-
Generate a secure random string to use as your API secret. This will be shared between your application and the RSS service.
noteThe API secret is used to authenticate requests to the RSS service. Make sure to keep it secure.
-
Modify your
curate.config.json
to include the RSS configuration:{
"outputs": {
"stream": {
"enabled": true,
"distribute": [
{
"plugin": "@curatedotfun/rss",
"config": {
"serviceUrl": "https://your-rss-service-url.com",
"apiSecret": "{API_SECRET}"
}
}
]
}
}
}The container is already set up to hydrate environment variables into the configuration at runtime, replacing
{API_SECRET}
with the values from the environment.You need to specify:
serviceUrl
: The URL of your deployed RSS serviceapiSecret
: API secret for authentication with the RSS service
cautionKeep your API secret secure! Never commit it directly to your configuration files or repositories.
-
Enable the stream by setting
"enabled": true
if not already enabled.Once merged, your approved messages will start flowing to your RSS feed through the configured service.
📝 Configuration Reference
Full configuration options for the RSS plugin:
{
"plugin": "@curatedotfun/rss",
"config": {
"serviceUrl": "https://your-rss-service-url.com", // URL of your deployed RSS service
"apiSecret": "{API_SECRET}", // Automatically injected from environment
"feedConfig": { // Optional feed configuration
"title": "My Custom RSS Feed",
"description": "A feed of curated content",
"siteUrl": "https://example.com",
"language": "en",
"copyright": "© 2025",
"maxItems": 50,
"image": "https://example.com/logo.png",
"author": {
"name": "Feed Author",
"email": "author@example.com",
"link": "https://author.example.com"
}
}
}
}
Feed Configuration
The feedConfig
property allows you to customize your RSS feed's metadata during plugin initialization. This configuration is sent to the RSS service to be available when feed data is queried.
Key configuration options:
- title: The title of your RSS feed
- description: A brief description of your feed's content
- siteUrl: The URL of your website (used for feed links)
- language: The language code for your feed (e.g., "en", "es", "fr")
- copyright: Copyright notice for your feed content
- maxItems: Maximum number of items to keep in the feed (older items are removed)
- image: URL to an image representing your feed
- author: Information about the feed author (name, email, link)
If you don't provide a feedConfig
, the RSS service will use default values.
🔄 Data Transformation
The RSS plugin accepts structured input data that maps to RSS item fields. You can provide as much or as little data as you want, and the plugin will fill in defaults for missing fields.
Input Data Structure
The plugin validates input using Zod and expects an object with these fields (content and link are required, others are optional):
interface RssInput {
// Core fields
title?: string; // Optional custom title
content: string; // Required - Content of the item
description?: string; // Optional description/summary
link: string; // Required - URL to the item
publishedAt?: string; // Default: new Date().toISOString()
guid?: string; // Default: `item-${Date.now()}`
// Author information
author?: {
name: string;
email?: string;
link?: string;
} | Array<{
name: string;
email?: string;
link?: string;
}>;
// Media and categorization
image?: string | {
url: string;
type?: string;
length?: number;
};
audio?: string | {
url: string;
type?: string;
length?: number;
};
video?: string | {
url: string;
type?: string;
length?: number;
};
enclosure?: {
url: string;
type?: string;
length?: number;
};
categories?: string[] | Array<{
name: string;
domain?: string;
}>;
// Additional metadata
copyright?: string;
source?: {
url: string;
title: string;
};
isPermaLink?: boolean;
}
The plugin handles various formats for fields like author
, image
, audio
, video
, and categories
, allowing for both simple string values and more complex objects with additional metadata.
Using Transformer Plugins
To format your data properly for RSS, you can use transformer plugins like @curatedotfun/ai-transform
and @curatedotfun/object-transform
before the RSS plugin. The recommended pattern is to use AI transformation first to generate content, then use object transformation to map the AI-generated content to the RSS item schema.
Recommended Transformation Pipeline
{
"outputs": {
"stream": {
"enabled": true,
"transform": [
{
"plugin": "@curatedotfun/ai-transform",
"config": {
"prompt": "Summarize the content into a concise news flash, incorporating relevant details from the curator's notes. Maintain a neutral, third-person tone. Mention the author if relevant, or simply convey the information.",
"apiKey": "{OPENROUTER_API_KEY}",
"schema": {
"title": {
"type": "string",
"description": "Title derived from summary of content"
},
"summary": {
"type": "string",
"description": "Summary of content influenced by curator notes"
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Relevant tags for the content"
}
}
}
},
{
"plugin": "@curatedotfun/object-transform",
"config": {
"mappings": {
"title": "{{title}}",
"content": "<h2>{{title}}</h2><p>{{summary}}</p>",
"description": "{{summary}}",
"link": "https://example.com/posts/{{id}}",
"publishedAt": "{{publishedAt}}",
"guid": "post-{{id}}",
"author": {
"name": "{{author.name}}",
"email": "{{author.email}}",
"link": "{{author.url}}"
},
"image": {
"url": "{{image.url}}",
"type": "{{image.type}}",
"length": "{{image.size}}"
},
"audio": "{{audio.url}}",
"video": {
"url": "{{video.url}}",
"type": "{{video.type}}",
"length": "{{video.size}}"
},
"categories": ["{{tags}}", "news", "updates"],
"copyright": "© {{currentYear}} Example Company",
"source": {
"url": "{{sourceUrl}}",
"title": "{{sourceTitle}}"
},
"isPermaLink": true
}
}
}
],
"distribute": [
{
"plugin": "@curatedotfun/rss",
"config": {
"serviceUrl": "http://localhost:4001",
"apiSecret": "{API_SECRET}"
}
}
]
}
}
}
This example demonstrates a complete transformation pipeline that:
- First uses AI transformation to generate a title, summary, and tags from the input content
- Then uses object transformation to map the AI-generated content to all available RSS item fields:
- Core fields: title, content, description, link, publishedAt, guid
- Author information: name, email, link
- Media: image, audio, video
- Categories: tags from AI plus additional static categories
- Additional metadata: copyright, source, isPermaLink
Simplified Example
For a simpler implementation, you can use just the essential fields:
{
"outputs": {
"stream": {
"enabled": true,
"transform": [
{
"plugin": "@curatedotfun/object-transform",
"config": {
"mappings": {
"source": "https://x.com/{{username}}/status/{{tweetId}}",
"content": "{{content}}",
"author": "{{username}}",
"notes": "{{curator.notes}}",
"submittedAt": "{{submittedAt}}",
"createdAt": "{{createdAt}}"
}
}
},
{
"plugin": "@curatedotfun/ai-transform",
"config": {
"prompt": "Transform this into an engaging news article with a title and content",
"apiKey": "{OPENROUTER_API_KEY}",
"schema": {
"title": {
"type": "string",
"description": "Engaging title for the article"
},
"content": {
"type": "string",
"description": "Article content in HTML format"
}
}
}
},
{
"plugin": "@curatedotfun/object-transform",
"config": {
"mappings": {
"title": "{{title}}",
"content": "{{content}}",
"link": "{{source}}",
"author": [{ "name": "{{author}}", "link": "https://x.com/{{author}}" }],
"published": "{{createdAt}}"
}
}
}
],
"distribute": [
{
"plugin": "@curatedotfun/rss",
"config": {
"serviceUrl": "http://localhost:4001",
"apiSecret": "{API_SECRET}"
}
}
]
}
}
}
This creates a basic RSS item with just the essential fields: title, content, link, publication date, and a unique identifier.
🔐 Security Considerations
- The RSS plugin requires an API secret to authenticate with the RSS service. This secret should be stored securely as an environment variable.
- Consider restricting access to your RSS service by configuring the ALLOWED_ORIGINS environment variable.
- Monitor your RSS service's activity regularly to ensure it's being used as expected.
📡 Accessing Your RSS Feed
Once your RSS service is deployed and the plugin is configured, your RSS feed will be available in multiple formats:
https://your-rss-service-url.com/rss.xml # RSS 2.0 format
https://your-rss-service-url.com/atom.xml # Atom format
https://your-rss-service-url.com/feed.json # JSON Feed format (HTML)
https://your-rss-service-url.com/raw.json # Raw JSON format (No HTML)
You can share these URLs with users who want to subscribe to your feed using their favorite RSS reader.