twitter-skillv1.0.0latest

by ryan321

Post tweets, reply, search, read timelines, like, retweet, and look up users on Twitter/X. Uses the official API v2 via the twitter-api-v2 SDK. Free tier supports posting and deleting; Basic tier ($200/mo) adds search, timelines, and engagement.

Install
https://clawskills.io/api/skills/twitter-skill/releases/1.0.0/SKILL.md

Give this URL to your OpenClaw agent to install.

Agent prompt

Fetch the skill from https://clawskills.io/api/skills/twitter-skill/releases/1.0.0/SKILL.md and follow its Quick Start section to install, configure, and verify the twitter-skill skill (v1.0.0).

Or copy this full prompt to give your agent.

SKILL.md

---
name: twitter-skill
version: 1.0.0
url: https://clawskills.io/api/skills/twitter-skill/releases/1.0.0/SKILL.md
artifact_sha256: 2dc550634a4dad60056ee9daabdaab4dcda0313163cbad0d412c6a3b60d7e154
signature: 7FTc0IJR3g3EraZEDxEXS+l6gaAsg7UvDpNL0Chn3F8ypVJn8U3DSUVR3FN8pzlXt7y2HimDhB8v7iuI9yM+Dg==
key_id: 625b196966442b38cf1c7188ba15fa81
verify: https://clawskills.io/docs/verification
---
# Twitter (X) Skill

Post tweets, search tweets, read timelines, and manage engagement on Twitter/X using the official API v2 via the `twitter-api-v2` SDK.

---

## Overview
- **What it does:**
  Lets an AI agent read and write to Twitter/X — post tweets, reply, search, read timelines, like, retweet, and look up users via the `twitter-api-v2` Node.js SDK.

- **When to use it:**
  When the user wants to interact with Twitter/X: posting updates, monitoring mentions, searching for topics, or engaging with tweets.

- **Requirements:**
  - OS: macOS / Linux / Windows
  - Runtime: Node.js 18+
  - Accounts: Twitter/X developer account with API v2 access
  - API tier: **Free** ($0) supports posting, deleting, and authenticated user lookup only. **Basic** ($200/mo) required for search, timelines, likes, retweets, and user lookups.

---

## Quick start

### Install

```bash
npm install twitter-api-v2@1.29.0
```

### Configure

Add your credentials in the **OpenClaw runtime environment** (Control UI env editor if available, process env, or `.env`):

```bash
# Required — set in OpenClaw runtime environment:
#   TWITTER_API_KEY       — your app's API key (Consumer Key)
#   TWITTER_API_SECRET    — your app's API secret (Consumer Secret)
#   TWITTER_ACCESS_TOKEN  — user-level access token
#   TWITTER_ACCESS_SECRET — user-level access token secret
#
# Get your keys from: https://developer.x.com/en/portal/dashboard
```

### Verify

```bash
node -e "const{TwitterApi}=require('twitter-api-v2');new TwitterApi({appKey:process.env.TWITTER_API_KEY,appSecret:process.env.TWITTER_API_SECRET,accessToken:process.env.TWITTER_ACCESS_TOKEN,accessSecret:process.env.TWITTER_ACCESS_SECRET}).v2.me().then(u=>console.log(JSON.stringify(u.data,null,2)))"
```

**Expected result:**
Prints JSON with your authenticated user's `id`, `name`, and `username`.

---

## Core tasks

### Post a tweet

```text
Post a tweet saying "Hello from my agent!"
```

### Reply to a tweet

```text
Reply to tweet ID 1234567890 with the text "Great point, thanks for sharing!"
```

### Search recent tweets

```text
Search Twitter for recent tweets about "artificial intelligence" and show the top 10 results with timestamps and engagement metrics.
```

*Requires Basic tier ($200/mo) or higher.*

### Get home timeline

```text
Show the 10 most recent tweets from my home timeline, including timestamps and engagement metrics.
```

*Requires Basic tier ($200/mo) or higher.*

### Like a tweet

```text
Like the tweet with ID 1234567890.
```

*Requires Basic tier ($200/mo) or higher.*

### Retweet

```text
Retweet the tweet with ID 1234567890.
```

*Requires Basic tier ($200/mo) or higher.*

### Look up a user by username

```text
Look up the Twitter user @elonmusk and show their bio, follower count, and account creation date.
```

