feat: support Premium long-form posts - #64
Conversation
|
Article publishing note: this PR intentionally only fixes long-form posts. X Articles use a separate entity flow ( |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds long-form (“Note Tweet”) support by routing oversized tweet text to X’s CreateNoteTweet GraphQL mutation, while updating feature flags, tests, and user-facing docs.
Changes:
- Add
CreateNoteTweetoperation + long-form related feature flags in GraphQL config. - Route
create_tweet/quote_tweettoCreateNoteTweetwhen text exceeds the weighted length threshold; parse results from multiple response shapes. - Add unit tests and README documentation for long-form routing behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| twitter_cli/graphql.py | Adds CreateNoteTweet operation id and enables long-form/article-related feature flags. |
| twitter_cli/client.py | Implements weighted-length routing to CreateNoteTweet, shared result extraction, and improved error messages. |
| tests/test_client.py | Adds coverage for routing logic and asserts the chosen mutation name/variables. |
| README.md | Documents automatic routing for Premium long-form posts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
#60 by @rakei076 reached the same core conclusion 17 days earlier — including the What this PR adds on top of #60:
Happy to either rebase this as a follow-up on top of #60, or have maintainers pick whichever — the quote path and the tests are the parts worth landing either way. |
|
@jackwener, I cleared the open review findings on this PR and #65. This branch now uses twitter-text v3-style weights, 23-character URL normalization, operation-scoped NoteTweet flags, and one shared create/quote routing helper. #65 now fails closed when Article publishing returns no confirmation. Full Python 3.10 suites, Ruff, and mypy pass in both branches. Could you take a look when you have time? |
Summary
Fixes #54.
Adds automatic routing to X's long-form post mutation for Premium accounts when a post exceeds the standard 280 weighted-character limit.
What changed
CreateNoteTweetin GraphQL fallback query IDs.create_tweet()andquote_tweet()toCreateNoteTweetwhen text is over the standard weighted limit.disallowed_reply_options: nullfor long-form writes; without this field X can return an emptytweet_resultsobject.CreateTweetpath.Why this scope
This intentionally keeps the patch narrower than #62: it does not add video upload or Article publishing. Article publishing appears to be a separate X entity flow (
ArticleEntityDraftCreate/ update title / update content / publish) and should be handled as a separate feature with its own payload tests.Compared with #60, this also covers quote tweets and includes local tests for the routing and payload shape.
Validation
uv run ruff check .uv run mypy twitter_cliuv run pytest -q