@elizaos/plugin-twitter 1.2.15 → 1.2.17
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 +27 -1
- package/dist/index.js +54 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -304,7 +304,33 @@ TWITTER_ENABLE_POST=true
|
|
|
304
304
|
TWITTER_POST_IMMEDIATELY=true
|
|
305
305
|
```
|
|
306
306
|
|
|
307
|
-
##
|
|
307
|
+
## 🚨 Troubleshooting
|
|
308
|
+
|
|
309
|
+
### 403 Errors When Engaging with Tweets
|
|
310
|
+
|
|
311
|
+
If you see errors like "Failed to create tweet: Request failed with code 403", this usually means:
|
|
312
|
+
|
|
313
|
+
1. **Missing Write Permissions**: Make sure your Twitter app has "Read and write" permissions
|
|
314
|
+
- Go to your app settings in the Twitter Developer Portal
|
|
315
|
+
- Check that App permissions shows "Read and write" ✅
|
|
316
|
+
- If not, change it and regenerate your Access Token & Secret
|
|
317
|
+
|
|
318
|
+
2. **Protected Accounts**: The bot may be trying to engage with protected/private accounts
|
|
319
|
+
- The plugin now automatically skips these with a warning
|
|
320
|
+
|
|
321
|
+
3. **Self-Engagement**: Trying to reply to or quote your own tweets
|
|
322
|
+
- Twitter API doesn't allow this and returns 403
|
|
323
|
+
|
|
324
|
+
4. **Account Restrictions**: Your account may have restrictions
|
|
325
|
+
- Check if your account is in good standing
|
|
326
|
+
- Ensure you're not violating Twitter's automation rules
|
|
327
|
+
|
|
328
|
+
The plugin will now:
|
|
329
|
+
- Automatically detect and skip 403 errors with a warning
|
|
330
|
+
- Continue processing other tweets
|
|
331
|
+
- Mark failed tweets as "skip" to avoid retrying
|
|
332
|
+
|
|
333
|
+
### Other Common Issues
|
|
308
334
|
|
|
309
335
|
### "403 Forbidden" When Posting
|
|
310
336
|
|
package/dist/index.js
CHANGED
|
@@ -6282,6 +6282,25 @@ function getRandomInterval(runtime, type) {
|
|
|
6282
6282
|
return fallbackInterval;
|
|
6283
6283
|
}
|
|
6284
6284
|
|
|
6285
|
+
// src/utils/time.ts
|
|
6286
|
+
function getEpochMs(ts) {
|
|
6287
|
+
if (!ts) return Date.now();
|
|
6288
|
+
const digits = Math.floor(Math.log10(ts)) + 1;
|
|
6289
|
+
if (digits <= 12) {
|
|
6290
|
+
return ts * 1e3;
|
|
6291
|
+
}
|
|
6292
|
+
if (digits === 13) {
|
|
6293
|
+
return ts;
|
|
6294
|
+
}
|
|
6295
|
+
if (digits === 16) {
|
|
6296
|
+
return Math.floor(ts / 1e3);
|
|
6297
|
+
}
|
|
6298
|
+
while (ts > 9999999999999) {
|
|
6299
|
+
ts = Math.floor(ts / 1e3);
|
|
6300
|
+
}
|
|
6301
|
+
return ts;
|
|
6302
|
+
}
|
|
6303
|
+
|
|
6285
6304
|
// src/interactions.ts
|
|
6286
6305
|
var TwitterInteractionClient = class {
|
|
6287
6306
|
/**
|
|
@@ -6435,7 +6454,7 @@ var TwitterInteractionClient = class {
|
|
|
6435
6454
|
if (existingMemory) {
|
|
6436
6455
|
continue;
|
|
6437
6456
|
}
|
|
6438
|
-
const tweetAge = Date.now() - tweet.timestamp
|
|
6457
|
+
const tweetAge = Date.now() - getEpochMs(tweet.timestamp);
|
|
6439
6458
|
const maxAge = 24 * 60 * 60 * 1e3;
|
|
6440
6459
|
if (tweetAge > maxAge) {
|
|
6441
6460
|
continue;
|
|
@@ -6464,7 +6483,7 @@ var TwitterInteractionClient = class {
|
|
|
6464
6483
|
1 /* Latest */
|
|
6465
6484
|
);
|
|
6466
6485
|
const relevantTweets = searchResult.tweets.filter((tweet) => {
|
|
6467
|
-
const tweetAge = Date.now() - tweet.timestamp
|
|
6486
|
+
const tweetAge = Date.now() - getEpochMs(tweet.timestamp);
|
|
6468
6487
|
return tweetAge < 12 * 60 * 60 * 1e3;
|
|
6469
6488
|
});
|
|
6470
6489
|
if (relevantTweets.length > 0) {
|
|
@@ -6583,7 +6602,7 @@ Response (YES/NO):`;
|
|
|
6583
6602
|
},
|
|
6584
6603
|
agentId: this.runtime.agentId,
|
|
6585
6604
|
roomId,
|
|
6586
|
-
createdAt: tweet.timestamp
|
|
6605
|
+
createdAt: getEpochMs(tweet.timestamp)
|
|
6587
6606
|
};
|
|
6588
6607
|
await this.runtime.createMemory(tweetMemory, "messages");
|
|
6589
6608
|
}
|
|
@@ -6602,7 +6621,7 @@ Response (YES/NO):`;
|
|
|
6602
6621
|
},
|
|
6603
6622
|
agentId: this.runtime.agentId,
|
|
6604
6623
|
roomId: createUniqueUuid2(this.runtime, tweet.conversationId),
|
|
6605
|
-
createdAt: tweet.timestamp
|
|
6624
|
+
createdAt: getEpochMs(tweet.timestamp)
|
|
6606
6625
|
};
|
|
6607
6626
|
const result = await this.handleTweet({
|
|
6608
6627
|
tweet,
|
|
@@ -6739,7 +6758,7 @@ Response (YES/NO):`;
|
|
|
6739
6758
|
},
|
|
6740
6759
|
agentId: this.runtime.agentId,
|
|
6741
6760
|
roomId,
|
|
6742
|
-
createdAt: tweet.timestamp
|
|
6761
|
+
createdAt: getEpochMs(tweet.timestamp)
|
|
6743
6762
|
};
|
|
6744
6763
|
logger4.log("Saving tweet memory...");
|
|
6745
6764
|
await this.runtime.createMemory(memory, "messages");
|
|
@@ -7428,7 +7447,7 @@ var TwitterTimelineClient = class {
|
|
|
7428
7447
|
},
|
|
7429
7448
|
entityId: createUniqueUuid4(runtime, tweet.userId),
|
|
7430
7449
|
roomId: createUniqueUuid4(runtime, tweet.conversationId),
|
|
7431
|
-
createdAt: tweet.timestamp
|
|
7450
|
+
createdAt: getEpochMs(tweet.timestamp)
|
|
7432
7451
|
};
|
|
7433
7452
|
}
|
|
7434
7453
|
async handleTimeline() {
|
|
@@ -7545,7 +7564,7 @@ ${actionSummary.join("\n")}`);
|
|
|
7545
7564
|
},
|
|
7546
7565
|
agentId: this.runtime.agentId,
|
|
7547
7566
|
roomId,
|
|
7548
|
-
createdAt: tweet.timestamp
|
|
7567
|
+
createdAt: getEpochMs(tweet.timestamp)
|
|
7549
7568
|
},
|
|
7550
7569
|
"messages"
|
|
7551
7570
|
);
|
|
@@ -8062,6 +8081,13 @@ var TwitterDiscoveryClient = class {
|
|
|
8062
8081
|
// Remove the discoverFromTrends method since API v2 doesn't support it
|
|
8063
8082
|
// Remove the isTrendRelevant method since we're not using trends
|
|
8064
8083
|
scoreTweet(tweet, source) {
|
|
8084
|
+
if (tweet.isRetweet) {
|
|
8085
|
+
return {
|
|
8086
|
+
tweet,
|
|
8087
|
+
relevanceScore: 0,
|
|
8088
|
+
engagementType: "skip"
|
|
8089
|
+
};
|
|
8090
|
+
}
|
|
8065
8091
|
let relevanceScore = 0;
|
|
8066
8092
|
const sourceScores = {
|
|
8067
8093
|
topic: 0.4,
|
|
@@ -8225,10 +8251,25 @@ var TwitterDiscoveryClient = class {
|
|
|
8225
8251
|
engagementCount++;
|
|
8226
8252
|
await this.delay(3e3 + Math.random() * 5e3);
|
|
8227
8253
|
} catch (error) {
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8254
|
+
if (error?.message?.includes("403")) {
|
|
8255
|
+
logger7.warn(
|
|
8256
|
+
`Permission denied (403) for tweet ${scoredTweet.tweet.id}. This might be a protected account or restricted tweet. Skipping.`
|
|
8257
|
+
);
|
|
8258
|
+
await this.saveEngagementMemory(
|
|
8259
|
+
scoredTweet.tweet,
|
|
8260
|
+
"skip"
|
|
8261
|
+
);
|
|
8262
|
+
} else if (error?.message?.includes("429")) {
|
|
8263
|
+
logger7.warn(
|
|
8264
|
+
`Rate limit (429) hit while engaging with tweet ${scoredTweet.tweet.id}. Pausing engagement cycle.`
|
|
8265
|
+
);
|
|
8266
|
+
break;
|
|
8267
|
+
} else {
|
|
8268
|
+
logger7.error(
|
|
8269
|
+
`Failed to engage with tweet ${scoredTweet.tweet.id}:`,
|
|
8270
|
+
error
|
|
8271
|
+
);
|
|
8272
|
+
}
|
|
8232
8273
|
}
|
|
8233
8274
|
}
|
|
8234
8275
|
return engagementCount;
|
|
@@ -8691,7 +8732,7 @@ var _ClientBase = class _ClientBase {
|
|
|
8691
8732
|
content,
|
|
8692
8733
|
agentId: this.runtime.agentId,
|
|
8693
8734
|
roomId,
|
|
8694
|
-
createdAt: tweet.timestamp
|
|
8735
|
+
createdAt: getEpochMs(tweet.timestamp)
|
|
8695
8736
|
},
|
|
8696
8737
|
"messages"
|
|
8697
8738
|
);
|
|
@@ -8772,7 +8813,7 @@ var _ClientBase = class _ClientBase {
|
|
|
8772
8813
|
content,
|
|
8773
8814
|
agentId: this.runtime.agentId,
|
|
8774
8815
|
roomId,
|
|
8775
|
-
createdAt: tweet.timestamp
|
|
8816
|
+
createdAt: getEpochMs(tweet.timestamp)
|
|
8776
8817
|
},
|
|
8777
8818
|
"messages"
|
|
8778
8819
|
);
|