Articles
Read and manage Twitter Articles (long-form posts).
WARNING
Creating, editing, and publishing articles requires an eligible Twitter Premium account. The read methods (get, byUser, published, drafts) work on any account.
The write methods take content_state, which is the article editor's rich-text content state (Draft.js raw content state). emusks forwards it to Twitter unchanged rather than constructing it for you.
articles.get(articleEntityId)
Fetch a single article by its entity id. Uses the GraphQL ArticleEntityResultByRestId query.
const article = await client.articles.get("1234567890");articles.forTweet(tweetId)
Fetch the full article attached to a post, by the post's id. Uses the GraphQL TweetResultsByRestIds query with the withArticleRichContentState and withArticlePlainText field toggles. Returns null when the post has no article.
const article = await client.articles.forTweet("2105653173314887758");
// {
// rest_id: "2105652739669999616",
// title: "...",
// preview_text: "...",
// plain_text: "...",
// cover_media: { media_info: { original_img_url, ... } },
// media_entities: [{ media_id, media_info: { __typename: "ApiImage" | "ApiVideo", ... } }],
// content_state: { blocks: [...], entityMap: [...] },
// metadata: { first_published_at_secs },
// }articles.get(articleEntityId) returns an empty result for other people's articles, so use this method to read them. The id in an x.com/i/article/<id> link is the article entity id, not the post id.
content_state is a Draft.js raw content state. Block types seen so far are unstyled, header-one, header-two, unordered-list-item, ordered-list-item, blockquote and atomic. Inline styles are Bold and Italic. entityMap is an array of { key, value }, and a block's entityRanges[].key points at key. Entity types are LINK (data.url), MEDIA (data.mediaItems[].mediaId, matched against media_entities[].media_id), TWEET (data.tweetId), DIVIDER, TWEMOJI (data.url) and MARKDOWN (data.markdown, used for code blocks). An atomic block holds one entity.
articles.byUser(userId, opts?)
Get a user's published articles as a parsed timeline. Uses the GraphQL UserArticlesTweets query.
| Option | Type | Description |
|---|---|---|
userId | string | The user id |
opts.count | number | Number of results (default 20) |
opts.cursor | string | Pagination cursor |
opts.raw | boolean | Return the raw GraphQL response instead of a parsed timeline |
const timeline = await client.articles.byUser("44196397");articles.published(userId, opts?) / articles.drafts(userId, opts?)
List a user's articles by lifecycle. Both wrap the GraphQL ArticleEntitiesSlice query (slice(userId, lifecycle)).
const published = await client.articles.published("44196397");
const drafts = await client.articles.drafts(myUserId);articles.createDraft(contentState, opts?)
Create a new draft article. Uses the GraphQL ArticleEntityDraftCreate mutation.
const draft = await client.articles.createDraft(contentState);articles.updateTitle(articleEntityId, title)
Update an article's title. Uses the GraphQL ArticleEntityUpdateTitle mutation.
await client.articles.updateTitle(articleEntityId, "My headline");articles.updateContent(articleEntityId, contentState)
Replace an article's body. Uses the GraphQL ArticleEntityUpdateContent mutation.
await client.articles.updateContent(articleEntityId, contentState);articles.updateCoverMedia(articleEntityId, coverMediaId)
Set the cover image. Pass a media id from the media upload flow. Uses the GraphQL ArticleEntityUpdateCoverMedia mutation.
await client.articles.updateCoverMedia(articleEntityId, mediaId);articles.publish(articleEntityId) / articles.unpublish(articleEntityId)
Publish or unpublish an article. Use the GraphQL ArticleEntityPublish and ArticleEntityUnpublish mutations.
await client.articles.publish(articleEntityId);
await client.articles.unpublish(articleEntityId);articles.remove(articleEntityId)
Delete an article. Uses the GraphQL ArticleEntityDelete mutation.
await client.articles.remove(articleEntityId);