Bluesky, X/Twitter & Reddit
Open-web social channels that respond to mentions, DMs, and replies.
This page covers Revka’s three open-web social channels: Bluesky (AT Protocol), X/Twitter (API v2), and Reddit (OAuth2). Unlike workspace chat or messaging apps, these channels operate on public social networks: your agent watches its own notification feed, and responds when it is @-mentioned, replied to, or (on X and Reddit) sent a direct message. Use this page when you need exact config keys, auth model, and the mention-driven behavior for each platform.
All three are polling channels. None requires a public inbound port — Revka connects out to the platform API on a short interval and pulls new notifications, so there is no webhook to expose. All three are always compiled in (no Cargo feature flag). Configure them under [channels_config] in ~/.revka/config.toml, then restart the daemon to apply changes. For the trait model, delivery modes, and allowlist semantics shared by every channel, see Channels overview.
At a glance
Section titled “At a glance”| Channel | Auth | Receive mode | Poll interval | Triggers on | DMs |
|---|---|---|---|---|---|
| Bluesky | App password → JWT | Notification polling | 5s | mentions, replies | No |
| X/Twitter | OAuth 2.0 bearer token | Mentions-timeline polling | 15s | mentions | Send only |
| OAuth2 refresh token | Inbox polling | 5s | username mentions, comment replies, DMs | Yes |
Bluesky
Section titled “Bluesky”The Bluesky channel speaks the AT Protocol against https://bsky.social/xrpc. It authenticates with your handle and an app password, polls your notification feed every 5 seconds, and replies as a post that threads onto the original. It only acts on notifications whose reason is mention or reply — likes, follows, and reposts are ignored.
Configure Bluesky
Section titled “Configure Bluesky”[channels_config.bluesky]handle = "mybot.bsky.social"app_password = "xxxx-xxxx-xxxx-xxxx"| Field | Type | Default | Meaning |
|---|---|---|---|
handle | string | — | Your bot’s Bluesky handle, e.g. mybot.bsky.social. Required. |
app_password | string | — | An app-specific password generated in Bluesky settings. Required. |
App password auth and JWT refresh
Section titled “App password auth and JWT refresh”Bluesky does not use your main account password. Generate a scoped, revocable app password under Settings → Privacy and security → App passwords in the Bluesky client, then put it in app_password.
On startup Revka calls com.atproto.server.createSession with the handle and app password and receives a short-lived access JWT plus a longer-lived refresh JWT. AT Protocol access tokens last roughly two hours; Revka refreshes well before expiry via com.atproto.server.refreshSession, and if a refresh ever fails it falls back to a full re-authentication automatically. You do not manage tokens yourself — only the app password.
Mention-driven behavior
Section titled “Mention-driven behavior”- Revka polls
app.bsky.notification.listNotifications(25 at a time) every 5 seconds. - Only
mentionandreplynotifications are processed. The bot’s own posts and already-read notifications are skipped. - Each handled notification is marked seen via
app.bsky.notification.updateSeen, so it is not reprocessed. - Replies are created with
com.atproto.repo.createRecordinto theapp.bsky.feed.postcollection, with the reply’s root/parent set so the post threads correctly. - Posts are capped at Bluesky’s 300-character limit; longer agent output is truncated with a trailing
....
This channel has no DM support — it works purely through public mentions and replies.
X/Twitter
Section titled “X/Twitter”The X/Twitter channel uses the X (Twitter) API v2 at https://api.x.com/2 with an OAuth 2.0 app-only bearer token. It watches the authenticated bot account’s mentions, strips the leading @bot token, and replies in-thread. Sending also supports direct messages.
Configure X/Twitter
Section titled “Configure X/Twitter”[channels_config.twitter]bearer_token = "AAAA..."allowed_users = ["*"]| Field | Type | Default | Meaning |
|---|---|---|---|
bearer_token | string | — | OAuth 2.0 app-only (app-level) bearer token from your X developer app. Required. |
allowed_users | array | [] | Usernames or numeric user IDs allowed to interact. [] denies all; ["*"] allows everyone. |
Bearer token auth
Section titled “Bearer token auth”The bearer token is app-level, not tied to a single end user. Create an X developer app, then copy its OAuth 2.0 bearer token into bearer_token. On startup Revka calls GET /2/users/me to resolve the authenticated account’s user ID — this both validates the token (it is also the health check) and identifies which mentions belong to the bot.
Mention-driven behavior
Section titled “Mention-driven behavior”- Revka polls
GET /2/users/{id}/mentionsevery 15 seconds, requestingauthor_id,conversation_id, andcreated_at, and expanding author usernames. It usessince_idso each poll only returns tweets newer than the last one seen. - The bot’s own tweets are skipped, and a 10,000-entry deduplication set prevents reprocessing the same tweet.
- The sender (resolved username, falling back to author ID) is checked against
allowed_users. - The leading
@bot(and any other leading@mentions) is stripped from the text before it reaches the model; if nothing remains, the mention is ignored. - Replies are posted via
POST /2/tweetswithreply.in_reply_to_tweet_id. Output longer than the 280-character tweet limit is split at word boundaries into a reply thread, each tweet chained to the previous one.
Sending DMs
Section titled “Sending DMs”Outbound send chooses its action from the recipient prefix:
tweet:<id>(or a bare tweet ID) → a threaded reply viaPOST /2/tweets.dm:<user_id>→ a direct message viaPOST /2/dm_conversations/with/{user_id}/messages.
Inbound traffic for this channel is mention-driven; DMs are primarily an outbound capability your agent or workflows can use.
The Reddit channel is an OAuth2 bot that polls the account’s unread inbox every 5 seconds and handles three kinds of items: username mentions, comment replies, and private messages (DMs). It replies to comments as comments and to DMs as DMs. An optional subreddit filter narrows it to a single community.
Configure Reddit
Section titled “Configure Reddit”[channels_config.reddit]client_id = "reddit-client-id"client_secret = "reddit-client-secret"refresh_token = "reddit-refresh-token"username = "MyBotName"subreddit = "MySubreddit" # optional| Field | Type | Default | Meaning |
|---|---|---|---|
client_id | string | — | OAuth2 client ID from your Reddit app. Required. |
client_secret | string | — | OAuth2 client secret from your Reddit app. Required. |
refresh_token | string | — | Long-lived OAuth2 refresh token for persistent access. Required. |
username | string | — | The bot’s Reddit username, without the u/ prefix. Used for self-message filtering. Required. |
subreddit | string | — | Optional filter (without the r/ prefix). When set, only items from this subreddit are processed. |
Refresh-token auth
Section titled “Refresh-token auth”Reddit issues short-lived access tokens, so Revka uses a refresh token for durable access. On startup and whenever the access token nears expiry, Revka POSTs to https://www.reddit.com/api/v1/access_token with HTTP Basic auth (client_id:client_secret) and grant_type=refresh_token, then uses the returned access token as a bearer credential against https://oauth.reddit.com. The token is cached and refreshed automatically (60 seconds before its stated expiry). All requests send a descriptive User-Agent, as Reddit requires.
Mention-driven behavior
Section titled “Mention-driven behavior”- Revka polls
GET /message/unread(25 at a time) every 5 seconds, then marks the fetched items read viaPOST /api/read_messageso they are not reprocessed. - Items authored by the bot itself (case-insensitive match on
username) and items with an empty body are skipped. - If
subredditis set, items from any other subreddit are dropped. - Reply routing depends on item type:
- Comment replies / mentions (Reddit fullnames
t1_…,t3_…,t4_…) → a public comment viaPOST /api/commentwiththing_id. - Direct messages → a private reply to the author via
POST /api/compose(default subjectMessage from Revka).
- Comment replies / mentions (Reddit fullnames
Allowlist semantics
Section titled “Allowlist semantics”X/Twitter uses allowed_users with the standard rules:
- An empty list (
[]) denies all senders. - A single
"*"entry allows all senders. - Otherwise, only listed usernames or numeric user IDs are accepted.
Bluesky and Reddit do not expose an allowed_users field of their own. Bluesky responds to any non-self mention/reply; Reddit responds to any non-self inbox item, optionally narrowed by subreddit. Start by confirming delivery, then use the subreddit filter (Reddit) or X’s allowed_users to tighten who your agent answers. For the full allowlist model across channels, see Channels overview.
Troubleshooting
Section titled “Troubleshooting”- Bot connects but never replies. Confirm the trigger type is supported: Bluesky and Reddit act on mentions/replies/DMs, not likes or upvotes. For X, make sure the sender passes
allowed_users(use["*"]while testing). - X bot goes quiet. Check for
429rate-limit back-off in the logs; the free tier is easily exhausted. Verify the bearer token with theusers/mecall that runs at startup and as the health check. - Reddit auth fails on boot. A failed token refresh means the
refresh_token,client_id, orclient_secretis wrong or revoked — re-run the external OAuth2 flow to mint a fresh refresh token. - Bluesky auth fails. Regenerate the app password in Bluesky settings; an expired or revoked app password breaks
createSession.
Raise per-channel log detail to diagnose:
RUST_LOG=revka::channels::bluesky=debug,revka::channels::twitter=debug,revka::channels::reddit=debug revka daemonRelated pages
Section titled “Related pages”- Channels overview — the channel trait, delivery modes, and allowlist model.
- Connect a messaging channel — the general channel setup workflow.
- Config: channels, tools & integrations — the full
[channels_config]schema. - Security model — how allowlists and approvals gate untrusted public input.
- Telegram, Discord & Slack — the most common bot channels, with streaming-mode options.