*Requires Basic tier ($200/mo) or higher.*

### Get a user's recent tweets

```text
Show the 10 most recent tweets from @elonmusk, including timestamps and engagement metrics.
```

*Requires Basic tier ($200/mo) or higher.*

### Delete a tweet

```text
Delete the tweet with ID 1234567890.
```

### Post a thread

```text
Post a Twitter thread with these parts: 1) "First tweet of the thread" 2) "Second tweet continues the thought" 3) "Final tweet wraps it up"
```

---

## SDK usage reference

This skill uses the `twitter-api-v2` npm package (no MCP server). The agent must write Node.js code to interact with the Twitter API. Below is the complete reference for constructing the client and calling each endpoint.

### Client initialization

```javascript
const { TwitterApi } = require('twitter-api-v2');

const client = new TwitterApi({
  appKey: process.env.TWITTER_API_KEY,
  appSecret: process.env.TWITTER_API_SECRET,
  accessToken: process.env.TWITTER_ACCESS_TOKEN,
  accessSecret: process.env.TWITTER_ACCESS_SECRET,
});
```

### Get authenticated user (Free tier)

```javascript
const { data: me } = await client.v2.me();
// me => { id: '123', name: 'Display Name', username: 'handle' }
```

Note: many methods below require the authenticated user's ID. Call `.me()` first and store `me.id`.

### Post a tweet (Free tier)

```javascript
const { data } = await client.v2.tweet('Hello world!');
// data => { id: '1234567890', text: 'Hello world!' }
```

With options:

```javascript
const { data } = await client.v2.tweet({
  text: 'Tweet with options',
  poll: { options: ['Yes', 'No'], duration_minutes: 60 },
});
```

### Reply to a tweet (Free tier)

```javascript
const { data } = await client.v2.reply('My reply text', '1234567890');
// '1234567890' is the tweet ID being replied to
```

### Delete a tweet (Free tier)

```javascript
const { data } = await client.v2.deleteTweet('1234567890');
// data => { deleted: true }
```

### Post a thread (Free tier)

```javascript
const results = await client.v2.tweetThread([
  'First tweet in the thread',
  'Second tweet continues the thought',
  'Final tweet wraps it up',
]);
// results => array of TweetV2PostTweetResult
```

### Search recent tweets (Basic tier required)

```javascript
const results = await client.v2.search('artificial intelligence', {
  max_results: 10,
  'tweet.fields': ['created_at', 'public_metrics', 'author_id'],
});

for await (const tweet of results) {
  // tweet => { id, text, created_at, public_metrics: { like_count, retweet_count, reply_count, impression_count }, author_id }
}
```

### Get home timeline (Basic tier required)

```javascript
const timeline = await client.v2.homeTimeline({
  max_results: 10,
  'tweet.fields': ['created_at', 'public_metrics', 'author_id'],
});

for await (const tweet of timeline) {
  // tweet => { id, text, created_at, public_metrics, author_id }
}
```

### Get a user's tweets (Basic tier required)

```javascript
const tweets = await client.v2.userTimeline('USER_ID', {
  max_results: 10,
  'tweet.fields': ['created_at', 'public_metrics'],
});

for await (const tweet of tweets) {
  // tweet => { id, text, created_at, public_metrics }
}
```

### Like a tweet (Basic tier required)

```javascript
const { data: me } = await client.v2.me();
await client.v2.like(me.id, '1234567890');
```

### Unlike a tweet (Basic tier required)

```javascript
const { data: me } = await client.v2.me();
await client.v2.unlike(me.id, '1234567890');
```

### Retweet (Basic tier required)

```javascript
const { data: me } = await client.v2.me();
await client.v2.retweet(me.id, '1234567890');
```

### Unretweet (Basic tier required)

```javascript
const { data: me } = await client.v2.me();
await client.v2.unretweet(me.id, '1234567890');
```

### Look up a user by username (Basic tier required)

```javascript
const { data: user } = await client.v2.userByUsername('elonmusk', {
  'user.fields': ['description', 'public_metrics', 'created_at', 'profile_image_url'],
});
// user => { id, name, username, description, public_metrics: { followers_count, following_count, tweet_count }, created_at }
```

### Look up multiple users (Basic tier required)

```javascript
const { data: users } = await client.v2.usersByUsernames(['user1', 'user2'], {
  'user.fields': ['description', 'public_metrics'],
});
```

### Get a single tweet by ID (Basic tier required)

```javascript
const { data: tweet } = await client.v2.singleTweet('1234567890', {
  'tweet.fields': ['created_at', 'public_metrics', 'author_id'],
});
```

### Get user's mention timeline (Basic tier required)

```javascript
const { data: me } = await client.v2.me();
const mentions = await client.v2.userMentionTimeline(me.id, {
  max_results: 10,
  'tweet.fields': ['created_at', 'public_metrics'],
});
```

### API tier summary

| Operation | Free ($0) | Basic ($200/mo) |
|---|---|---|
| Post tweet | 1,500/mo app-level | 10,000/24h |
| Delete tweet | Yes | Yes |
| Get authenticated user (`me`) | Yes | Yes |
| Reply to tweet | Yes | Yes |
| Post thread | Yes | Yes |
| Search tweets | No | 450 req/15min |
| Home timeline | No | Yes |
| User timeline | No | 900 req/15min |
| Like / unlike | No | 50 req/15min |
| Retweet / unretweet | No | 50 req/15min |
| User lookup | No | 300 req/15min |
| Single tweet lookup | No | Yes |
| Mention timeline | No | Yes |

### Error handling pattern

```javascript
try {
  const { data } = await client.v2.tweet('Hello!');
  console.log('Posted:', data.id);
} catch (err) {
  if (err.code === 429) {
    // Rate limited — inform the user and wait
    const resetTime = err.rateLimit?.reset;
    console.error(`Rate limited. Resets at ${new Date(resetTime * 1000).toISOString()}`);
  } else if (err.code === 401) {
    console.error('Authentication failed — check credentials');
  } else if (err.code === 403) {
    console.error('Forbidden — check API tier and permissions');
  } else {
    console.error('Twitter API error:', err.message);
  }
}
```

---

## Environment variable contract

| Variable | Purpose | Required | Where to set |
|---|---|---|---|
| `TWITTER_API_KEY` | API key / Consumer Key | Yes | OpenClaw runtime environment |
| `TWITTER_API_SECRET` | API secret / Consumer Secret | Yes | OpenClaw runtime environment |
| `TWITTER_ACCESS_TOKEN` | User-level OAuth 1.0a access token | Yes | OpenClaw runtime environment |
| `TWITTER_ACCESS_SECRET` | User-level OAuth 1.0a access token secret | Yes | OpenClaw runtime environment |

Credentials set in the OpenClaw runtime environment are automatically available to scripts executed by the agent.

---

## Configuration

* **Secrets / credentials required:**

  * `TWITTER_API_KEY` — your app's API key (Consumer Key) from the X Developer Portal
  * `TWITTER_API_SECRET` — your app's API secret (Consumer Secret)
  * `TWITTER_ACCESS_TOKEN` — user-level access token (OAuth 1.0a)
  * `TWITTER_ACCESS_SECRET` — user-level access token secret (OAuth 1.0a)

* **How to obtain credentials:**

  1. Go to https://developer.x.com/en/portal/dashboard
  2. Create a project and app
  3. Under "Keys and tokens", generate API Key & Secret
  4. Under "Authentication tokens", generate Access Token & Secret (with read+write permissions)
  5. Free tier allows posting and deleting only. Upgrade to Basic ($200/mo) for search, timelines, likes, retweets, and user lookups.

* **Config files used:**

  * No config files — this is an SDK-only skill. Credentials are read from environment variables at runtime.

* **How to reset / re-auth:**

  * Regenerate tokens in the X Developer Portal under your app's "Keys and tokens" tab
  * Update your environment variables with the new values
  * Re-run the Verify command to confirm

---

## Security & Guardrails

### Secrets handling

* Never paste API keys, tokens, or secrets into chat.
* Always use environment variables (`TWITTER_API_KEY`, etc.).
* If authentication fails with a 401 or 403, recommend the user regenerate and rotate their credentials immediately — the old ones may be compromised.
* Never pass credentials as command-line arguments (visible in `ps` output).

### Confirmations (before risky actions)

* Always confirm with the user before:
  * Posting a tweet or reply (content goes public immediately)
  * Retweeting (visible to all followers)
  * Deleting a tweet (irreversible)
  * Liking tweets in bulk (may trigger rate limits or look like bot behavior)
* Show the user the exact text that will be posted before sending.

