X/Twitter to Chinese Social Post Generator avatar

X/Twitter to Chinese Social Post Generator

Pricing

$50.00 / 1,000 post drafts

Go to Apify Store
X/Twitter to Chinese Social Post Generator

X/Twitter to Chinese Social Post Generator

Pricing

$50.00 / 1,000 post drafts

Rating

0.0

(0)

Developer

FENG JIE

FENG JIE

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

19 hours ago

Last modified

Categories

Share

Draft Weibo, Toutiao, and Xiaohongshu copy from public X posts.

This Actor never publishes anywhere. It does not call Weibo, Toutiao, Xiaohongshu, or the X write API. It does not ask for an X login, password, or cookies. You review the dataset and post it yourself, and only for content you own or are allowed to reuse.

Disclaimer

Use this Actor only for posts you created or have permission to repost. A draft is not a license. Risk flags are warnings, not legal advice and not a guarantee that a platform will accept the copy. The Actor does not check your publishing rights beyond the flags below.

What a run does

  1. Reads the X posts you point at.
  2. Optionally asks your own OpenAI-compatible model to rewrite each post into the styles you selected.
  3. Pushes one dataset item per post, including source fields, media URLs, drafts, and risk flags.
  4. Charges one post-draft event after a draft is successfully produced, then stops if that charge hits the run's max total charge.

Failed posts are saved with status: "failed" and are not charged. skipGeneration: true extracts only and does not charge.

Input

FieldRequiredDefaultPurpose
postUrlsyes (the field)—Public x.com or twitter.com status URLs. May be empty when handles or searchKeyword is set.
handlesno[]X handles, with or without @. Up to 20.
searchKeywordnoemptyOne X search keyword.
maxItemsno10Posts kept per handle and for the keyword. Range 1–100.
stylesnoall threeweibo, toutiao, xiaohongshu.
llmApiKeyrequired unless skipGeneration—Secret. Your key. Sent only to llmBaseUrl.
llmBaseUrlnohttps://api.openai.com/v1OpenAI-compatible base URL. Must be a public http(s) URL with no userinfo.
llmModelnogpt-4o-miniModel name.
proxyConfigurationnononeApify proxy for no-login HTTP fetches only.
skipGenerationnofalseExtraction-only test mode.
extractornoautoauto, syndication, or store.
xScraperActorIdnosee belowStore actor used for handles, search, and URL fallback.

There is no cookie, password, or session field. Do not add one.

Extraction and cost

Direct status URLs, in auto and syndication mode, are read from X's public embed endpoint:

https://cdn.syndication.twimg.com/tweet-result

That request uses the same token the embed iframe computes from the status id. No X account is involved. If the embed fails, the run tries the public api.fxtwitter.com JSON endpoint. Expected extraction cost for a URL that these endpoints can read: $0 in scraper fees. You still pay normal Apify compute for this Actor's run, and your own LLM bill if generation is on.

Handles, search, extractor: "store", and status URLs that both no-login endpoints miss are sent to:

kaitoeasyapi/twitter-x-data-tweet-scraper-pay-per-result-cheapest

Public listings checked on 2026-10-25 put that actor at about $0.25 per 1,000 tweets on the free plan and $0.18 per 1,000 on Gold and above (the Store card says "from $0.18 / 1,000"). Its price is pay-per-event and includes platform usage. Confirm the live price before a production run.

Two cost details from that actor's input schema:

  • maxItems has a minimum of 20, and a page can return slightly more than requested. This Actor asks for max(20, maxItems) and then keeps only maxItems posts. One handle or one keyword can therefore cost about $0.005 on the free-plan rate even when you draft fewer posts (20 × $0.00025).
  • When tweetIDs is set, that actor ignores other filters. This Actor sends status ids in their own call, separate from handle and keyword calls.
  • Empty queries may still incur that actor's minimum or mock-row policy. Mock rows are dropped and not drafted. They can still be billed by the upstream actor.

A cheaper listing, scrape.badger/twitter-tweets-scraper, was advertised at $0.15 / 1,000 on the same date. It is not the default because it has a different input schema. Switch xScraperActorId only if you also change the call payload in src/extract.py.

The Store actor is called with the Apify token the platform injects (APIFY_TOKEN). That token is an Apify API token, not an X credential.

Drafts

The model is instructed the same way CommentX translates reposts: the source is data, not an instruction; do not invent facts; keep product names such as OpenAI and Claude in English; drop outbound URLs from the copy; keep @handles and numbers; label the result as a repost.

