Skip to main content
Righteous

Twitter Feeds

Mirror a public X/Twitter account's new posts into a channel, with video, photos and GIFs. Setup, filters, pinging, and the three different reasons a feed can go quiet.

Twitter Feeds mirrors a public X/Twitter account's new posts into a channel, checking roughly every two minutes. Video, photos and GIFs come along with the post, not just a link. Changing anything needs Manage Server and Server Premium, but reading is free: if your Server Premium has lapsed, you can still see exactly what's configured and why a channel has gone quiet. The command is ,twitterfeed (also ,tweets or ,xfeed), and the slash form is /feeds twitter.

Add a feed

Syntax

,twitterfeed add <#channel> <@handle> [message]

Example

,twitterfeed add #news @NASA

Give it the channel and the handle. You can type the handle with or without the @, or paste a link to the profile instead. A server can hold up to 5 feeds. If your server is already at the limit when you try to add another, remove one first; a server that was already over the limit before it dropped keeps every feed it has.

A new feed starts from now. It doesn't dump the account's history into the channel, so the first thing you'll see posted is whatever that account posts after you added it, not anything older.

Only public accounts

Twitter Feeds can't read a private account's posts, so adding one is refused by name up front rather than silently failing later.

If an account you already follow goes private afterwards, the feed is paused and list says exactly that: the account is now private. Nothing is deleted. If they go public again, run ,twitterfeed retry and the feed picks up from where it left off.

To remove a feed:

Syntax

,twitterfeed remove <#channel> <@handle>

Example

,twitterfeed remove #news @NASA

Check what's configured, free of charge

Syntax

,twitterfeed list

Syntax

,twitterfeed info <#channel> <@handle>

Example

,twitterfeed info #news @NASA

list shows every feed in the server; info shows one feed's full setup and current status. Neither needs Server Premium; only Manage Server to view your own server's configuration. This is deliberate: an admin whose channel has gone quiet because Server Premium lapsed is exactly the person who most needs to see why, and paywalling the explanation would refuse them.

Choose what gets mirrored

Retweets, replies to other accounts, and an account's own multi-post threads can each be switched off independently, per feed:

Syntax

,twitterfeed retweets <#channel> <@handle> <on|off>

Example

,twitterfeed retweets #news @NASA off

Syntax

,twitterfeed replies <#channel> <@handle> <on|off>

Example

,twitterfeed replies #news @NASA off

Syntax

,twitterfeed threads <#channel> <@handle> <on|off>

Example

,twitterfeed threads #news @NASA off

All three are on by default. Turning threads off, for instance, hides an account's own continuation posts but still mirrors a completely separate new post from the same account.

You can also give a feed a short, display-only nickname, useful once a channel has more than one feed and the handle alone stops being a helpful label:

Syntax

,twitterfeed label <#channel> <@handle> <text|off>

Example

,twitterfeed label #news @NASA Space News

Add a trailing message, and a ping

Syntax

,twitterfeed message <#channel> <@handle> <text|off> [@role] [@everyone]

Example

,twitterfeed message #news @NASA Breaking: @Staff

This sets text that gets posted along with every one of that feed's posts, and it's also the only place you configure a ping. Mentioning a role, or typing @everyone, needs Mention Everyone on top of Manage Server and Server Premium. Running this command replaces the whole message and ping setup at once: run it again with plain text and no mention, and any ping you had configured is cleared along with it.

The mention has to actually be in the message text

This is the single most confusing part of the feature. Discord only sends a notification from a mention that is genuinely part of the message content, so a role picked without a real @role mention typed into the text pings nobody: it renders, it looks configured, and it never fires. The bot checks for this and warns you when a role you referenced isn't actually in the text. If you want a ping, make sure the @role or @everyone is written directly into the message you give this command, not just implied by it.

Post under a different name and picture

A new feed's posts arrive wearing the tracked account's own name and picture. You can change that per feed, so they post as Righteous instead or under a name you pick yourself.

Syntax

,twitterfeed webhook <#channel> <@handle> <off|source|custom|name|avatar> [value]

Example

,twitterfeed webhook #news @NASA source

There are three modes:

ModeWhat posts look like
offPosts as Righteous itself
sourcePosts as the tracked account, using its own display name and profile picture. This is what a new feed does
customPosts as a name and picture you set yourself

For custom, set the two pieces separately:

Syntax

,twitterfeed webhook <#channel> <@handle> name <text>

Example

,twitterfeed webhook #news @NASA name Space News

Syntax