### Rate limits

* Twitter API v2 enforces strict rate limits per endpoint and tier.
* Free tier: ~1,500 posts per month at app level.
* Basic tier: standard 15-minute rate windows (see API tier summary above).
* Do not retry aggressively on 429 responses — check `err.rateLimit.reset` for the reset timestamp and inform the user.
* Prefer batched lookups (`client.v2.tweets([id1, id2])`) over individual calls when possible.

### Data minimization

* Return summaries by default — don't dump full API responses unless the user asks.
* Avoid logging or echoing tokens in output.
* When searching, use `max_results: 10` unless the user requests more.
* Strip unnecessary metadata from responses before presenting to the user.

### Permissions / scopes

* **Required OAuth 1.0a permissions:** Read and Write.
* **Least privilege:** If the user only needs to read (search, timelines, lookups), a read-only app is sufficient. Only enable write access when posting, liking, or retweeting is needed.

### Network access

* **Domains used:**
  * `api.twitter.com` — all Twitter API v2 requests
  * `api.x.com` — alias for the same API

### Local storage

* **Writes to:** Nothing — this skill does not write to the filesystem beyond the installed npm package in `node_modules/`.
* **Does not access:** SSH keys, browser profiles, keychains, password stores, or any local files.

### Revoke / rotate

* Revoke tokens: X Developer Portal > Your App > Keys and tokens > Regenerate (old tokens are immediately invalidated).
* Rotate tokens: Generate new Access Token & Secret, update environment variables, re-run the Verify command.

---

## Troubleshooting

* **Error:** `401 Unauthorized`
  * Fix: Check that all four environment variables are set and correct. Regenerate tokens in the X Developer Portal if needed.

* **Error:** `403 Forbidden - client-not-enrolled`
  * Fix: Your developer account may not have API v2 access enabled, or the endpoint requires a higher tier. Free tier only supports posting, deleting, and user self-lookup. Upgrade to Basic ($200/mo) for search, timelines, likes, retweets, and user lookups.

* **Error:** `403 Forbidden` on like/retweet/search
  * Fix: These endpoints are not available on the Free tier. The user needs to upgrade to Basic tier ($200/mo) in the X Developer Portal.

* **Error:** `429 Too Many Requests`
  * Fix: Rate limit exceeded. Check the `rateLimit.reset` timestamp in the error response for when the window resets (typically 15 minutes). Do not retry aggressively.

* **Error:** `ENOTFOUND api.twitter.com`
  * Fix: Check your network connection. If behind a proxy, configure `https_proxy` environment variable.

* **Problem:** "Tweet text too long"
  * Fix: Tweets are limited to 280 characters. Use `client.v2.tweetThread()` to split into a thread.

---

## Release notes

* v1.0.0:
  * Initial release
  * Post, reply, delete, thread, search, timeline, like, retweet, user lookup
  * Uses `twitter-api-v2@1.29.0`
  * Documents Free vs Basic tier limitations

---

## Links

* Package: https://www.npmjs.com/package/twitter-api-v2
* Package repo: https://github.com/PLhery/node-twitter-api-v2
* SDK documentation: https://github.com/PLhery/node-twitter-api-v2/blob/master/doc/v2.md
* API docs: https://developer.x.com/en/docs/twitter-api
* Developer portal: https://developer.x.com/en/portal/dashboard
* Rate limits reference: https://developer.x.com/en/docs/twitter-api/rate-limits
* API tier comparison: https://developer.x.com/en/docs/twitter-api/getting-started/about-twitter-api

---

## Publisher

* **Publisher:** @Agentopolis

Security Guardrails

secrets/credential handlingconfirmation before risky actionsrate limitingdata minimizationpermissions/scopesnetwork access disclosurelocal storage disclosuretoken revocation/rotation

Releases

1.0.0listedcurrent
2/15/2026

External Interfaces

Secrets & Environment Variables
TWITTER_API_KEYTWITTER_API_SECRETTWITTER_ACCESS_TOKENTWITTER_ACCESS_SECRET
Packages
npm install twitter-api-v2@1.29.0
Languages
javascript
Network Domains
localhostdeveloper.x.comwww.npmjs.comgithub.com
File System Access
~/.openclaw/openclaw.json
Files Included (1)
SKILL.md15.5 KB

Comments

Sign in to leave a comment.

No comments yet.