@robinpath/twitter
Advanced tools
| import type { ModuleAdapter } from "@robinpath/core"; | ||
| declare const TwitterModule: ModuleAdapter; | ||
| export default TwitterModule; | ||
| export { TwitterModule }; | ||
| export { TwitterFunctions, TwitterFunctionMetadata, TwitterModuleMetadata, TwitterCredentialTypes, } from "./twitter.js"; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AASrD,QAAA,MAAM,aAAa,EAAE,aAQpB,CAAC;AAEF,eAAe,aAAa,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,cAAc,CAAC"} |
| import { TwitterFunctions, TwitterFunctionMetadata, TwitterModuleMetadata, TwitterCredentialTypes, configureTwitter, } from "./twitter.js"; | ||
| const TwitterModule = { | ||
| name: "twitter", | ||
| functions: TwitterFunctions, | ||
| functionMetadata: TwitterFunctionMetadata, | ||
| moduleMetadata: TwitterModuleMetadata, | ||
| credentialTypes: TwitterCredentialTypes, | ||
| configure: configureTwitter, | ||
| global: false, | ||
| }; | ||
| export default TwitterModule; | ||
| export { TwitterModule }; | ||
| export { TwitterFunctions, TwitterFunctionMetadata, TwitterModuleMetadata, TwitterCredentialTypes, } from "./twitter.js"; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAEtB,MAAM,aAAa,GAAkB;IACnC,IAAI,EAAE,SAAS;IACf,SAAS,EAAE,gBAAgB;IAC3B,gBAAgB,EAAE,uBAAuB;IACzC,cAAc,EAAE,qBAAqB;IACrC,eAAe,EAAE,sBAAsB;IACvC,SAAS,EAAE,gBAAgB;IAC3B,MAAM,EAAE,KAAK;CACd,CAAC;AAEF,eAAe,aAAa,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,cAAc,CAAC"} |
| /** | ||
| * RobinPath Twitter (X) Module (Node port) | ||
| * | ||
| * X (formerly Twitter) v2 API integration. Mirror of | ||
| * packages/php/twitter/src/index.php for the WordPress plugin; shares the | ||
| * same credential contract, metadata shape, and error taxonomy so the | ||
| * visual editor can render both identically. | ||
| * | ||
| * Authentication uses the RobinPath credential vault. Every handler takes | ||
| * a credential slug as its first argument; the module resolves the stored | ||
| * OAuth 2.0 user-context access token at call time via the injected | ||
| * ModuleHost. The clientId and clientSecret fields are optional and only | ||
| * needed if you intend to implement refresh-token rotation (not handled | ||
| * by this module — refresh the token externally and re-save the | ||
| * credential). | ||
| * | ||
| * Credential types declared by this module: | ||
| * - twitter_oauth2 : { accessToken, clientId?, clientSecret? } | ||
| */ | ||
| import type { BuiltinHandler, CredentialTypeSchema, FunctionMetadata, ModuleHost, ModuleMetadata } from "@robinpath/core"; | ||
| export declare function configureTwitter(h: ModuleHost): void; | ||
| export declare const TwitterFunctions: Record<string, BuiltinHandler>; | ||
| export declare const TwitterCredentialTypes: CredentialTypeSchema[]; | ||
| export declare const TwitterFunctionMetadata: Record<string, FunctionMetadata>; | ||
| export declare const TwitterModuleMetadata: ModuleMetadata; | ||
| //# sourceMappingURL=twitter.d.ts.map |
| {"version":3,"file":"twitter.d.ts","sourceRoot":"","sources":["../src/twitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,cAAc,EAEf,MAAM,iBAAiB,CAAC;AAezB,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAEpD;AAsbD,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAS3D,CAAC;AAIF,eAAO,MAAM,sBAAsB,EAAE,oBAAoB,EAmCxD,CAAC;AA2GF,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA2SpE,CAAC;AAIF,eAAO,MAAM,qBAAqB,EAAE,cAkCnC,CAAC"} |
+755
| /** | ||
| * RobinPath Twitter (X) Module (Node port) | ||
| * | ||
| * X (formerly Twitter) v2 API integration. Mirror of | ||
| * packages/php/twitter/src/index.php for the WordPress plugin; shares the | ||
| * same credential contract, metadata shape, and error taxonomy so the | ||
| * visual editor can render both identically. | ||
| * | ||
| * Authentication uses the RobinPath credential vault. Every handler takes | ||
| * a credential slug as its first argument; the module resolves the stored | ||
| * OAuth 2.0 user-context access token at call time via the injected | ||
| * ModuleHost. The clientId and clientSecret fields are optional and only | ||
| * needed if you intend to implement refresh-token rotation (not handled | ||
| * by this module — refresh the token externally and re-save the | ||
| * credential). | ||
| * | ||
| * Credential types declared by this module: | ||
| * - twitter_oauth2 : { accessToken, clientId?, clientSecret? } | ||
| */ | ||
| // ── Module-local state (populated by configure hook) ──────────────────── | ||
| const state = {}; | ||
| function host() { | ||
| if (!state.host) { | ||
| throw new Error("Twitter module not initialized. Pass the adapter to rp.registerModule() via loadModule so its configure() hook runs first."); | ||
| } | ||
| return state.host; | ||
| } | ||
| export function configureTwitter(h) { | ||
| state.host = h; | ||
| } | ||
| // ── Constants ────────────────────────────────────────────────────────── | ||
| const API_BASE = "https://api.twitter.com/2/"; | ||
| const CREDENTIAL_TYPE = "twitter_oauth2"; | ||
| function errorReturn(error, code, extra = {}) { | ||
| return { error, code, ...extra }; | ||
| } | ||
| // ── Credential resolver ──────────────────────────────────────────────── | ||
| async function resolveToken(credentialSlug) { | ||
| if (!credentialSlug) { | ||
| return errorReturn("Credential slug is required.", "credential_not_found"); | ||
| } | ||
| let fields; | ||
| try { | ||
| fields = await host().credentials.get(credentialSlug); | ||
| } | ||
| catch (e) { | ||
| return errorReturn(e instanceof Error ? e.message : String(e), "credential_not_found"); | ||
| } | ||
| if (!fields) { | ||
| return errorReturn(`Credential '${credentialSlug}' not found.`, "credential_not_found"); | ||
| } | ||
| const token = String(fields.accessToken ?? ""); | ||
| if (!token) { | ||
| return errorReturn(`Credential '${credentialSlug}' has no \`accessToken\` field.`, "token_missing"); | ||
| } | ||
| return { token }; | ||
| } | ||
| // ── HTTP helper (normalized envelope, never throws for API errors) ───── | ||
| async function callApi(credentialSlug, method, path, query, body) { | ||
| const resolved = await resolveToken(credentialSlug); | ||
| if ("error" in resolved) | ||
| return resolved; | ||
| let url = `${API_BASE}${path}`; | ||
| if (query && Object.keys(query).length > 0) { | ||
| const params = new URLSearchParams(); | ||
| for (const [k, v] of Object.entries(query)) { | ||
| if (v === undefined || v === null || v === "") | ||
| continue; | ||
| params.set(k, String(v)); | ||
| } | ||
| const qs = params.toString(); | ||
| if (qs) | ||
| url += (url.includes("?") ? "&" : "?") + qs; | ||
| } | ||
| const headers = { | ||
| Authorization: `Bearer ${resolved.token}`, | ||
| Accept: "application/json", | ||
| }; | ||
| const init = { | ||
| method: method.toUpperCase(), | ||
| headers, | ||
| }; | ||
| if (body !== null) { | ||
| headers["Content-Type"] = "application/json; charset=utf-8"; | ||
| init.body = JSON.stringify(body); | ||
| } | ||
| const label = `${method.toUpperCase()} ${path}`; | ||
| let response; | ||
| try { | ||
| response = await fetch(url, init); | ||
| } | ||
| catch (e) { | ||
| return errorReturn(e instanceof Error ? e.message : String(e), "transport"); | ||
| } | ||
| const status = response.status; | ||
| const rawBody = await response.text(); | ||
| let decoded; | ||
| try { | ||
| decoded = rawBody ? JSON.parse(rawBody) : {}; | ||
| } | ||
| catch { | ||
| decoded = null; | ||
| } | ||
| if (!decoded || typeof decoded !== "object") { | ||
| return errorReturn(`X returned non-JSON for ${label}: ${rawBody.slice(0, 200)}`, "transport", { status }); | ||
| } | ||
| // 2xx with a body → success. | ||
| if (status >= 200 && status < 300) { | ||
| return decoded; | ||
| } | ||
| // X v2 error envelope: { title, detail, type, status, errors? } | ||
| let code; | ||
| if (status === 401) | ||
| code = "unauthorized"; | ||
| else if (status === 429) | ||
| code = "rate_limited"; | ||
| else | ||
| code = "twitter_error"; | ||
| const body_ = decoded; | ||
| const message = String(body_.detail ?? body_.title ?? `X ${label} failed (HTTP ${status})`); | ||
| return { | ||
| ...body_, | ||
| error: message, | ||
| code, | ||
| status, | ||
| twitter_error: String(body_.type ?? body_.title ?? ""), | ||
| }; | ||
| } | ||
| // ── Field-query helper (mirrors PHP buildFieldQuery) ─────────────────── | ||
| function buildFieldQuery(opts, map) { | ||
| const out = {}; | ||
| for (const [optKey, apiKey] of Object.entries(map)) { | ||
| const value = opts[optKey]; | ||
| if (value === undefined || value === null || value === "") | ||
| continue; | ||
| if (Array.isArray(value)) { | ||
| out[apiKey] = value.map((v) => String(v)).join(","); | ||
| } | ||
| else { | ||
| out[apiKey] = String(value); | ||
| } | ||
| } | ||
| return out; | ||
| } | ||
| // ── Cached lookup of authenticated user ID ───────────────────────────── | ||
| const myUserIdCache = {}; | ||
| async function resolveMyUserId(credentialSlug) { | ||
| if (myUserIdCache[credentialSlug]) { | ||
| return myUserIdCache[credentialSlug]; | ||
| } | ||
| const result = await callApi(credentialSlug, "GET", "users/me", null, null); | ||
| if ("error" in result) { | ||
| return result; | ||
| } | ||
| const data = (result.data && typeof result.data === "object" | ||
| ? result.data | ||
| : {}); | ||
| const id = String(data.id ?? ""); | ||
| if (!id) { | ||
| return errorReturn("Could not determine the authenticated user ID from /users/me.", "twitter_error"); | ||
| } | ||
| myUserIdCache[credentialSlug] = id; | ||
| return id; | ||
| } | ||
| // ── Handlers ─────────────────────────────────────────────────────────── | ||
| const postTweet = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const text = String(args[1] ?? ""); | ||
| const opts = (args[2] && typeof args[2] === "object" ? args[2] : {}); | ||
| const mediaIds = opts.mediaIds; | ||
| const poll = opts.poll; | ||
| const hasMedia = Array.isArray(mediaIds) && mediaIds.length > 0; | ||
| const hasPoll = poll && typeof poll === "object"; | ||
| if (text === "" && !hasMedia && !hasPoll) { | ||
| return errorReturn("Tweet text (or mediaIds/poll) is required.", "twitter_error"); | ||
| } | ||
| const body = {}; | ||
| if (text !== "") | ||
| body.text = text; | ||
| if (opts.replyToTweetId) { | ||
| body.reply = { in_reply_to_tweet_id: String(opts.replyToTweetId) }; | ||
| } | ||
| if (opts.quoteTweetId) { | ||
| body.quote_tweet_id = String(opts.quoteTweetId); | ||
| } | ||
| if (Array.isArray(mediaIds) && mediaIds.length > 0) { | ||
| body.media = { media_ids: mediaIds.map((m) => String(m)) }; | ||
| } | ||
| if (poll && typeof poll === "object") { | ||
| const p = poll; | ||
| const pollOptions = Array.isArray(p.options) ? p.options : []; | ||
| body.poll = { | ||
| options: pollOptions, | ||
| duration_minutes: p.duration_minutes !== undefined ? Number(p.duration_minutes) | 0 : 1440, | ||
| }; | ||
| } | ||
| if (opts.forSuperFollowersOnly !== undefined) { | ||
| body.for_super_followers_only = Boolean(opts.forSuperFollowersOnly); | ||
| } | ||
| if (opts.replySettings !== undefined) { | ||
| body.reply_settings = String(opts.replySettings); | ||
| } | ||
| return (await callApi(cred, "POST", "tweets", null, body)); | ||
| }; | ||
| const deleteTweet = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const tweetId = String(args[1] ?? ""); | ||
| if (!tweetId) { | ||
| return errorReturn("Tweet ID is required.", "twitter_error"); | ||
| } | ||
| return (await callApi(cred, "DELETE", `tweets/${encodeURIComponent(tweetId)}`, null, null)); | ||
| }; | ||
| const getTweet = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const tweetId = String(args[1] ?? ""); | ||
| const opts = (args[2] && typeof args[2] === "object" ? args[2] : {}); | ||
| if (!tweetId) { | ||
| return errorReturn("Tweet ID is required.", "twitter_error"); | ||
| } | ||
| const query = buildFieldQuery(opts, { | ||
| tweetFields: "tweet.fields", | ||
| expansions: "expansions", | ||
| userFields: "user.fields", | ||
| mediaFields: "media.fields", | ||
| pollFields: "poll.fields", | ||
| placeFields: "place.fields", | ||
| }); | ||
| return (await callApi(cred, "GET", `tweets/${encodeURIComponent(tweetId)}`, query, null)); | ||
| }; | ||
| const searchTweets = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const query = String(args[1] ?? ""); | ||
| const opts = (args[2] && typeof args[2] === "object" ? args[2] : {}); | ||
| if (!query) { | ||
| return errorReturn("Search query is required.", "twitter_error"); | ||
| } | ||
| const qs = { query }; | ||
| if (opts.maxResults !== undefined) { | ||
| qs.max_results = Math.max(10, Math.min(100, Number(opts.maxResults) | 0)); | ||
| } | ||
| const passthrough = { | ||
| startTime: "start_time", | ||
| endTime: "end_time", | ||
| sinceId: "since_id", | ||
| untilId: "until_id", | ||
| nextToken: "next_token", | ||
| }; | ||
| for (const [optKey, apiKey] of Object.entries(passthrough)) { | ||
| const v = opts[optKey]; | ||
| if (v !== undefined && String(v) !== "") | ||
| qs[apiKey] = String(v); | ||
| } | ||
| Object.assign(qs, buildFieldQuery(opts, { | ||
| tweetFields: "tweet.fields", | ||
| expansions: "expansions", | ||
| userFields: "user.fields", | ||
| mediaFields: "media.fields", | ||
| })); | ||
| return (await callApi(cred, "GET", "tweets/search/recent", qs, null)); | ||
| }; | ||
| const getUser = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const idOrU = String(args[1] ?? "").trim(); | ||
| const opts = (args[2] && typeof args[2] === "object" ? args[2] : {}); | ||
| if (!idOrU) { | ||
| return errorReturn("User ID or @handle is required.", "twitter_error"); | ||
| } | ||
| const query = buildFieldQuery(opts, { | ||
| userFields: "user.fields", | ||
| expansions: "expansions", | ||
| tweetFields: "tweet.fields", | ||
| }); | ||
| // Numeric → ID lookup; otherwise treat as username. | ||
| let path; | ||
| if (/^[0-9]+$/.test(idOrU)) { | ||
| path = `users/${encodeURIComponent(idOrU)}`; | ||
| } | ||
| else { | ||
| const handle = idOrU.replace(/^@/, ""); | ||
| path = `users/by/username/${encodeURIComponent(handle)}`; | ||
| } | ||
| return (await callApi(cred, "GET", path, query, null)); | ||
| }; | ||
| const getMyUser = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const opts = (args[1] && typeof args[1] === "object" ? args[1] : {}); | ||
| const query = buildFieldQuery(opts, { | ||
| userFields: "user.fields", | ||
| expansions: "expansions", | ||
| }); | ||
| return (await callApi(cred, "GET", "users/me", query, null)); | ||
| }; | ||
| const follow = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const targetUser = String(args[1] ?? ""); | ||
| if (!targetUser) { | ||
| return errorReturn("Target user ID is required.", "twitter_error"); | ||
| } | ||
| const source = await resolveMyUserId(cred); | ||
| if (typeof source !== "string") | ||
| return source; | ||
| return (await callApi(cred, "POST", `users/${source}/following`, null, { | ||
| target_user_id: targetUser, | ||
| })); | ||
| }; | ||
| const unfollow = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const targetUser = String(args[1] ?? ""); | ||
| if (!targetUser) { | ||
| return errorReturn("Target user ID is required.", "twitter_error"); | ||
| } | ||
| const source = await resolveMyUserId(cred); | ||
| if (typeof source !== "string") | ||
| return source; | ||
| return (await callApi(cred, "DELETE", `users/${source}/following/${encodeURIComponent(targetUser)}`, null, null)); | ||
| }; | ||
| // ── Exports: functions map ───────────────────────────────────────────── | ||
| export const TwitterFunctions = { | ||
| postTweet, | ||
| deleteTweet, | ||
| getTweet, | ||
| searchTweets, | ||
| getUser, | ||
| getMyUser, | ||
| follow, | ||
| unfollow, | ||
| }; | ||
| // ── Exports: credential types ────────────────────────────────────────── | ||
| export const TwitterCredentialTypes = [ | ||
| { | ||
| slug: CREDENTIAL_TYPE, | ||
| title: "X (Twitter) OAuth 2.0", | ||
| icon: "twitter", | ||
| fields: [ | ||
| { | ||
| name: "accessToken", | ||
| title: "Access Token", | ||
| type: "password", | ||
| required: true, | ||
| placeholder: "eyJhbGciOi… or AAAA…", | ||
| description: "OAuth 2.0 user-context access token from the X Developer portal. Must include `tweet.read`, `tweet.write`, `users.read`, and `follows.write` scopes for full coverage.", | ||
| }, | ||
| { | ||
| name: "clientId", | ||
| title: "Client ID", | ||
| type: "text", | ||
| required: false, | ||
| placeholder: "M1M5R3BMVy13QmpScXl3Y…", | ||
| description: "Optional. OAuth 2.0 Client ID from the X Developer portal. Only needed for external refresh-token rotation flows.", | ||
| }, | ||
| { | ||
| name: "clientSecret", | ||
| title: "Client Secret", | ||
| type: "password", | ||
| required: false, | ||
| placeholder: "…", | ||
| description: "Optional. OAuth 2.0 Client Secret from the X Developer portal. Only needed for external refresh-token rotation flows (confidential clients).", | ||
| }, | ||
| ], | ||
| }, | ||
| ]; | ||
| // ── Shared parameter descriptors ─────────────────────────────────────── | ||
| const credentialParam = { | ||
| name: "credential", | ||
| title: "Credential", | ||
| description: "Slug of a saved `twitter_oauth2` credential. The access token is decrypted at call time and never appears in logs.", | ||
| dataType: "string", | ||
| formInputType: "resource", | ||
| required: true, | ||
| allowExpression: true, | ||
| placeholder: "my_x_account", | ||
| resource: { | ||
| type: "credential", | ||
| listFn: "credential.list", | ||
| modes: ["list", "expression"], | ||
| searchable: true, | ||
| filter: { type: CREDENTIAL_TYPE }, | ||
| }, | ||
| }; | ||
| const tweetTextParam = { | ||
| name: "text", | ||
| title: "Text", | ||
| description: "Tweet text. Up to 280 characters (or 25,000 for X Premium accounts). URLs count as 23 chars regardless of length.", | ||
| dataType: "string", | ||
| formInputType: "textarea", | ||
| required: true, | ||
| allowExpression: true, | ||
| rows: 4, | ||
| placeholder: "Hello from RobinPath", | ||
| }; | ||
| const tweetIdParam = { | ||
| name: "tweetId", | ||
| title: "Tweet ID", | ||
| description: "Numeric tweet ID (a string in the API to avoid JS precision loss). E.g. `1772558986145034000`.", | ||
| dataType: "string", | ||
| formInputType: "text", | ||
| required: true, | ||
| allowExpression: true, | ||
| placeholder: "1772558986145034000", | ||
| validation: { pattern: "^[0-9]+$" }, | ||
| }; | ||
| const userIdParam = { | ||
| name: "userId", | ||
| title: "User ID", | ||
| description: "Numeric X user ID (string in the API). Use `getUser` with a username to resolve a handle to an ID first.", | ||
| dataType: "string", | ||
| formInputType: "text", | ||
| required: true, | ||
| allowExpression: true, | ||
| placeholder: "2244994945", | ||
| validation: { pattern: "^[0-9]+$" }, | ||
| }; | ||
| const tweetResponseSchema = { | ||
| type: "object", | ||
| properties: { | ||
| data: { | ||
| type: "object", | ||
| description: "X v2 envelope: { id, text, … }", | ||
| }, | ||
| includes: { | ||
| type: "object", | ||
| description: "Expanded entities (users, media, …) when requested via `expansions`.", | ||
| }, | ||
| meta: { | ||
| type: "object", | ||
| description: "Result metadata (e.g. `result_count`, `next_token`).", | ||
| }, | ||
| errors: { | ||
| type: "array", | ||
| description: "Per-item errors returned by X.", | ||
| }, | ||
| error: { | ||
| type: "string", | ||
| description: "Module error (transport, missing credential).", | ||
| }, | ||
| twitter_error: { | ||
| type: "string", | ||
| description: "X-side error type or title.", | ||
| }, | ||
| }, | ||
| }; | ||
| const commonErrors = { | ||
| credential_not_found: "No credential with that slug exists in the vault.", | ||
| token_missing: "The credential exists but does not have an `accessToken` field.", | ||
| transport: "Network failure calling api.twitter.com — see error message.", | ||
| twitter_error: "X returned an error envelope — see twitter_error / status fields.", | ||
| rate_limited: "X returned 429. Back off and retry after the `x-rate-limit-reset` window.", | ||
| unauthorized: "X returned 401. Token expired, revoked, or missing required scope.", | ||
| }; | ||
| // ── Exports: function metadata ───────────────────────────────────────── | ||
| export const TwitterFunctionMetadata = { | ||
| // ── Tweets ───────────────────────────────────────────────────────── | ||
| postTweet: { | ||
| title: "Post tweet", | ||
| summary: "Publish a new tweet on the authenticated user's timeline", | ||
| description: "Calls `POST /2/tweets`. Supports replies, quote tweets, media attachments, and polls via the optional `options` object.", | ||
| group: "tweet", | ||
| action: "write", | ||
| icon: "send", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: false, | ||
| since: "1.0.0", | ||
| tags: ["twitter", "x", "tweet", "post", "social"], | ||
| parameters: [ | ||
| credentialParam, | ||
| tweetTextParam, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Extra tweet fields. Recognized keys:\n replyToTweetId : string — tweet ID this is a reply to (sets `reply.in_reply_to_tweet_id`)\n quoteTweetId : string — tweet ID being quoted (sets `quote_tweet_id`)\n mediaIds : string[] — up to 4 media IDs uploaded via the v1.1 media endpoint\n poll : { options: string[], duration_minutes: int } — attach a poll\n forSuperFollowersOnly : bool — Super Follows-only tweet\n replySettings : 'mentionedUsers' | 'following' | 'everyone' — who can reply", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 6, | ||
| advanced: true, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "X v2 envelope: { data: { id, text, edit_history_tweet_ids } }.", | ||
| returnSchema: tweetResponseSchema, | ||
| errors: commonErrors, | ||
| examples: [ | ||
| { | ||
| title: "Plain tweet", | ||
| code: 'twitter.postTweet "my_x_account" "Just shipped a new RobinPath module"', | ||
| }, | ||
| { | ||
| title: "Reply to a tweet", | ||
| code: 'twitter.postTweet "my_x_account" "Thanks for sharing!" {\n replyToTweetId: "1772558986145034000"\n}', | ||
| }, | ||
| { | ||
| title: "Tweet with a poll", | ||
| code: 'twitter.postTweet "my_x_account" "Pick one" {\n poll: { options: ["Yes", "No", "Maybe"], duration_minutes: 1440 }\n}', | ||
| }, | ||
| ], | ||
| example: 'twitter.postTweet "my_x_account" "Hello from RobinPath"', | ||
| }, | ||
| deleteTweet: { | ||
| title: "Delete tweet", | ||
| summary: "Delete a tweet authored by the authenticated user", | ||
| description: "Calls `DELETE /2/tweets/{id}`. Only works for tweets owned by the access token's user.", | ||
| group: "tweet", | ||
| action: "delete", | ||
| icon: "trash-2", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["twitter", "x", "tweet", "delete"], | ||
| parameters: [credentialParam, tweetIdParam], | ||
| returnType: "object", | ||
| returnDescription: "{ data: { deleted: bool } }", | ||
| returnSchema: tweetResponseSchema, | ||
| errors: commonErrors, | ||
| example: 'twitter.deleteTweet "my_x_account" "1772558986145034000"', | ||
| }, | ||
| getTweet: { | ||
| title: "Get tweet", | ||
| summary: "Look up a single tweet by ID", | ||
| description: "Calls `GET /2/tweets/{id}`. Pass `tweetFields`, `expansions`, and `userFields` in `options` to enrich the response.", | ||
| group: "tweet", | ||
| action: "read", | ||
| icon: "message-circle", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["twitter", "x", "tweet", "lookup"], | ||
| parameters: [ | ||
| credentialParam, | ||
| tweetIdParam, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Recognized keys (all optional, comma-separated strings):\n tweetFields : 'created_at,public_metrics,author_id,lang,…'\n expansions : 'author_id,attachments.media_keys,referenced_tweets.id'\n userFields : 'username,name,profile_image_url,verified'\n mediaFields : 'url,preview_image_url,duration_ms'", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 4, | ||
| advanced: true, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnSchema: tweetResponseSchema, | ||
| errors: commonErrors, | ||
| example: 'twitter.getTweet "my_x_account" "1772558986145034000" {tweetFields: "created_at,public_metrics"}', | ||
| }, | ||
| // ── Search ───────────────────────────────────────────────────────── | ||
| searchTweets: { | ||
| title: "Search recent tweets", | ||
| summary: "Search tweets from the past 7 days using the recent-search endpoint", | ||
| description: "Calls `GET /2/tweets/search/recent`. Uses X's search query DSL — see https://developer.x.com/en/docs/x-api/tweets/search/integrate/build-a-query.", | ||
| group: "search", | ||
| action: "query", | ||
| icon: "search", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["twitter", "x", "search"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "query", | ||
| title: "Search query", | ||
| description: "X search query DSL. Supports operators like `from:`, `to:`, `lang:`, `-is:retweet`, `has:media`, etc. Up to 1024 chars.", | ||
| dataType: "string", | ||
| formInputType: "text", | ||
| required: true, | ||
| allowExpression: true, | ||
| placeholder: "#robinpath -is:retweet lang:en", | ||
| }, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Recognized keys:\n maxResults : int 10-100 (default 10)\n startTime : ISO 8601 — earliest tweet creation time\n endTime : ISO 8601 — latest tweet creation time\n sinceId : string — return tweets after this ID\n untilId : string — return tweets before this ID\n nextToken : string — pagination token from previous response\n tweetFields : comma-separated\n expansions : comma-separated\n userFields : comma-separated", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 5, | ||
| advanced: true, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "{ data: Tweet[], includes?, meta: { result_count, next_token? } }", | ||
| returnSchema: tweetResponseSchema, | ||
| errors: commonErrors, | ||
| examples: [ | ||
| { | ||
| title: "Recent mentions of a hashtag", | ||
| code: 'twitter.searchTweets "my_x_account" "#robinpath -is:retweet" {maxResults: 50}', | ||
| }, | ||
| ], | ||
| example: 'twitter.searchTweets "my_x_account" "from:robinpath"', | ||
| }, | ||
| // ── Users ────────────────────────────────────────────────────────── | ||
| getUser: { | ||
| title: "Get user", | ||
| summary: "Look up a user by ID or @handle", | ||
| description: "Calls `GET /2/users/{id}` or `GET /2/users/by/username/{handle}` depending on the input format.", | ||
| group: "users", | ||
| action: "read", | ||
| icon: "user", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["twitter", "x", "user", "lookup"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "idOrUsername", | ||
| title: "User ID or @handle", | ||
| description: "Either a numeric user ID (e.g. `2244994945`) or a handle with or without the leading `@` (e.g. `robinpath` or `@robinpath`).", | ||
| dataType: "string", | ||
| formInputType: "text", | ||
| required: true, | ||
| allowExpression: true, | ||
| placeholder: "@robinpath", | ||
| }, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Recognized keys:\n userFields : comma-separated, e.g. 'created_at,description,public_metrics,verified,profile_image_url'\n expansions : 'pinned_tweet_id'", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 3, | ||
| advanced: true, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "{ data: { id, name, username, … } }", | ||
| returnSchema: tweetResponseSchema, | ||
| errors: { | ||
| ...commonErrors, | ||
| user_not_found: "No user with that ID/username exists.", | ||
| }, | ||
| example: 'twitter.getUser "my_x_account" "@robinpath"', | ||
| }, | ||
| getMyUser: { | ||
| title: "Get authenticated user", | ||
| summary: "Return the user attached to the credential", | ||
| description: "Calls `GET /2/users/me`. Useful to confirm which X account a credential authenticates as.", | ||
| group: "users", | ||
| action: "read", | ||
| icon: "user-check", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["twitter", "x", "me"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Recognized keys:\n userFields : comma-separated, e.g. 'created_at,description,public_metrics,verified'", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 3, | ||
| advanced: true, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnSchema: tweetResponseSchema, | ||
| errors: commonErrors, | ||
| example: 'twitter.getMyUser "my_x_account"', | ||
| }, | ||
| follow: { | ||
| title: "Follow user", | ||
| summary: "Follow another X user as the authenticated user", | ||
| description: "Calls `POST /2/users/{source_user_id}/following`. Resolves the source user via `users/me` once per call. Requires the `follows.write` scope.", | ||
| group: "users", | ||
| action: "write", | ||
| icon: "user-plus", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["twitter", "x", "follow"], | ||
| parameters: [credentialParam, userIdParam], | ||
| returnType: "object", | ||
| returnDescription: "{ data: { following: bool, pending_follow: bool } }", | ||
| returnSchema: tweetResponseSchema, | ||
| errors: commonErrors, | ||
| example: 'twitter.follow "my_x_account" "2244994945"', | ||
| }, | ||
| unfollow: { | ||
| title: "Unfollow user", | ||
| summary: "Unfollow another X user as the authenticated user", | ||
| description: "Calls `DELETE /2/users/{source_user_id}/following/{target_user_id}`. Resolves the source via `users/me`. Requires the `follows.write` scope.", | ||
| group: "users", | ||
| action: "delete", | ||
| icon: "user-minus", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["twitter", "x", "unfollow"], | ||
| parameters: [credentialParam, userIdParam], | ||
| returnType: "object", | ||
| returnDescription: "{ data: { following: false } }", | ||
| returnSchema: tweetResponseSchema, | ||
| errors: commonErrors, | ||
| example: 'twitter.unfollow "my_x_account" "2244994945"', | ||
| }, | ||
| }; | ||
| // ── Exports: module metadata ─────────────────────────────────────────── | ||
| export const TwitterModuleMetadata = { | ||
| slug: "twitter", | ||
| title: "X (Twitter)", | ||
| summary: "Post and read tweets, search, look up users, and follow/unfollow via the X v2 API", | ||
| description: "Full X (Twitter) v2 API integration. All operations require a saved `twitter_oauth2` credential containing a valid OAuth 2.0 user-context access token.\n\nEvery method returns the parsed v2 response object so downstream nodes can read tweet IDs, author IDs, etc. directly. Errors are returned as `{error: '...', twitter_error?: '...'}` rather than thrown.\n\nNote: this module does not refresh tokens — handle the OAuth 2.0 PKCE refresh flow externally and update the credential when the token rotates.", | ||
| category: "communication", | ||
| icon: "icon.svg", | ||
| color: "#000000", | ||
| version: "0.2.0", | ||
| docsUrl: "https://docs.robinpath.com/modules/twitter", | ||
| status: "stable", | ||
| requires: [], | ||
| minNodeVersion: "18.0.0", | ||
| credentialsType: CREDENTIAL_TYPE, | ||
| operationGroups: { | ||
| tweet: { | ||
| title: "Tweets", | ||
| description: "Post, delete, and look up tweets.", | ||
| order: 1, | ||
| }, | ||
| search: { | ||
| title: "Search", | ||
| description: "Search recent tweets.", | ||
| order: 2, | ||
| }, | ||
| users: { | ||
| title: "Users", | ||
| description: "Look up user profiles and follow/unfollow.", | ||
| order: 3, | ||
| }, | ||
| }, | ||
| methods: Object.keys(TwitterFunctions), | ||
| }; | ||
| //# sourceMappingURL=twitter.js.map |
| {"version":3,"file":"twitter.js","sourceRoot":"","sources":["../src/twitter.ts"],"names":[],"mappings":"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"} |
+19
-8
| { | ||
| "name": "@robinpath/twitter", | ||
| "version": "0.1.1", | ||
| "version": "0.3.0", | ||
| "publishConfig": { | ||
@@ -23,12 +23,17 @@ "access": "public" | ||
| "peerDependencies": { | ||
| "@robinpath/core": ">=0.20.0" | ||
| "@robinpath/core": ">=0.40.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@robinpath/core": "^0.30.1", | ||
| "@robinpath/core": "^0.40.0", | ||
| "typescript": "^5.6.0" | ||
| }, | ||
| "description": "Twitter/X module for RobinPath.", | ||
| "description": "X (Twitter) v2 API integration — post and delete tweets, search, look up users, follow/unfollow. Uses the encrypted credential vault for OAuth 2.0 user-context access tokens.", | ||
| "keywords": [ | ||
| "twitter", | ||
| "social media" | ||
| "social media", | ||
| "x", | ||
| "tweet", | ||
| "social", | ||
| "oauth2", | ||
| "api-v2" | ||
| ], | ||
@@ -38,6 +43,12 @@ "license": "MIT", | ||
| "category": "social-media", | ||
| "type": "integration", | ||
| "auth": "bearer-token", | ||
| "functionCount": 31 | ||
| "type": "module", | ||
| "auth": "credential-vault", | ||
| "functionCount": 31, | ||
| "language": "nodejs", | ||
| "platforms": [ | ||
| "cloud", | ||
| "cli", | ||
| "desktop" | ||
| ] | ||
| } | ||
| } |
+1
-1
@@ -22,3 +22,3 @@ # @robinpath/twitter | ||
| ```bash | ||
| npm install @robinpath/twitter | ||
| robinpath add @robinpath/twitter | ||
| ``` | ||
@@ -25,0 +25,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
60964
1086.3%10
400%801
Infinity%2
100%