Split RSS bots into their own category
New RSS_TYPES category with a /rss-bots page, sidebar entry, homepage tile, and an explanation that RSS bots post a feed to a channel — share the channel link, not the user. Remove rss from the Bots page (types table + create dropdown); the RSS Bots page has a '+ New RSS Bot' button that only creates rss bots, with feed URL + per hour/day/week fields shown directly (no bot-type select). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -71,9 +71,11 @@ def _enrich(profiles: list[dict]) -> list[dict]:
|
||||
|
||||
|
||||
def _category(bot_type: str) -> str:
|
||||
"""Which sidebar category a profile belongs to: users / businesses / bots."""
|
||||
"""Which sidebar category a profile belongs to: users / businesses / rss-bots / bots."""
|
||||
if bot_type in pm.BUSINESS_TYPES:
|
||||
return "businesses"
|
||||
if bot_type in pm.RSS_TYPES:
|
||||
return "rss-bots"
|
||||
if bot_type in pm.USER_TYPES:
|
||||
return "users"
|
||||
return "bots"
|
||||
@@ -144,6 +146,17 @@ async def bots_page(request: Request):
|
||||
})
|
||||
|
||||
|
||||
@app.get("/rss-bots", response_class=HTMLResponse)
|
||||
async def rss_bots_page(request: Request):
|
||||
if redir := _redirect_if_unauth(request):
|
||||
return redir
|
||||
items = _enrich([p for p in db.list_profiles() if p["bot_type"] in pm.RSS_TYPES])
|
||||
return TEMPLATES.TemplateResponse(request, "list.html", {
|
||||
"tab": "rss-bots", "items": items, "create_types": pm.RSS_TYPES,
|
||||
"nav_active": "rss-bots",
|
||||
})
|
||||
|
||||
|
||||
RELAY_KINDS = {"chat": "Chat Relay", "file": "File Relay", "message": "Message Relay"}
|
||||
|
||||
|
||||
|
||||
@@ -139,10 +139,11 @@ def group_member_count(g: dict) -> int:
|
||||
return g.get("groupSummary", {}).get("currentMembers", 0)
|
||||
|
||||
|
||||
BOT_TYPES = ["echo", "llm", "rss", "crypto", "broadcast", "support", "directory", "deadmans"]
|
||||
BOT_TYPES = ["echo", "llm", "crypto", "broadcast", "support", "directory", "deadmans"]
|
||||
USER_TYPES = ["user"]
|
||||
BUSINESS_TYPES = ["business"] # cli accounts with a business address (per-customer group chats)
|
||||
ALL_TYPES = BOT_TYPES + USER_TYPES + BUSINESS_TYPES
|
||||
RSS_TYPES = ["rss"] # feed bots that post to a channel (their own category)
|
||||
ALL_TYPES = BOT_TYPES + USER_TYPES + BUSINESS_TYPES + RSS_TYPES
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -311,6 +311,7 @@
|
||||
<!-- Group 1: accounts -->
|
||||
<a href="/users" {% if nav_active == 'users' %}class="active"{% endif %}><span class="ico"><i class="fa-solid fa-user"></i></span><span class="lbl">Users</span></a>
|
||||
<a href="/bots" {% if nav_active == 'bots' %}class="active"{% endif %}><span class="ico"><i class="fa-solid fa-robot"></i></span><span class="lbl">Bots</span></a>
|
||||
<a href="/rss-bots" {% if nav_active == 'rss-bots' %}class="active"{% endif %}><span class="ico"><i class="fa-solid fa-rss"></i></span><span class="lbl">RSS Bots</span></a>
|
||||
<a href="/businesses" {% if nav_active == 'businesses' %}class="active"{% endif %}><span class="ico"><i class="fa-solid fa-briefcase"></i></span><span class="lbl">Business Groups</span></a>
|
||||
<a href="https://simplex.chat/file/" target="_blank" rel="noopener"><span class="ico"><i class="fa-solid fa-upload"></i></span><span class="lbl">File Upload</span></a>
|
||||
<!-- Group 2: relays -->
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
<span class="t-ico"><i class="fa-solid fa-robot"></i></span>
|
||||
<span class="t-title">Bots</span>
|
||||
</a>
|
||||
<a class="tile" href="/rss-bots">
|
||||
<span class="t-ico"><i class="fa-solid fa-rss"></i></span>
|
||||
<span class="t-title">RSS Bots</span>
|
||||
</a>
|
||||
<a class="tile" href="/businesses">
|
||||
<span class="t-ico"><i class="fa-solid fa-briefcase"></i></span>
|
||||
<span class="t-title">Business Groups</span>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
{% import "_macros.html" as ui %}
|
||||
{% block title %}{{ 'Business Groups' if tab == 'businesses' else tab | title }} — SimpleX Manager{% endblock %}
|
||||
{% block title %}{{ 'Business Groups' if tab == 'businesses' else ('RSS Bots' if tab == 'rss-bots' else tab | title) }} — SimpleX Manager{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<style>
|
||||
@@ -29,8 +29,8 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% set new_label = 'User' if tab == 'users' else ('Business Group' if tab == 'businesses' else 'Bot') %}
|
||||
{% set page_title = 'Business Groups' if tab == 'businesses' else tab | title %}
|
||||
{% set new_label = 'User' if tab == 'users' else ('Business Group' if tab == 'businesses' else ('RSS Bot' if tab == 'rss-bots' else 'Bot')) %}
|
||||
{% set page_title = 'Business Groups' if tab == 'businesses' else ('RSS Bots' if tab == 'rss-bots' else tab | title) %}
|
||||
<div class="flex-between" style="margin-bottom: 24px;">
|
||||
<h1 style="margin:0;">{{ page_title }}</h1>
|
||||
<button class="btn btn-primary" onclick="openCreate()">
|
||||
@@ -49,13 +49,23 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if tab == 'rss-bots' %}
|
||||
<div class="card bot-types-card" style="margin-bottom:24px;">
|
||||
<h2 style="font-size:15px;margin-bottom:8px;">RSS Bots</h2>
|
||||
<p class="muted" style="font-size:13px;">
|
||||
RSS bots read from an RSS/Atom feed and post new items to a channel. To receive a feed,
|
||||
share the bot's <strong>channel</strong> link with subscribers — open the bot and copy its
|
||||
<strong>channel</strong> link, <strong>not</strong> the user address.
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if tab == 'bots' %}
|
||||
<div class="card bot-types-card" style="margin-bottom:24px;">
|
||||
<h2 style="font-size:15px;margin-bottom:12px;">Available bot types</h2>
|
||||
<table>
|
||||
<tr><td><span class="tag">echo</span></td><td class="muted">Repeats every message back to the sender — handy for testing a connection end to end.</td></tr>
|
||||
<tr><td><span class="tag">llm</span></td><td class="muted">Chat with a local or remote LLM (OpenAI-compatible, e.g. Ollama). Give it context, it replies to your messages.</td></tr>
|
||||
<tr><td><span class="tag">rss</span></td><td class="muted">Watches an RSS/Atom feed and broadcasts new posts to a channel it creates. Subscribers join the channel to receive them.</td></tr>
|
||||
<tr><td><span class="tag">crypto</span></td><td class="muted">Streams selected crypto prices (CoinGecko) to a channel on an interval. Pick coins & currencies below.</td></tr>
|
||||
<tr><td><span class="tag">broadcast</span></td><td class="muted">Relays messages from authorized publishers out to all of the bot's contacts.</td></tr>
|
||||
<tr><td><span class="tag">support</span></td><td class="muted">Business inbox — auto-replies with a welcome message and collects incoming inquiries.</td></tr>
|
||||
@@ -108,6 +118,9 @@
|
||||
{% elif tab == 'businesses' %}
|
||||
<strong>No business groups yet</strong>
|
||||
<p>Create a business group; each customer who connects gets their own group chat.</p>
|
||||
{% elif tab == 'rss-bots' %}
|
||||
<strong>No RSS bots yet</strong>
|
||||
<p>Create an RSS bot to post a feed to a channel.</p>
|
||||
{% else %}
|
||||
<strong>No bots yet</strong>
|
||||
<p>Bots can echo messages, broadcast to subscribers, or run automated tasks.</p>
|
||||
@@ -140,6 +153,20 @@
|
||||
<input type="text" name="welcome_message" placeholder="Thanks for reaching out! How can we help?">
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if tab == 'rss-bots' %}
|
||||
<div class="field">
|
||||
<label>Feed URL</label>
|
||||
<input type="text" name="feed_url" placeholder="https://example.com/feed.xml">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>How often to check the feed</label>
|
||||
<div class="chk-grid">
|
||||
<label class="chk"><input type="radio" name="rss_poll" value="3600" checked> Per hour</label>
|
||||
<label class="chk"><input type="radio" name="rss_poll" value="86400"> Per day</label>
|
||||
<label class="chk"><input type="radio" name="rss_poll" value="604800"> Per week</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if tab == 'bots' %}
|
||||
<div class="field">
|
||||
<label>Bot Type</label>
|
||||
@@ -228,27 +255,6 @@
|
||||
<input type="text" name="prohibited_message" placeholder="Only publishers can broadcast. Your message is deleted.">
|
||||
</div>
|
||||
</div>
|
||||
<div id="rss-fields" style="display:none;">
|
||||
<div style="border-top:1px solid var(--border);margin:4px 0 14px;padding-top:14px;">
|
||||
<p class="muted" style="margin-bottom:12px;">
|
||||
The bot watches this feed and broadcasts new posts to a channel it creates.
|
||||
Share the channel link (from the bot's profile) with subscribers — new posts
|
||||
appear there automatically.
|
||||
</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Feed URL</label>
|
||||
<input type="text" name="feed_url" placeholder="https://example.com/feed.xml">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>How often to check the feed</label>
|
||||
<div class="chk-grid">
|
||||
<label class="chk"><input type="radio" name="rss_poll" value="3600" checked> Per hour</label>
|
||||
<label class="chk"><input type="radio" name="rss_poll" value="86400"> Per day</label>
|
||||
<label class="chk"><input type="radio" name="rss_poll" value="604800"> Per week</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="crypto-fields" style="display:none;">
|
||||
<div style="border-top:1px solid var(--border);margin:4px 0 14px;padding-top:14px;">
|
||||
<p class="muted" style="margin-bottom:12px;">
|
||||
@@ -355,7 +361,6 @@ function onTypeChange() {
|
||||
document.getElementById('deadmans-fields').style.display = (val === 'deadmans') ? 'block' : 'none';
|
||||
document.getElementById('directory-fields').style.display = (val === 'directory') ? 'block' : 'none';
|
||||
document.getElementById('broadcast-fields').style.display = (val === 'broadcast') ? 'block' : 'none';
|
||||
document.getElementById('rss-fields').style.display = (val === 'rss') ? 'block' : 'none';
|
||||
document.getElementById('crypto-fields').style.display = (val === 'crypto') ? 'block' : 'none';
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user