Skip to content

feat: add sendTweet with media upload support#193

Open
Faareoh wants to merge 4 commits into
the-convocation:mainfrom
Faareoh:feat/send-tweet
Open

feat: add sendTweet with media upload support#193
Faareoh wants to merge 4 commits into
the-convocation:mainfrom
Faareoh:feat/send-tweet

Conversation

@Faareoh

@Faareoh Faareoh commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

⚠️ This PR was entirely generated by Claude (claude-sonnet-4-6), inspired by
the reference implementation at https://github.com/0x4337/agent-twitter-client-grokky.

Summary

  • src/api-data.ts — adds mutationEndpoints.CreateTweet (current queryId + x.com URL)
  • src/tweets.ts — implements uploadMedia() (chunked video + simple image) and sendTweet() returning Tweet | null
  • src/scraper.ts — exposes sendTweet() as a public method on the Scraper class
  • src/_module.ts — exports the new MediaData type
  • src/tweet-mutations.test.ts — unit tests + opt-in integration tests for the mutation

Key details

  • Uses the CreateTweet GraphQL mutation (queryId: S1qcGUn68_U0lDKdMlYSGg) via POST x.com/i/api/graphql/…
  • Injects __typename: 'Tweet' on the response when absent (the CreateTweet API omits it) so the existing parser can handle it
  • Generates x-client-transaction-id when the experimental.xClientTransactionId option is enabled, to avoid Twitter's 226 "looks automated" errors
  • MediaData accepts { data: Buffer, mediaType: string }; videos use the chunked INIT/APPEND/FINALIZE flow with status polling

Test plan

  • npm test — all unit tests pass
  • Integration tests run with real credentials: set TWITTER_* env vars and run npx jest tweet-mutations --testNamePattern=integration

Faareoh added 4 commits April 10, 2026 14:14
Adds scraper.sendTweet() for posting tweets via the CreateTweet GraphQL
mutation, including image/video media upload through the chunked upload API.

- Add mutationEndpoints (CreateTweet queryId + URL) to api-data.ts
- Implement uploadMedia() with chunked video upload + polling and simple
  image upload paths
- Implement sendTweet() returning Tweet | null; injects __typename when
  absent from the CreateTweet API response to satisfy the parser
- Add optional x-client-transaction-id generation to avoid 226 errors
- Expose sendTweet on the Scraper class and export MediaData from _module.ts
- Add unit + opt-in integration tests in tweet-mutations.test.ts
@Morad37

Morad37 commented Jun 6, 2026

Copy link
Copy Markdown

The sendTweet function and its integration with media upload is a solid addition. One area that could use hardening: the media/upload step's error response is not shown being validated in the available diff. If X returns a non-JSON response or a response missing media_id_string, the downstream code would attempt to use undefined as the media ID, which would likely produce a confusing API error from the CreateTweet endpoint. Consider validating that the upload response contains a valid string media_id_string before continuing to the tweet mutation, and returning a clear error if it doesn't. The test mock always returns { media_id_string: 'mock_media_id' }, which is fine for happy-path coverage but means an upload failure would not be exercised. A test case with a mock that returns an error from media/upload would fill that gap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants