Skip to content
← Public packages

@kentcdodds/x

X API v2 helpers for tweets, search, legacy DMs, and encrypted X Chat via a Fly XDK sidecar.

src/create-post.ts

42 lines · 2.0 KB · TypeScript
import { createPost } from './client.ts'
import type { XCreatePostParams } from './client.ts'

/**
 * Create or dry-run an X post; publishing requires confirm: true.
 * Pass `account: '<purpose>'` for integration `x-<purpose>` (default omit → `x`).
 * X API path remains POST /2/tweets.
 *
 * **Replies:** pass `reply: { in_reply_to_tweet_id: '<id>' }` (X API shape).
 * Aliases `replyTo`, `inReplyTo`, `inReplyToTweetId`, `parentId`, and `parentTweetId` are mapped into that
 * shape. Other unknown keys are **rejected** (no silent drop). When the user
 * asked for a reply, dry-run first and confirm `mode: 'reply'` (and
 * `inReplyToTweetId`) before `confirm: true`. Prefer `./reply-post` when a
 * parent id is required.
 *
 * **Exclude reply mentions:** pass `reply.exclude_reply_user_ids: string[]`
 * (X API) or top-level `excludeReplyUserIds` / `exclude_reply_user_ids` when
 * someone asked not to be mentioned, or a follow-up should not ping everyone
 * in the reply chain. Dry-run / confirm echo those ids.
 *
 * **Reply mentions:** X auto-prefixes reply-chain @handles. Do **not** start
 * reply text with those handles — leading `@name` tokens are stripped before
 * send. Dry-run / confirm results include `originalText`, `text`, and
 * `strippedHandles` when replying.
 *
 * **Media:** upload with `./upload-media`, then pass `media: { media_ids: [mediaId] }`.
 *
 * @returns Created post payload, or dry-run request description including
 *   `mode: 'reply' | 'standalone'` (plus parent id fields when a reply).
 * @example
 * import createPost from 'kody:@kentcdodds/x/create-post'
 * const draft = await createPost({
 *   account: 'kodykoala',
 *   text: 'Hello world',
 *   reply: { in_reply_to_tweet_id: '2103670212524380386' },
 *   dryRun: true,
 * })
 * // => { dryRun: true, mode: 'reply', inReplyToTweetId: '...', requiresConfirm: true, ... }
 */
export default async function createPostEntrypoint(params: XCreatePostParams | Record<string, unknown> = {}) {
	return await createPost(params)
}