,twitterfeed webhook <#channel> <@handle> avatar <url>

Example

,twitterfeed webhook #news @NASA avatar https://example.com/icon.png

You can also set a name, a picture, and a default mode once for the whole server, which every feed that has not chosen for itself will use. This is shared with GitHub Feeds, so setting it from either command sets it for both:

Syntax

,twitterfeed webhook default <name|avatar|mode> [value]

Example

,twitterfeed webhook default mode source

A feed that chose for itself always wins

Setting off on a feed means "never wear an identity" and is respected even when the server default says otherwise. Only a feed that has never been given a mode of its own follows the server.

Turning it off stays free

Switching a feed back to off works even if your Server Premium has lapsed, and so does reading what is configured. Only source and custom, and setting a name or picture, need Server Premium. A feed whose Server Premium has lapsed keeps its setting and simply posts as Righteous until you renew, and info shows you that is what is happening rather than showing a name your posts are not actually wearing.

Righteous needs Manage Webhooks in the channel

Posting under a different name uses a webhook, which Righteous creates in the channel the first time it needs one. Without the Manage Webhooks permission it cannot create one, so posts arrive as Righteous instead. Nothing is ever lost this way: the post still goes out, and ,twitterfeed info tells you exactly why it is not wearing the identity you set. Grant the permission and the next post picks it up on its own.

Posts get tidier when the feed wears the account's identity

When a feed posts as the account itself (source), the card stops repeating what the message header already shows: the account's name and picture appear once, at the top, instead of again inside the embed. The post text, the stats and the time it was posted stay where they are.

This only applies to source. A custom name like "Pop News" does not tell anyone which account a post came from, so those cards keep naming the account inside the embed.

Choose which numbers show

Syntax

,twitterfeed stats <#channel> <@handle> <replies|retweets|likes|views|all> <on|off>

Example

,twitterfeed stats #news @NASA views off

Cards carry a row of numbers from the post: replies, retweets, likes and views. Each can be switched off on its own, or all four at once with all.

This is not the same as the retweets and replies settings above

,twitterfeed stats ... retweets off hides the retweet count on a card. ,twitterfeed retweets off stops the feed mirroring retweets at all. They are different settings that happen to share a word.

Copy one feed's setup onto another

Syntax

,twitterfeed copy <#from> <@from> <#to> <@to>

Example

,twitterfeed copy #news @NASA #space @SpaceX

Copies the style, the webhook name and picture, the retweet/reply/thread settings, and the trailing message and ping. It never copies the channel or the account, so the destination feed keeps mirroring what it always did, just presented the same way.

The ping is re-checked against the destination

Pinging needs the Mention Everyone permission in the channel a feed posts to, and that can differ per channel. If you do not have it where the feed is going, everything else still copies and the ping is left off, with a note saying so.

Show the post a reply or quote is about

Syntax

,twitterfeed reply <#channel> <@handle> <off|line|embed>

Example

,twitterfeed reply #news @NASA embed

A mirrored post is often answering or quoting someone else, and on its own it reads as a non-sequitur. The card can show what it is about.

ModeWhat you get
offNothing. The post looks like any other
lineOne line naming the account, linked to their profile
embedThat line, plus the other tweet underneath as its own card with its text and picture. This is the default

The line says which relationship it is: ↩ replying to @name for a reply, Quoted @name for a quote tweet. It sits above the post text, so the card reads top to bottom in the order it happened: who was answered, what they said, then the post itself.

Quotes are free, replies cost a lookup

A quote tweet arrives with the quoted tweet already attached, so embed costs nothing extra for those. A reply only arrives with a pointer to what it answered, so showing that one needs a second lookup. Either way the picture is linked rather than re-uploaded, so nothing is downloaded twice.

If the other tweet is gone, the post still arrives

Deleted, or from an account that has since gone private, or the lookup simply fails: the post is mirrored anyway and just falls back to the line on its own. A missing parent never costs you the post.

Choose how posts look

Syntax

,twitterfeed style <#channel> <@handle> <card|link|compact>

Example

,twitterfeed style #news @NASA link
StyleWhat you get
cardThe full card with video, photos and the download buttons. This is the default, and it now applies to text-only tweets too rather than falling back to a plain link
linkJust the link, which Discord unfurls into its own preview
compactA small embed: the account, the post text, and any media as a thumbnail

link and compact are quieter in a busy channel. Any trailing message and ping you configured still comes along with every style, so switching style never silently drops a ping.

Compact keeps its own link button

