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:
| Mode | What posts look like |
|---|---|
off | Posts as Righteous itself |
source | Posts as the tracked account, using its own display name and profile picture. This is what a new feed does |
custom | Posts 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.
| Mode | What you get |
|---|---|
off | Nothing. The post looks like any other |
line | One line naming the account, linked to their profile |
embed | That 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
| Style | What you get |
|---|---|
card | The 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 |
link | Just the link, which Discord unfurls into its own preview |
compact | A 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.
| Reason | Fix |
|---|---|
| You paused it yourself | ,twitterfeed resume |
| The account went private | Nothing 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 lapsed | Renew 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.