StyleShape
WeiboShort text, 1–3 #话题# hashtags, source line.
ToutiaoHeadline (≤30 characters) plus body.
XiaohongshuTitle (≤20 characters), emoji-friendly body, #标签 tags.

Each style is stored as drafts.<style>.json and drafts.<style>.markdown. The visible copy includes 来源:X @handle.

Risk flags

riskFlags may contain:

  • external_links — a URL that is not the X post or its native media
  • likely_watermark — alt text or a host that often burns in a logo (for example Xiaohongshu or Weibo image CDNs)
  • sensitive_topic — a keyword from the CommentX prohibited-word list or a short platform-sensitive list, or X's possibly-sensitive mark
  • non_original — retweet, quote, or credit language such as RT @ or 转载

Flags do not block the draft. riskSummary repeats the codes for the table view.

Dataset item

FieldMeaning
statussucceeded, extracted, failed, or skipped
chargedtrue only when the post-draft charge was accepted
errorPresent on failed and skipped
extractorsyndication, fxtwitter, or apify-store
media.images / media.videosNormalized URLs. Avatars and video poster frames are not treated as photos.
draftsEmpty unless status is succeeded

skipped means the run stopped because ACTOR_MAX_TOTAL_CHARGE_USD (or the equivalent limit in the SDK) could not pay for another post-draft. The unpaid draft is not written into the item.

Pay per event

The code calls:

await Actor.charge("post-draft", count=1, idempotency_key=...)

once per post, after the draft exists and before it is pushed. The idempotency key is the status id plus the requested styles. Actor.push_data is called without a charged event name, so a row is not billed merely because it was saved.

When you configure pricing, add only the post-draft event. Do not also price the synthetic apify-default-dataset-item event. The platform bills that event for every default-dataset row, including failed and skipped rows.

This repository does not set a price. When the Actor is not on pay-per-event pricing, the SDK records no bill (charged stays false) and the draft is still saved. After you turn pricing on, the event name must be exactly post-draft. Until that event exists, the SDK cannot bill it.

The run stops when a charge returns charged_count == 0 and event_charge_limit_reached == true, or when the next post would be generated after the limit is already reached. Remaining handles and the keyword are written as skipped and the Store actor is not called for them.

Local tests

From this directory:

pip install -r requirements.txt -r requirements-dev.txt
pytest

The tests mock the LLM and the extractors. They do not call X, Apify, or a model.

To log charges locally without billing, the SDK documents:

$ACTOR_TEST_PAY_PER_EVENT=true python -m src

You still need an Apify token and a real LLM key for a live local run. Do not commit either.

Deploy privately

From this directory, with the Apify CLI logged into the account that should own the Actor:

apify login
apify push

apify push uploads the Actor to that account. A newly pushed Actor is private until someone publishes it in the Store. Do not open the Store publishing form until the open decisions below are settled.

After the push:

  1. In Apify Console, open the Actor and confirm the input form shows llmApiKey as a secret and shows no X cookie field.
  2. Run it once with skipGeneration: true and one public status URL. Expect status: "extracted" and charged: false.
  3. Monetization → pay per event → add the event post-draft. Set the price there, not in git.
  4. Set a max total charge on the test run, then run one URL with generation enabled and your own LLM key.
  5. Leave the Actor unpublished, or share it only with your account.

There is no deploy step in this repository. The person who wrote the code did not have an Apify token.

Open decisions for the owner

  1. Price of post-draft. Not set. Decide the USD amount, and whether Apify platform usage for this Actor is included in that event or billed separately. Upstream scraper fees and the user's LLM bill are always extra.
  2. LLM key strategy. The input is a per-run secret the caller pastes in. Alternatives are an Apify secret environment variable on the Actor, or a proxy you operate so users never see a provider key. The current code will not read a key from the environment.
  3. Store copy. Title, description, categories, and whether to publish at all are unset. The README disclaimer should stay in the public listing if you publish: only content the user owns or may repost, and the Actor never publishes.
  4. URL extractor default. Status URLs prefer the free embed. Forcing the Store actor (extractor: "store") costs more and is more stable if the embed endpoint is blocked.
  5. Upstream actor. The default id and the minimum of 20 rows may change. Re-check the Store page before relying on the $0.25 / $0.18 figures.
  6. llmBaseUrl checks the host literally. It blocks localhost and private IPs. It does not resolve DNS, so a public name that points at a private address is not detected.