@elizaos/plugin-x 2.0.0-beta.1 β†’ 2.0.3-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,536 +1,118 @@
1
- # Eliza Twitter/X Client
1
+ # @elizaos/plugin-x
2
2
 
3
- This package provides Twitter/X integration for the Eliza AI agent using the official Twitter API v2.
3
+ X (formerly Twitter) connector for elizaOS agents, built on the official Twitter API v2 (`twitter-api-v2`).
4
4
 
5
- ## 🚨 TL;DR - Quick Setup
5
+ It adds an `XService` to the agent runtime that registers an X message connector (DMs) and post connector (public tweets), and runs optional autonomous loops for posting, mention/reply handling, timeline actions, and content discovery. The plugin registers **no actions, providers, or evaluators** β€” all agent-facing behavior flows through the connector handlers.
6
6
 
7
- **Just want your bot to post tweets? Here's the fastest path:**
7
+ The plugin auto-enables when a `connectors.x` (or legacy `connectors.twitter`) block is present in agent config and is not explicitly disabled.
8
8
 
9
- 1. **Get Twitter Developer account** β†’ https://developer.twitter.com
10
- 2. **Create an app** β†’ Enable "Read and write" permissions
11
- 3. Choose your auth mode:
12
- - **Option A (default, legacy): OAuth 1.0a env vars**
13
- - API Key & Secret (from "Consumer Keys")
14
- - Access Token & Secret (from "Authentication Tokens")
9
+ ## Authentication
15
10
 
16
- - **Option B (recommended): β€œlogin + approve” OAuth 2.0 (PKCE)**
17
- - Client ID (from "OAuth 2.0 Client ID")
18
- - Redirect URI (loopback recommended)
11
+ Two auth modes, selected by `TWITTER_AUTH_MODE`:
19
12
 
20
- 4. **Add to `.env`:**
13
+ - **`env` (default) β€” OAuth 1.0a static credentials.** Requires `TWITTER_API_KEY`, `TWITTER_API_SECRET_KEY`, `TWITTER_ACCESS_TOKEN`, `TWITTER_ACCESS_TOKEN_SECRET`. The Twitter app must have **Read and write** permissions; after enabling write, regenerate the access token + secret.
14
+ - **`oauth` β€” OAuth 2.0 PKCE (login + approve).** Requires `TWITTER_CLIENT_ID` and `TWITTER_REDIRECT_URI` (loopback recommended). No client secret is used or stored. On first run the plugin prints an authorization URL and captures the callback; tokens persist per `accountId` via the runtime cache and connector credential store (no local token file).
21
15
 
22
- ```bash
23
- # Option A: legacy OAuth 1.0a (default)
24
- TWITTER_AUTH_MODE=env
25
- TWITTER_API_KEY=xxx
26
- TWITTER_API_SECRET_KEY=xxx
27
- TWITTER_ACCESS_TOKEN=xxx
28
- TWITTER_ACCESS_TOKEN_SECRET=xxx
16
+ ### Getting credentials
29
17
 
30
- # Option B: OAuth 2.0 PKCE (interactive login + approve, no client secret)
31
- # TWITTER_AUTH_MODE=oauth
32
- # TWITTER_CLIENT_ID=xxx
33
- # TWITTER_REDIRECT_URI=http://127.0.0.1:8080/callback
18
+ 1. Create an app in the [Twitter Developer Portal](https://developer.twitter.com/en/portal/projects-and-apps) with API v2 access.
19
+ 2. Under **User authentication settings**, set **App permissions: Read and write**.
20
+ 3. For `env` mode, copy API Key/Secret (Consumer Keys) and Access Token/Secret (Authentication Tokens). For `oauth` mode, copy the OAuth 2.0 Client ID.
34
21
 
35
- TWITTER_ENABLE_POST=true
36
- TWITTER_POST_IMMEDIATELY=true
37
- ```
22
+ ## Configuration
38
23
 