Discord only shows a link preview when a message has no embed of its own, so the compact style carries an Open on Twitter button instead. link is the style to pick if you specifically want Discord's own preview.

Why a feed goes quiet

A feed can stop posting for a few different reasons, and the fix is different for each one. None of them ever deletes a feed; they only pause it.

ReasonFix
You paused it yourself,twitterfeed resume
The account went privateNothing you can do from here. If they go public again, ,twitterfeed retry
The account or the connection to Twitter failed repeatedly,twitterfeed retry
Server Premium lapsedRenew it. Nothing was deleted, and every feed picks back up once you're paying again

Match the fix to the reason, or nothing changes

Resuming a feed that's actually broken doesn't fix it, and retrying a feed you paused on purpose doesn't un-pause it: each of these three touches only its own reason and leaves the other two exactly as they are. ,twitterfeed list and ,twitterfeed info tell you which reason currently applies to a feed, including when more than one does at once.

Syntax

,twitterfeed pause <#channel> <@handle>

Example

,twitterfeed pause #news @NASA

Syntax

,twitterfeed resume <#channel> <@handle>

Example

,twitterfeed resume #news @NASA

Syntax

,twitterfeed retry <#channel> <@handle>

Example

,twitterfeed retry #news @NASA

Test a feed without waiting for a real post

Syntax

,twitterfeed test <#channel> <@handle>

Example

,twitterfeed test #news @NASA

Posts that account's newest post into the channel right now, rendered exactly the way a real post would be, honoring the feed's own retweet/reply/thread filters. Nothing about the feed is changed: it's a preview, not a real check-in. If the feed has a ping configured, this test does not fire it; the real feed will still ping normally on its next genuine post.

Manage everything from one panel

Syntax

/feeds panel

Opens a private card for managing your Twitter, GitHub and Letterboxd feeds, with a tab for each. It updates in place as you navigate or act on a feed, and it stays visible only to whoever opened it. This only opens over slash, on purpose, so it stays private: running ,twitterfeed panel, ,github panel or ,letterboxdfeed panel on prefix points you at /feeds panel instead of posting anything. Opening the panel is free; acting on a feed from it needs the same Manage Server and Server Premium the matching command needs.

You can add a Twitter feed from the panel too: press Add, pick the channel, then type the handle in the form that opens. GitHub feeds are added with ,github add instead, because setting one up hands you a secret that has to be sent to you privately rather than shown on a shared card. Letterboxd feeds are covered in their own guide: see Letterboxd.

For what all three feed platforms have in common, GitHub's real-time webhook versus Twitter and Letterboxd's polling, Server Premium and what happens when it lapses, and the reasons any feed goes quiet, see Feeds.

Honest limits

  • Public accounts only. A private account is refused when you try to add it, not silently ignored later.
  • A very large video degrades to a link. If a post's video is bigger than your server's upload limit, it posts as a link plus the usual card instead of failing to attach.
  • This is separate from ,config social twitter. That toggle governs links members paste into chat, not a feed you've configured here. Turning it off doesn't pause a feed, and a feed keeps posting whether it's on or off.

Common issues

A feed I added dumped a bunch of old tweets into the channel. It shouldn't: a new feed starts from the moment you add it. If you're seeing old posts, check whether the feed shows as broken with ,twitterfeed info; a feed recovering from an outage still only posts what's genuinely new, never a backlog.

I set up a ping and it never notifies anyone. Almost always this is the mention not actually being in the message text; see Add a trailing message, and a ping above. Re-run ,twitterfeed message with a real @role mention or @everyone typed into the text.

A feed stopped posting and I don't know why. Run ,twitterfeed info on it: it tells you which of the three reasons in Why a feed goes quiet applies, including when more than one does.

,twitterfeed add refuses a handle. Either it isn't a valid X handle or profile link, the account doesn't exist, or the account is private, in which case Twitter Feeds can't read it at all.

,twitterfeed panel or ,github panel doesn't open anything. These only work over slash; use /feeds panel instead.

I set a custom name or picture and posts still arrive as Righteous. Run ,twitterfeed info on the feed. It tells you which of these it is: Righteous is missing Manage Webhooks in that channel, the channel already holds Discord's maximum of 15 webhooks, Discord rejected the name you chose, or your Server Premium has lapsed. The posts keep arriving throughout, so this is always a cosmetic problem rather than a lost feed.

My picture never shows up. Discord has to be able to fetch the image at the URL you gave. A link that needs a login, or one that is not a direct image, silently produces no picture rather than an error.