39
- 5. **Run:** `bun start`
40
-
41
- Tip: if you use **OAuth 2.0 PKCE**, the plugin will print an authorization URL on first run and store tokens for you (no manual token pasting).
42
-
43
- ## Features
44
-
45
- - βœ… **Autonomous tweet posting** with configurable intervals
46
- - βœ… **Timeline monitoring** and interaction
47
- - βœ… **Mention and reply handling**
48
- - βœ… **Search functionality**
49
- - βœ… **Direct message support**
50
- - βœ… **Advanced timeline algorithms** with weighted scoring
51
- - βœ… **Comprehensive caching system**
52
- - βœ… **Built-in rate limiting and retry mechanisms**
53
- - βœ… **Discovery service** for autonomous content discovery and growth
54
-
55
- ## Prerequisites
56
-
57
- - Twitter Developer Account with API v2 access
58
- - Either Twitter OAuth 1.0a credentials (legacy env vars) or OAuth 2.0 Client ID (PKCE)
59
- - Node.js and bun installed
60
-
61
- ## πŸš€ Quick Start
62
-
63
- ### Step 1: Get Twitter Developer Access
64
-
65
- 1. Apply for a developer account at https://developer.twitter.com
66
- 2. Create a new app in the [Developer Portal](https://developer.twitter.com/en/portal/projects-and-apps)
67
- 3. Ensure your app has API v2 access
68
-
69
- ### Step 2: Configure App Permissions for Posting
70
-
71
- **⚠️ CRITICAL: Default apps can only READ. You must enable WRITE permissions to post tweets!**
72
-
73
- 1. In your app settings, go to **"User authentication settings"**
74
- 2. Configure exactly as shown:
75
-
76
- **App permissions**: `Read and write` βœ…
77
-
78
- **Type of App**: `Web App, Automated App or Bot`
79
-
80
- **Required URLs** (copy these exactly):
81
-
82
- ```
83
- Callback URI: http://localhost:3000/callback
84
- Website URL: https://github.com/elizaos/eliza
85
- ```
86
-
87
- **Optional fields**:
88
-
89
- ```
90
- Organization name: ElizaOS
91
- Organization URL: https://github.com/elizaos/eliza
92
- ```
93
-
94
- 3. Click **Save**
95
-
96
- ### Step 3: Get the RIGHT Credentials (OAuth 1.0a)
97
-
98
- You can use either legacy **OAuth 1.0a** env vars (default) or **OAuth 2.0 PKCE** (β€œlogin + approve”).
99
-
100
- In your app's **"Keys and tokens"** page, you'll see several sections. Here's what to use:
101
-
102
- ```
103
- βœ… USE THESE when TWITTER_AUTH_MODE=env (OAuth 1.0a):
104
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
105
- β”‚ Consumer Keys β”‚
106
- β”‚ β”œβ”€ API Key: xxx...xxx β†’ TWITTER_API_KEY β”‚
107
- β”‚ └─ API Key Secret: xxx...xxx β†’ TWITTER_API_SECRET_KEY β”‚
108
- β”‚ β”‚
109
- β”‚ Authentication Tokens β”‚
110
- β”‚ β”œβ”€ Access Token: xxx...xxx β†’ TWITTER_ACCESS_TOKEN β”‚
111
- β”‚ └─ Access Token Secret: xxx β†’ TWITTER_ACCESS_TOKEN_SECRET β”‚
112
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
113
-
114
- βœ… USE THESE when TWITTER_AUTH_MODE=oauth (OAuth 2.0 PKCE):
115
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
116
- β”‚ OAuth 2.0 Client ID and Client Secret β”‚
117
- β”‚ β”œβ”€ Client ID: xxx...xxx β†’ TWITTER_CLIENT_ID β”‚
118
- β”‚ └─ Client Secret: xxx...xxx ← NOT USED (do not put in env) β”‚
119
- β”‚ β”‚
120
- β”‚ Bearer Token ← NOT USED β”‚
121
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
122
- ```
123
-
124
- **After enabling write permissions, you MUST:**
125
-
126
- 1. Click **"Regenerate"** on Access Token & Secret
127
- 2. Copy the NEW tokens (old ones won't have write access)
128
- 3. Look for "Created with Read and Write permissions" βœ…
129
-
130
- ### Step 4: Configure Environment Variables
131
-
132
- Create or edit `.env` file in your project root:
24
+ Set via the agent's settings or environment. All values are read with `getSetting(runtime, key)`, which checks runtime settings before `process.env`. Intervals are in minutes unless noted.
133
25
 
134
26
  ```bash
135
- # Auth mode (default: env)
136
- # - env: legacy OAuth 1.0a keys/tokens
137
- # - oauth: β€œlogin + approve” OAuth 2.0 PKCE (no client secret in plugin)
27
+ # Auth (env mode shown)
138
28
  TWITTER_AUTH_MODE=env
139
- TWITTER_DEFAULT_ACCOUNT_ID=default
140
-
141
- # REQUIRED: OAuth 1.0a Credentials (from "Consumer Keys" section)
142
- TWITTER_API_KEY=your_api_key_here # From "API Key"
143
- TWITTER_API_SECRET_KEY=your_api_key_secret_here # From "API Key Secret"
144
-
145
- # REQUIRED: OAuth 1.0a Tokens (from "Authentication Tokens" section)
146
- TWITTER_ACCESS_TOKEN=your_access_token_here # Must have "Read and Write"
147
- TWITTER_ACCESS_TOKEN_SECRET=your_token_secret_here # Regenerate after permission change
29
+ TWITTER_API_KEY=...
30
+ TWITTER_API_SECRET_KEY=...
31
+ TWITTER_ACCESS_TOKEN=... # must have write permission
32
+ TWITTER_ACCESS_TOKEN_SECRET=...
148
33
 
149
- # ---- OR ----
150
- # OAuth 2.0 PKCE (β€œlogin + approve”) configuration:
34
+ # OAuth 2.0 PKCE alternative
151
35
  # TWITTER_AUTH_MODE=oauth
152
- # TWITTER_CLIENT_ID=your_oauth2_client_id_here
36
+ # TWITTER_CLIENT_ID=...
153
37
  # TWITTER_REDIRECT_URI=http://127.0.0.1:8080/callback
154
- # Optional:
155
38
  # TWITTER_SCOPES="tweet.read tweet.write users.read offline.access"
156
39
 
157
- # Basic Configuration
158
- TWITTER_DRY_RUN=false # Set to true to test without posting
159
- TWITTER_ENABLE_POST=true # Enable autonomous tweet posting
160
-
161
- # Optional: Posting Configuration
162
- TWITTER_POST_IMMEDIATELY=true # Post on startup (great for testing)
163
- TWITTER_POST_INTERVAL=120 # Minutes between posts (default: 120)
164
- # For more natural timing, use MIN/MAX intervals:
165
- TWITTER_POST_INTERVAL_MIN=90 # Minimum minutes between posts
166
- TWITTER_POST_INTERVAL_MAX=150 # Maximum minutes between posts
167
- ```
168
-
169
- When using **TWITTER_AUTH_MODE=oauth**, the plugin will:
170
-
171
- - Print an authorization URL on first run
172
- - Capture the callback via a local loopback server **or** ask you to paste the redirected URL
173
- - Persist tokens per `accountId` via Eliza runtime cache if available, otherwise a local token file under `~/.eliza/twitter/accounts/<accountId>/oauth2.tokens.json`
174
-
175
- For multi-account pilots, route connector targets with `accountId`. The plugin defaults to `TWITTER_DEFAULT_ACCOUNT_ID` when no target/content account is provided. You can also provide account-scoped credentials through `TWITTER_ACCOUNTS` JSON until the shared connector account store is available.
176
-
177
- ### Step 5: Run Your Bot
178
-
179
- ```typescript
180
- // Your character should include the twitter plugin
181
- const character = {
182
- // ... other config
183
- plugins: [
184
- // Required for content generation
185
- "@elizaos/plugin-x", // X (Twitter) functionality
186
- ],
187
- postExamples: [
188
- // Examples for tweet generation
189
- "Just discovered an amazing pattern in the data...",
190
- "The future of AI is collaborative intelligence",
191
- // ... more examples
192
- ],
193
- };
194
- ```
195
-
196
- Then start your bot:
197
-
198
- ```bash
199
- bun run start
200
- ```
201
-
202
- ## πŸ“‹ Complete Configuration Reference
203
-
204
- ```bash
205
- # Required Twitter API v2 Credentials (OAuth 1.0a)
206
- TWITTER_API_KEY= # Consumer API Key
207
- TWITTER_API_SECRET_KEY= # Consumer API Secret
208
- TWITTER_ACCESS_TOKEN= # Access Token (with write permissions)
209
- TWITTER_ACCESS_TOKEN_SECRET= # Access Token Secret
210
-
211
- # Core Configuration
212
- TWITTER_DRY_RUN=false # Set to true for testing without posting
213
- TWITTER_TARGET_USERS= # Comma-separated usernames to target (use "*" for all)
214
- TWITTER_RETRY_LIMIT=5 # Maximum retry attempts for failed operations
215
-
216
- # Feature Toggles
217
- TWITTER_ENABLE_POST=false # Enable autonomous tweet posting
218
- TWITTER_ENABLE_REPLIES=true # Enable mention and reply handling
219
- TWITTER_ENABLE_ACTIONS=false # Enable timeline actions (likes, retweets, quotes)
220
- TWITTER_ENABLE_DISCOVERY= # Enable discovery service (defaults to true if ACTIONS enabled)
221
-
222
- # Timing Configuration (all in minutes)
223
- # For natural behavior, set MIN/MAX intervals - the agent will randomly choose between them
224
- # If MIN/MAX not set, falls back to the fixed interval values
225
-
226
- # Post intervals
227
- TWITTER_POST_INTERVAL=120 # Fixed interval between posts (default: 120, used if MIN/MAX not set)
228
- TWITTER_POST_INTERVAL_MIN=90 # Minimum minutes between posts (default: 90)
229
- TWITTER_POST_INTERVAL_MAX=150 # Maximum minutes between posts (default: 150)
230
-
231
- # Engagement intervals
232
- TWITTER_ENGAGEMENT_INTERVAL=30 # Fixed interval for interactions (default: 30, used if MIN/MAX not set)
233
- TWITTER_ENGAGEMENT_INTERVAL_MIN=20 # Minimum minutes between engagements (default: 20)
234
- TWITTER_ENGAGEMENT_INTERVAL_MAX=40 # Maximum minutes between engagements (default: 40)
235
-
236
- # Discovery intervals
237
- TWITTER_DISCOVERY_INTERVAL_MIN=15 # Minimum minutes between discovery cycles (default: 15)
238
- TWITTER_DISCOVERY_INTERVAL_MAX=30 # Maximum minutes between discovery cycles (default: 30)
239
-
240
- # Engagement Limits
241
- TWITTER_MAX_ENGAGEMENTS_PER_RUN=5 # Maximum interactions per engagement cycle (default: 5)
242
- TWITTER_MAX_TWEET_LENGTH=280 # Maximum tweet length
243
-
244
- # Discovery Service Settings
245
- TWITTER_MIN_FOLLOWER_COUNT=100 # Minimum followers for accounts to follow
246
- TWITTER_MAX_FOLLOWS_PER_CYCLE=5 # Maximum accounts to follow per discovery cycle
247
- ```
248
-
249
- ## πŸ” Discovery Service
250
-
251
- The Twitter Discovery Service enables autonomous content discovery and engagement, helping your agent build a following and interact with relevant content on Twitter.
252
-
253
- ### Overview
254
-
255
- The discovery service autonomously:
256
-
257
- - Searches for content related to your agent's topics
258
- - Identifies high-quality accounts to follow
259
- - Engages with relevant tweets through likes, replies, and quotes
260
- - Builds up your agent's timeline by following interesting accounts
261
-
262
- ### Configuration
263
-
264
- ```bash
265
- # Enable discovery service (defaults to true if TWITTER_ENABLE_ACTIONS=true)
266
- TWITTER_ENABLE_DISCOVERY=true
267
-
268
- # Discovery interval in minutes (default: 30)
269
- TWITTER_DISCOVERY_INTERVAL=30
270
-
271
- # Minimum follower count for accounts to follow (default: 100)
40
+ # Feature toggles (all opt-in except replies)
41
+ TWITTER_ENABLE_POST=false # autonomous posting loop
42
+ TWITTER_ENABLE_REPLIES=true # mention/reply handling
43
+ TWITTER_ENABLE_ACTIONS=false # timeline likes/retweets/quotes
44
+ TWITTER_ENABLE_DISCOVERY= # defaults to true when ACTIONS=true, unless set false
45
+
46
+ # Behavior
47
+ TWITTER_DRY_RUN=false # simulate writes, post nothing
48
+ TWITTER_POST_IMMEDIATELY=false # post once on startup
49
+ TWITTER_TARGET_USERS= # comma-separated usernames; empty or "*" = all
50
+ TWITTER_NICKNAMES= # comma-separated nicknames the agent answers to (TWITTER_IDENTITY provider)
51
+ TWITTER_MAX_TWEET_LENGTH=280
52
+ TWITTER_RETRY_LIMIT=5
53
+
54
+ # Timing (minutes; MIN/MAX add randomness, else the fixed value is used)
55
+ TWITTER_POST_INTERVAL=120
56
+ TWITTER_POST_INTERVAL_MIN=90
57
+ TWITTER_POST_INTERVAL_MAX=180
58
+ TWITTER_ENGAGEMENT_INTERVAL=30
59
+ TWITTER_ENGAGEMENT_INTERVAL_MIN=20
60
+ TWITTER_ENGAGEMENT_INTERVAL_MAX=40
61
+ TWITTER_DISCOVERY_INTERVAL_MIN=15
62
+ TWITTER_DISCOVERY_INTERVAL_MAX=30
63
+
64
+ # Discovery limits
65
+ TWITTER_MAX_ENGAGEMENTS_PER_RUN=5
272
66
  TWITTER_MIN_FOLLOWER_COUNT=100
273
-
274
- # Maximum accounts to follow per cycle (default: 5)
275
67
  TWITTER_MAX_FOLLOWS_PER_CYCLE=5
276
-
277
- # Maximum engagements per cycle (default: 10)
278
- TWITTER_MAX_ENGAGEMENTS_PER_RUN=10
279
68
  ```
280
69
 
281
- ### How It Works
282
-
283
- 1. **Content Discovery**: Searches for tweets containing your agent's topics
284
- 2. **Account Scoring**: Scores accounts based on quality (follower count) and relevance
285
- 3. **Tweet Scoring**: Scores tweets for engagement based on relevance:
286
- - Like: score > 0.6
287
- - Reply: score > 0.8
288
- - Quote: score > 0.85
289
- 4. **Memory System**: Tracks engaged tweets and followed accounts to avoid duplicates
70
+ Multi-account routing: provide account-scoped credentials in `TWITTER_ACCOUNTS` (JSON) or register accounts via the runtime's ConnectorAccountManager. `TWITTER_DEFAULT_ACCOUNT_ID` selects the default account (effective default: `"default"`).
290
71
 
291
- ### Character Configuration
72
+ For the full validated schema and defaults see `src/environment.ts` (`twitterEnvSchema`, `validateTwitterConfig`). For an exhaustive variable table and architecture notes see [CLAUDE.md](./CLAUDE.md).
292
73
 
293
- The discovery service uses your agent's character configuration:
294
-
295
- ```json
296
- {
297
- "name": "YourAgent",
298
- "topics": [
299
- "artificial intelligence",
300
- "machine learning",
301
- "web3",
302
- "blockchain"
303
- ],
304
- "bio": "AI researcher interested in decentralized systems"
305
- }
306
- ```
74
+ ## Discovery service
307
75
 
308
- If topics aren't specified, the service extracts them from the bio.
76
+ When enabled, the discovery service searches for content matching the agent's `topics` (falling back to its `bio`), scores accounts and tweets, and engages. Relevance thresholds (in `src/discovery.ts`): like β‰₯ 0.5, reply β‰₯ 0.7, quote β‰₯ 0.85. Engaged tweets and followed accounts are tracked to avoid duplicates.
309
77
 
310
- ## 🎯 Common Use Cases
78
+ ## src layout
311
79
 
312
- ### Just Want to Post Tweets?
313
-
314
- ```bash
315
- # Minimal setup for posting only
316
- TWITTER_API_KEY=xxx
317
- TWITTER_API_SECRET_KEY=xxx
318
- TWITTER_ACCESS_TOKEN=xxx # Must have write permissions!
319
- TWITTER_ACCESS_TOKEN_SECRET=xxx
320
-
321
- TWITTER_ENABLE_POST=true
322
- TWITTER_POST_IMMEDIATELY=true # Great for testing
323
- TWITTER_ENABLE_REPLIES=false # Disable interactions
324
- TWITTER_ENABLE_ACTIONS=false # Disable timeline actions
325
80
  ```
326
-
327
- ### Want Full Interaction Bot?
328
-
329
- ```bash
330
- # Full interaction setup
331
- TWITTER_API_KEY=xxx
332
- TWITTER_API_SECRET_KEY=xxx
333
- TWITTER_ACCESS_TOKEN=xxx
334
- TWITTER_ACCESS_TOKEN_SECRET=xxx
335
-
336
- TWITTER_ENABLE_POST=true
337
- TWITTER_ENABLE_REPLIES=true
338
- TWITTER_ENABLE_ACTIONS=true # Enables likes, retweets, quotes
339
- TWITTER_ENABLE_DISCOVERY=true # Enables growth features
81
+ src/
82
+ index.ts XPlugin (services: XService, XWorkflowCredentialProvider)
83
+ base.ts ClientBase β€” twitter-api-v2 wrapper, profile/timeline/search
84
+ environment.ts twitterEnvSchema, validateTwitterConfig
85
+ types.ts TwitterClientState, ITwitterClient, Tweet, MediaData, event payloads
86
+ post.ts TwitterPostClient β€” posting loop
87
+ interactions.ts TwitterInteractionClient β€” mention/reply loop
88
+ timeline.ts TwitterTimelineClient β€” timeline action loop
89
+ discovery.ts TwitterDiscoveryClient β€” discovery loop
90
+ connector-account-provider.ts, connector-credential-refs.ts, workflow-credential-provider.ts
91
+ client/ Low-level API: client.ts, tweets.ts, profile.ts, search.ts,
92
+ relationships.ts, accounts.ts, auth.ts, errors.ts, auth-providers/
93
+ services/ XService (x.service.ts), Post/Message services + interfaces
94
+ utils/ settings.ts, memory.ts, time.ts, error-handler.ts
340
95
  ```
341
96
 
342
- ### Testing Without Posting?
97
+ ## Commands
343
98
 
344
99
  ```bash
345
- # Dry run mode
346
- TWITTER_DRY_RUN=true # Simulates all actions
347
- TWITTER_ENABLE_POST=true
348
- TWITTER_POST_IMMEDIATELY=true
100
+ bun run --cwd plugins/plugin-x build # tsup β†’ dist/
101
+ bun run --cwd plugins/plugin-x dev # tsup --watch
102
+ bun run --cwd plugins/plugin-x test # vitest run
103
+ bun run --cwd plugins/plugin-x test:coverage # vitest run --coverage
104
+ bun run --cwd plugins/plugin-x lint # biome check --write --unsafe
105
+ bun run --cwd plugins/plugin-x format # biome format --write
349
106
  ```
350
107
 
351
- ## 🚨 Troubleshooting
352
-
353
- ### 403 Errors When Engaging with Tweets
354
-
355
- If you see errors like "Failed to create tweet: Request failed with code 403", this usually means:
356
-
357
- 1. **Missing Write Permissions**: Make sure your Twitter app has "Read and write" permissions
358
- - Go to your app settings in the Twitter Developer Portal
359
- - Check that App permissions shows "Read and write" βœ…
360
- - If not, change it and regenerate your Access Token & Secret
361
-
362
- 2. **Protected Accounts**: The bot may be trying to engage with protected/private accounts
363
- - The plugin now automatically skips these with a warning
364
-
365
- 3. **Self-Engagement**: Trying to reply to or quote your own tweets
366
- - Twitter API doesn't allow this and returns 403
367
-
368
- 4. **Account Restrictions**: Your account may have restrictions
369
- - Check if your account is in good standing
370
- - Ensure you're not violating Twitter's automation rules
371
-
372
- The plugin will now:
373
-
374
- - Automatically detect and skip 403 errors with a warning
375
- - Continue processing other tweets
376
- - Mark failed tweets as "skip" to avoid retrying
377
-
378
- ### Other Common Issues
379
-
380
- ### "403 Forbidden" When Posting
381
-
382
- This is the #1 issue! Your app has read-only permissions.
383
-
384
- **Solution:**
385
-
386
- 1. Go to app settings β†’ "User authentication settings"
387
- 2. Change to "Read and write"
388
- 3. Save settings
389
- 4. **CRITICAL**: Regenerate your Access Token & Secret
390
- 5. Update `.env` with NEW tokens
391
- 6. Restart your bot
392
-
393
- **How to verify:** In "Keys and tokens", your Access Token should show "Created with Read and Write permissions"
394
-
395
- ### "Could not authenticate you"
396
-
397
- This usually means your credentials don’t match your selected auth mode.
398
-
399
- **Solution:**
400
-
401
- - If `TWITTER_AUTH_MODE=env`:
402
- - Use credentials from "Consumer Keys" section (API Key/Secret)
403
- - Use credentials from "Authentication Tokens" section (Access Token/Secret)
404
- - Do not use OAuth 2.0 Client ID/Client Secret/Bearer Token for this mode
405
- - If `TWITTER_AUTH_MODE=oauth`:
406
- - Use OAuth 2.0 **Client ID** (`TWITTER_CLIENT_ID`)
407
- - Set a loopback redirect URI (`TWITTER_REDIRECT_URI`, e.g. `http://127.0.0.1:8080/callback`)
408
- - Do not set/ship a client secret (PKCE flow)
409
-
410
- ### Bot Not Posting Automatically
411
-
412
- **Checklist:**
413
-
414
- - βœ… Is `TWITTER_ENABLE_POST=true`?
415
- - βœ… Does your character have `postExamples`?
416
- - βœ… Check logs for "Twitter posting is ENABLED"
417
- - βœ… Try `TWITTER_POST_IMMEDIATELY=true` for testing
418
-
419
- ### Timeline Not Loading
420
-
421
- **Common causes:**
422
-
423
- - Rate limiting (check Twitter Developer Portal)
424
- - Invalid credentials
425
- - Account restrictions
426
-
427
- ### "Invalid or expired token"
428
-
429
- Your tokens may have been revoked or regenerated.
430
-
431
- **Solution:**
432
-
433
- 1. Go to Twitter Developer Portal
434
- 2. Regenerate all tokens
435
- 3. Update `.env`
436
- 4. Restart bot
437
-
438
- ## πŸ“š Advanced Features
439
-
440
- ### Timeline Processing
441
-
442
- The plugin supports two main approaches:
443
-
444
- - **Timeline Actions**: Process home timeline for likes, retweets, and quotes
445
- - **Targeted Interactions**: Reply to mentions and specific users
446
-
447
- ### Target User Configuration
448
-
449
- ```bash
450
- # Interact with everyone (default)
451
- TWITTER_TARGET_USERS=
452
-
453
- # Interact with specific users only
454
- TWITTER_TARGET_USERS=user1,user2,user3
455
-
456
- # Interact with everyone (explicit)
457
- TWITTER_TARGET_USERS=*
458
- ```
459
-
460
- ### Natural Posting Intervals
461
-
462
- The plugin adds variance to all intervals for more human-like behavior:
463
-
464
- - Post intervals vary by Β±20% by default
465
- - Discovery intervals vary by Β±10 minutes
466
- - Engagement intervals vary based on activity
467
-
468
- ### Request Queue & Rate Limiting
469
-
470
- The plugin includes sophisticated rate limiting:
471
-
472
- - Automatic retry with exponential backoff
473
- - Request queue to prevent API abuse
474
- - Configurable retry limits
475
- - Built-in caching to reduce API calls
476
-
477
- ## πŸ§ͺ Development & Testing
478
-
479
- ```bash
480
- # Run tests
481
- bun test
482
-
483
- # Run with debug logging
484
- DEBUG=eliza:* bun start
485
-
486
- # Test without posting
487
- TWITTER_DRY_RUN=true bun start
488
- ```
489
-
490
- ### Testing Checklist
491
-
492
- 1. **Test Auth**: Check logs for successful Twitter login
493
- 2. **Test Posting**: Set `TWITTER_POST_IMMEDIATELY=true`
494
- 3. **Test Dry Run**: Use `TWITTER_DRY_RUN=true` first
495
- 4. **Monitor Logs**: Look for "Twitter posting is ENABLED"
496
-
497
- ## πŸ”’ Security Best Practices
498
-
499
- - Store credentials in `.env` file (never commit!)
500
- - Use `.env.local` for local development
501
- - Regularly rotate API keys
502
- - Monitor API usage in Developer Portal
503
- - Enable only necessary permissions
504
- - Review [Twitter's automation rules](https://help.twitter.com/en/rules-and-policies/twitter-automation)
505
-
506
- ## πŸ“Š API Usage & Limits
507
-
508
- This plugin uses Twitter API v2 endpoints efficiently:
509
-
510
- - **Home Timeline**: Cached and refreshed periodically
511
- - **Tweet Creation**: Rate limited automatically
512
- - **User Lookups**: Cached to reduce calls
513
- - **Search**: Configurable intervals
514
-
515
- Monitor your usage at: https://developer.twitter.com/en/portal/dashboard
516
-
517
- ## πŸ“– Additional Resources
518
-
519
- - [Twitter API v2 Documentation](https://developer.twitter.com/en/docs/twitter-api)
520
- - [Twitter OAuth 1.0a Guide](https://developer.twitter.com/en/docs/authentication/oauth-1-0a)
521
- - [Twitter OAuth 2.0 (Authorization Code with PKCE)](https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code)
522
- - [Rate Limits Reference](https://developer.twitter.com/en/docs/twitter-api/rate-limits)
523
- - [ElizaOS Documentation](https://github.com/elizaos/eliza)
524
-
525
- ## 🀝 Contributing
526
-
527
- Contributions are welcome! Please:
108
+ ## Troubleshooting
528
109
 
529
- 1. Check existing issues first
530
- 2. Follow the code style
531
- 3. Add tests for new features
532
- 4. Update documentation
110
+ - **403 on post or engagement** β€” app is read-only, or you're engaging a protected/own tweet. Set **Read and write** permissions, regenerate the access token + secret, and restart.
111
+ - **"Could not authenticate you"** β€” credentials don't match the selected `TWITTER_AUTH_MODE`. In `env` mode use Consumer Keys + Authentication Tokens; in `oauth` mode use the OAuth 2.0 Client ID and a loopback redirect URI (no client secret).
112
+ - **Bot not posting** β€” confirm `TWITTER_ENABLE_POST=true`, the character has `bio`/`topics`/`messageExamples` for generation, and try `TWITTER_POST_IMMEDIATELY=true`.
533
113
 
534
- ## πŸ“ License
114
+ ## Resources
535
115
 
536
- This plugin is part of the ElizaOS project. See the main repository for license information.
116
+ - [Twitter API v2 docs](https://developer.twitter.com/en/docs/twitter-api)
117
+ - [OAuth 2.0 Authorization Code with PKCE](https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code)
118
+ - [Twitter automation rules](https://help.twitter.com/en/rules-and-policies/twitter-automation)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elizaos/plugin-x",
3
- "version": "2.0.0-beta.1",
3
+ "version": "2.0.3-beta.6",
4
4
  "description": "elizaOS X (formerly Twitter) connector: posting, mentions, replies, DMs, and timeline interactions.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -10,11 +10,28 @@
10
10
  "./package.json": "./package.json",
11
11
  ".": {
12
12
  "types": "./dist/index.d.ts",
13
+ "eliza-source": {
14
+ "types": "./src/index.ts",
15
+ "import": "./src/index.ts",
16
+ "default": "./src/index.ts"
17
+ },
13
18
  "import": "./dist/index.js",
14
19
  "default": "./dist/index.js"
20
+ },
21
+ "./*.css": "./dist/*.css",
22
+ "./*": {
23
+ "types": "./dist/*.d.ts",
24
+ "eliza-source": {
25
+ "types": "./src/*.ts",
26
+ "import": "./src/*.ts",
27
+ "default": "./src/*.ts"
28
+ },
29
+ "import": "./dist/*.js",
30
+ "default": "./dist/*.js"
15
31
  }
16
32
  },
17
33
  "files": [
34
+ "registry-entry.json",
18
35
  "dist",
19
36
  "auto-enable.ts"
20
37
  ],
@@ -49,7 +66,7 @@
49
66
  "lint": "bunx @biomejs/biome check --write --unsafe .",
50
67
  "lint:check": "bunx @biomejs/biome check .",
51
68
  "typecheck": "echo \"Typecheck skipped for release\"",
52
- "clean": "rm -rf dist .turbo .turbo-tsconfig.json tsconfig.tsbuildinfo",
69
+ "clean": "node ../../packages/scripts/rm-path-recursive.mjs dist .turbo .turbo-tsconfig.json tsconfig.tsbuildinfo",
53
70
  "format": "bunx @biomejs/biome format --write .",
54
71
  "format:check": "bunx @biomejs/biome format ."
55
72
  },
@@ -389,6 +406,7 @@
389
406
  }
390
407
  },
391
408
  "peerDependencies": {
392
- "@elizaos/core": "2.0.0-beta.1"
393
- }
409
+ "@elizaos/core": "2.0.3-beta.6"
410
+ },
411
+ "gitHead": "990dc996172b3e0fb525a75052a5ac28a4cd4de5"
394
412
  }