@elizaos/plugin-twitter 1.2.5 → 1.2.7
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/dist/index.d.ts +3 -1222
- package/dist/index.js +204 -135
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,7 +5,10 @@ var __export = (target, all) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/index.ts
|
|
8
|
-
import { logger as
|
|
8
|
+
import { logger as logger10 } from "@elizaos/core";
|
|
9
|
+
|
|
10
|
+
// src/services/twitter.service.ts
|
|
11
|
+
import { Service, logger as logger8 } from "@elizaos/core";
|
|
9
12
|
|
|
10
13
|
// src/interactions.ts
|
|
11
14
|
import {
|
|
@@ -1983,6 +1986,17 @@ var parseActionResponseFromText = (text) => {
|
|
|
1983
1986
|
return { actions };
|
|
1984
1987
|
};
|
|
1985
1988
|
|
|
1989
|
+
// src/utils/settings.ts
|
|
1990
|
+
function getSetting(runtime, key, defaultValue) {
|
|
1991
|
+
if (runtime && typeof runtime.getSetting === "function") {
|
|
1992
|
+
const value = runtime.getSetting(key);
|
|
1993
|
+
if (value !== void 0 && value !== null) {
|
|
1994
|
+
return String(value);
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
return process.env[key] ?? defaultValue;
|
|
1998
|
+
}
|
|
1999
|
+
|
|
1986
2000
|
// node_modules/zod/dist/esm/v3/external.js
|
|
1987
2001
|
var external_exports = {};
|
|
1988
2002
|
__export(external_exports, {
|
|
@@ -6077,15 +6091,6 @@ function getTargetUsers(targetUsersConfig) {
|
|
|
6077
6091
|
const users = parseTargetUsers(targetUsersConfig);
|
|
6078
6092
|
return users.filter((u) => u !== "*");
|
|
6079
6093
|
}
|
|
6080
|
-
function getSetting(runtime, key, defaultValue) {
|
|
6081
|
-
if (runtime && typeof runtime.getSetting === "function") {
|
|
6082
|
-
const value = runtime.getSetting(key);
|
|
6083
|
-
if (value !== void 0 && value !== null) {
|
|
6084
|
-
return String(value);
|
|
6085
|
-
}
|
|
6086
|
-
}
|
|
6087
|
-
return process.env[key] ?? defaultValue;
|
|
6088
|
-
}
|
|
6089
6094
|
async function validateTwitterConfig(runtime, config = {}) {
|
|
6090
6095
|
try {
|
|
6091
6096
|
const validatedConfig = {
|
|
@@ -6123,17 +6128,6 @@ async function validateTwitterConfig(runtime, config = {}) {
|
|
|
6123
6128
|
}
|
|
6124
6129
|
}
|
|
6125
6130
|
|
|
6126
|
-
// src/utils/settings.ts
|
|
6127
|
-
function getSetting2(runtime, key, defaultValue) {
|
|
6128
|
-
if (runtime && typeof runtime.getSetting === "function") {
|
|
6129
|
-
const value = runtime.getSetting(key);
|
|
6130
|
-
if (value !== void 0 && value !== null) {
|
|
6131
|
-
return String(value);
|
|
6132
|
-
}
|
|
6133
|
-
}
|
|
6134
|
-
return process.env[key] ?? defaultValue;
|
|
6135
|
-
}
|
|
6136
|
-
|
|
6137
6131
|
// src/interactions.ts
|
|
6138
6132
|
var TwitterInteractionClient = class {
|
|
6139
6133
|
/**
|
|
@@ -6149,7 +6143,7 @@ var TwitterInteractionClient = class {
|
|
|
6149
6143
|
this.client = client;
|
|
6150
6144
|
this.runtime = runtime;
|
|
6151
6145
|
this.state = state;
|
|
6152
|
-
const dryRunSetting = this.state?.TWITTER_DRY_RUN ??
|
|
6146
|
+
const dryRunSetting = this.state?.TWITTER_DRY_RUN ?? getSetting(this.runtime, "TWITTER_DRY_RUN") ?? process.env.TWITTER_DRY_RUN;
|
|
6153
6147
|
this.isDryRun = dryRunSetting === true || dryRunSetting === "true" || typeof dryRunSetting === "string" && dryRunSetting.toLowerCase() === "true";
|
|
6154
6148
|
}
|
|
6155
6149
|
/**
|
|
@@ -6164,7 +6158,7 @@ var TwitterInteractionClient = class {
|
|
|
6164
6158
|
return;
|
|
6165
6159
|
}
|
|
6166
6160
|
const engagementIntervalMinutes = parseInt(
|
|
6167
|
-
this.state?.TWITTER_ENGAGEMENT_INTERVAL ||
|
|
6161
|
+
this.state?.TWITTER_ENGAGEMENT_INTERVAL || getSetting(this.runtime, "TWITTER_ENGAGEMENT_INTERVAL") || process.env.TWITTER_ENGAGEMENT_INTERVAL || "30"
|
|
6168
6162
|
);
|
|
6169
6163
|
const interactionInterval = engagementIntervalMinutes * 60 * 1e3;
|
|
6170
6164
|
logger3.info(`Twitter interaction client will check every ${engagementIntervalMinutes} minutes`);
|
|
@@ -6189,11 +6183,11 @@ var TwitterInteractionClient = class {
|
|
|
6189
6183
|
logger3.log("Checking Twitter interactions");
|
|
6190
6184
|
const twitterUsername = this.client.profile?.username;
|
|
6191
6185
|
try {
|
|
6192
|
-
const repliesEnabled = (
|
|
6186
|
+
const repliesEnabled = (getSetting(this.runtime, "TWITTER_ENABLE_REPLIES") ?? process.env.TWITTER_ENABLE_REPLIES) !== "false";
|
|
6193
6187
|
if (repliesEnabled) {
|
|
6194
6188
|
await this.handleMentions(twitterUsername);
|
|
6195
6189
|
}
|
|
6196
|
-
const targetUsersConfig = (
|
|
6190
|
+
const targetUsersConfig = (getSetting(this.runtime, "TWITTER_TARGET_USERS") ?? process.env.TWITTER_TARGET_USERS) || "";
|
|
6197
6191
|
if (targetUsersConfig?.trim()) {
|
|
6198
6192
|
await this.handleTargetUserPosts(targetUsersConfig);
|
|
6199
6193
|
}
|
|
@@ -6267,7 +6261,7 @@ var TwitterInteractionClient = class {
|
|
|
6267
6261
|
*/
|
|
6268
6262
|
async processTargetUserTweets(tweets, username) {
|
|
6269
6263
|
const maxEngagementsPerRun = parseInt(
|
|
6270
|
-
|
|
6264
|
+
getSetting(this.runtime, "TWITTER_MAX_ENGAGEMENTS_PER_RUN") || process.env.TWITTER_MAX_ENGAGEMENTS_PER_RUN || "10"
|
|
6271
6265
|
);
|
|
6272
6266
|
let engagementCount = 0;
|
|
6273
6267
|
for (const tweet of tweets) {
|
|
@@ -6344,7 +6338,8 @@ var TwitterInteractionClient = class {
|
|
|
6344
6338
|
createdAt: Date.now()
|
|
6345
6339
|
};
|
|
6346
6340
|
const state = await this.runtime.composeState(shouldEngageMemory);
|
|
6347
|
-
const
|
|
6341
|
+
const characterName = this.runtime?.character?.name || "AI Assistant";
|
|
6342
|
+
const context = `You are ${characterName}. Should you reply to this tweet based on your interests and expertise?
|
|
6348
6343
|
|
|
6349
6344
|
Tweet by @${tweet.username}: "${tweet.text}"
|
|
6350
6345
|
|
|
@@ -6463,7 +6458,7 @@ Response (YES/NO):`;
|
|
|
6463
6458
|
);
|
|
6464
6459
|
let uniqueTweetCandidates = [...mentionCandidates];
|
|
6465
6460
|
uniqueTweetCandidates = uniqueTweetCandidates.sort((a, b) => a.id.localeCompare(b.id)).filter((tweet) => tweet.userId !== this.client.profile.id);
|
|
6466
|
-
const targetUsersConfig = (
|
|
6461
|
+
const targetUsersConfig = (getSetting(this.runtime, "TWITTER_TARGET_USERS") ?? process.env.TWITTER_TARGET_USERS) || "";
|
|
6467
6462
|
if (targetUsersConfig?.trim()) {
|
|
6468
6463
|
uniqueTweetCandidates = uniqueTweetCandidates.filter((tweet) => {
|
|
6469
6464
|
const shouldTarget = shouldTargetUser(
|
|
@@ -6479,7 +6474,7 @@ Response (YES/NO):`;
|
|
|
6479
6474
|
});
|
|
6480
6475
|
}
|
|
6481
6476
|
const maxInteractionsPerRun = parseInt(
|
|
6482
|
-
|
|
6477
|
+
getSetting(this.runtime, "TWITTER_MAX_ENGAGEMENTS_PER_RUN") || process.env.TWITTER_MAX_ENGAGEMENTS_PER_RUN || "10"
|
|
6483
6478
|
);
|
|
6484
6479
|
const tweetsToProcess = uniqueTweetCandidates.slice(0, maxInteractionsPerRun);
|
|
6485
6480
|
logger3.info(`Processing ${tweetsToProcess.length} of ${uniqueTweetCandidates.length} mention tweets (max: ${maxInteractionsPerRun})`);
|
|
@@ -6838,12 +6833,12 @@ var TwitterPostClient = class {
|
|
|
6838
6833
|
this.client = client;
|
|
6839
6834
|
this.state = state;
|
|
6840
6835
|
this.runtime = runtime;
|
|
6841
|
-
const dryRunSetting = this.state?.TWITTER_DRY_RUN ??
|
|
6836
|
+
const dryRunSetting = this.state?.TWITTER_DRY_RUN ?? getSetting(this.runtime, "TWITTER_DRY_RUN") ?? process.env.TWITTER_DRY_RUN;
|
|
6842
6837
|
this.isDryRun = dryRunSetting === true || dryRunSetting === "true" || typeof dryRunSetting === "string" && dryRunSetting.toLowerCase() === "true";
|
|
6843
6838
|
logger4.log("Twitter Post Client Configuration:");
|
|
6844
6839
|
logger4.log(`- Dry Run Mode: ${this.isDryRun ? "Enabled" : "Disabled"}`);
|
|
6845
6840
|
const postIntervalMinutes = parseInt(
|
|
6846
|
-
this.state?.TWITTER_POST_INTERVAL ||
|
|
6841
|
+
this.state?.TWITTER_POST_INTERVAL || getSetting(this.runtime, "TWITTER_POST_INTERVAL") || process.env.TWITTER_POST_INTERVAL || "120"
|
|
6847
6842
|
);
|
|
6848
6843
|
logger4.log(`- Post Interval: ${postIntervalMinutes} minutes`);
|
|
6849
6844
|
}
|
|
@@ -6866,7 +6861,7 @@ var TwitterPostClient = class {
|
|
|
6866
6861
|
return;
|
|
6867
6862
|
}
|
|
6868
6863
|
const postIntervalMinutes = parseInt(
|
|
6869
|
-
this.state?.TWITTER_POST_INTERVAL ||
|
|
6864
|
+
this.state?.TWITTER_POST_INTERVAL || getSetting(this.runtime, "TWITTER_POST_INTERVAL") || process.env.TWITTER_POST_INTERVAL || "120"
|
|
6870
6865
|
);
|
|
6871
6866
|
const interval = postIntervalMinutes * 60 * 1e3;
|
|
6872
6867
|
logger4.info(`Next tweet scheduled in ${postIntervalMinutes} minutes`);
|
|
@@ -6877,7 +6872,7 @@ var TwitterPostClient = class {
|
|
|
6877
6872
|
};
|
|
6878
6873
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
6879
6874
|
const postImmediately = parseInt(
|
|
6880
|
-
this.state?.TWITTER_POST_INTERVAL ||
|
|
6875
|
+
this.state?.TWITTER_POST_INTERVAL || getSetting(this.runtime, "TWITTER_POST_INTERVAL") || process.env.TWITTER_POST_INTERVAL || "120"
|
|
6881
6876
|
) === 0;
|
|
6882
6877
|
if (postImmediately) {
|
|
6883
6878
|
logger4.info("TWITTER_POST_IMMEDIATELY is true, generating initial tweet now");
|
|
@@ -7093,9 +7088,9 @@ var TwitterTimelineClient = class {
|
|
|
7093
7088
|
this.twitterClient = client.twitterClient;
|
|
7094
7089
|
this.runtime = runtime;
|
|
7095
7090
|
this.state = state;
|
|
7096
|
-
const dryRunSetting = this.state?.TWITTER_DRY_RUN ??
|
|
7091
|
+
const dryRunSetting = this.state?.TWITTER_DRY_RUN ?? getSetting(this.runtime, "TWITTER_DRY_RUN") ?? process.env.TWITTER_DRY_RUN;
|
|
7097
7092
|
this.isDryRun = dryRunSetting === true || dryRunSetting === "true" || typeof dryRunSetting === "string" && dryRunSetting.toLowerCase() === "true";
|
|
7098
|
-
const timelineMode =
|
|
7093
|
+
const timelineMode = getSetting(this.runtime, "TWITTER_TIMELINE_MODE") ?? process.env.TWITTER_TIMELINE_MODE;
|
|
7099
7094
|
this.timelineType = timelineMode === "following" /* Following */ ? "following" /* Following */ : "foryou" /* ForYou */;
|
|
7100
7095
|
}
|
|
7101
7096
|
async start() {
|
|
@@ -7107,7 +7102,7 @@ var TwitterTimelineClient = class {
|
|
|
7107
7102
|
return;
|
|
7108
7103
|
}
|
|
7109
7104
|
const engagementIntervalMinutes = parseInt(
|
|
7110
|
-
this.state?.TWITTER_ENGAGEMENT_INTERVAL ||
|
|
7105
|
+
this.state?.TWITTER_ENGAGEMENT_INTERVAL || getSetting(this.runtime, "TWITTER_ENGAGEMENT_INTERVAL") || process.env.TWITTER_ENGAGEMENT_INTERVAL || "30"
|
|
7111
7106
|
);
|
|
7112
7107
|
const actionInterval = engagementIntervalMinutes * 60 * 1e3;
|
|
7113
7108
|
logger5.info(`Timeline client will check every ${engagementIntervalMinutes} minutes`);
|
|
@@ -7153,7 +7148,7 @@ var TwitterTimelineClient = class {
|
|
|
7153
7148
|
const tweets = await this.getTimeline(20);
|
|
7154
7149
|
logger5.info(`Fetched ${tweets.length} tweets from timeline`);
|
|
7155
7150
|
const maxActionsPerCycle = parseInt(
|
|
7156
|
-
|
|
7151
|
+
getSetting(this.runtime, "TWITTER_MAX_ENGAGEMENTS_PER_RUN") || process.env.TWITTER_MAX_ENGAGEMENTS_PER_RUN || "10"
|
|
7157
7152
|
);
|
|
7158
7153
|
const tweetDecisions = [];
|
|
7159
7154
|
for (const tweet of tweets) {
|
|
@@ -7451,7 +7446,7 @@ var TwitterDiscoveryClient = class {
|
|
|
7451
7446
|
this.client = client;
|
|
7452
7447
|
this.twitterClient = client.twitterClient;
|
|
7453
7448
|
this.runtime = runtime;
|
|
7454
|
-
const dryRunSetting = state?.TWITTER_DRY_RUN ??
|
|
7449
|
+
const dryRunSetting = state?.TWITTER_DRY_RUN ?? getSetting(this.runtime, "TWITTER_DRY_RUN") ?? process.env.TWITTER_DRY_RUN;
|
|
7455
7450
|
this.isDryRun = dryRunSetting === true || dryRunSetting === "true" || typeof dryRunSetting === "string" && dryRunSetting.toLowerCase() === "true";
|
|
7456
7451
|
this.config = this.buildDiscoveryConfig();
|
|
7457
7452
|
logger6.info("Twitter Discovery Config:", {
|
|
@@ -7463,18 +7458,36 @@ var TwitterDiscoveryClient = class {
|
|
|
7463
7458
|
});
|
|
7464
7459
|
}
|
|
7465
7460
|
buildDiscoveryConfig() {
|
|
7466
|
-
const character = this.runtime
|
|
7467
|
-
const
|
|
7461
|
+
const character = this.runtime?.character;
|
|
7462
|
+
const defaultTopics = [
|
|
7463
|
+
"ai",
|
|
7464
|
+
"technology",
|
|
7465
|
+
"blockchain",
|
|
7466
|
+
"web3",
|
|
7467
|
+
"crypto",
|
|
7468
|
+
"programming",
|
|
7469
|
+
"innovation"
|
|
7470
|
+
];
|
|
7471
|
+
let topics = defaultTopics;
|
|
7472
|
+
if (character) {
|
|
7473
|
+
if (character.topics && Array.isArray(character.topics) && character.topics.length > 0) {
|
|
7474
|
+
topics = character.topics;
|
|
7475
|
+
} else if (character.bio) {
|
|
7476
|
+
topics = this.extractTopicsFromBio(character.bio);
|
|
7477
|
+
}
|
|
7478
|
+
} else {
|
|
7479
|
+
logger6.warn("Character not available in runtime, using default topics for discovery");
|
|
7480
|
+
}
|
|
7468
7481
|
return {
|
|
7469
7482
|
topics,
|
|
7470
7483
|
minFollowerCount: parseInt(
|
|
7471
|
-
|
|
7484
|
+
getSetting(this.runtime, "TWITTER_MIN_FOLLOWER_COUNT") || process.env.TWITTER_MIN_FOLLOWER_COUNT || "100"
|
|
7472
7485
|
),
|
|
7473
7486
|
maxFollowsPerCycle: parseInt(
|
|
7474
|
-
|
|
7487
|
+
getSetting(this.runtime, "TWITTER_MAX_FOLLOWS_PER_CYCLE") || process.env.TWITTER_MAX_FOLLOWS_PER_CYCLE || "5"
|
|
7475
7488
|
),
|
|
7476
7489
|
maxEngagementsPerCycle: parseInt(
|
|
7477
|
-
|
|
7490
|
+
getSetting(this.runtime, "TWITTER_MAX_ENGAGEMENTS_PER_RUN") || process.env.TWITTER_MAX_ENGAGEMENTS_PER_RUN || "10"
|
|
7478
7491
|
),
|
|
7479
7492
|
likeThreshold: 0.6,
|
|
7480
7493
|
replyThreshold: 0.8,
|
|
@@ -7482,6 +7495,9 @@ var TwitterDiscoveryClient = class {
|
|
|
7482
7495
|
};
|
|
7483
7496
|
}
|
|
7484
7497
|
extractTopicsFromBio(bio) {
|
|
7498
|
+
if (!bio) {
|
|
7499
|
+
return [];
|
|
7500
|
+
}
|
|
7485
7501
|
const bioText = Array.isArray(bio) ? bio.join(" ") : bio;
|
|
7486
7502
|
const words = bioText.toLowerCase().split(/\s+/).filter((word) => word.length > 4).filter((word) => !["about", "helping", "working", "people", "making", "building"].includes(word));
|
|
7487
7503
|
return [...new Set(words)].slice(0, 5);
|
|
@@ -7500,7 +7516,7 @@ var TwitterDiscoveryClient = class {
|
|
|
7500
7516
|
logger6.error("Discovery cycle error:", error);
|
|
7501
7517
|
}
|
|
7502
7518
|
const baseInterval = parseInt(
|
|
7503
|
-
|
|
7519
|
+
getSetting(this.runtime, "TWITTER_DISCOVERY_INTERVAL") || process.env.TWITTER_DISCOVERY_INTERVAL || "30"
|
|
7504
7520
|
);
|
|
7505
7521
|
const variance = Math.random() * 20 - 10;
|
|
7506
7522
|
const nextInterval = (baseInterval + variance) * 60 * 1e3;
|
|
@@ -7814,12 +7830,21 @@ var TwitterDiscoveryClient = class {
|
|
|
7814
7830
|
return followMemories.length > 0;
|
|
7815
7831
|
}
|
|
7816
7832
|
async generateReply(tweet) {
|
|
7817
|
-
const
|
|
7833
|
+
const characterName = this.runtime?.character?.name || "AI Assistant";
|
|
7834
|
+
let characterBio = "";
|
|
7835
|
+
if (this.runtime?.character?.bio) {
|
|
7836
|
+
if (Array.isArray(this.runtime.character.bio)) {
|
|
7837
|
+
characterBio = this.runtime.character.bio.join(" ");
|
|
7838
|
+
} else {
|
|
7839
|
+
characterBio = this.runtime.character.bio;
|
|
7840
|
+
}
|
|
7841
|
+
}
|
|
7842
|
+
const prompt = `You are ${characterName}. Generate a thoughtful reply to this tweet:
|
|
7818
7843
|
|
|
7819
7844
|
Tweet by @${tweet.username}: "${tweet.text}"
|
|
7820
7845
|
|
|
7821
7846
|
Your interests: ${this.config.topics.join(", ")}
|
|
7822
|
-
Character bio: ${
|
|
7847
|
+
Character bio: ${characterBio}
|
|
7823
7848
|
|
|
7824
7849
|
Keep the reply:
|
|
7825
7850
|
- Relevant and adding value to the conversation
|
|
@@ -7837,12 +7862,21 @@ Reply:`;
|
|
|
7837
7862
|
return response.trim();
|
|
7838
7863
|
}
|
|
7839
7864
|
async generateQuote(tweet) {
|
|
7840
|
-
const
|
|
7865
|
+
const characterName = this.runtime?.character?.name || "AI Assistant";
|
|
7866
|
+
let characterBio = "";
|
|
7867
|
+
if (this.runtime?.character?.bio) {
|
|
7868
|
+
if (Array.isArray(this.runtime.character.bio)) {
|
|
7869
|
+
characterBio = this.runtime.character.bio.join(" ");
|
|
7870
|
+
} else {
|
|
7871
|
+
characterBio = this.runtime.character.bio;
|
|
7872
|
+
}
|
|
7873
|
+
}
|
|
7874
|
+
const prompt = `You are ${characterName}. Add your perspective to this tweet with a quote tweet:
|
|
7841
7875
|
|
|
7842
7876
|
Original tweet by @${tweet.username}: "${tweet.text}"
|
|
7843
7877
|
|
|
7844
7878
|
Your interests: ${this.config.topics.join(", ")}
|
|
7845
|
-
Character bio: ${
|
|
7879
|
+
Character bio: ${characterBio}
|
|
7846
7880
|
|
|
7847
7881
|
Create a quote tweet that:
|
|
7848
7882
|
- Adds unique insight or perspective
|
|
@@ -8414,11 +8448,23 @@ var _ClientBase = class _ClientBase {
|
|
|
8414
8448
|
try {
|
|
8415
8449
|
const profile = await this.requestQueue.add(async () => {
|
|
8416
8450
|
const profile2 = await this.twitterClient.getProfile(username);
|
|
8451
|
+
const defaultName = "AI Assistant";
|
|
8452
|
+
const defaultBio = "";
|
|
8453
|
+
let characterName = defaultName;
|
|
8454
|
+
let characterBio = defaultBio;
|
|
8455
|
+
if (this.runtime?.character) {
|
|
8456
|
+
characterName = this.runtime.character.name || defaultName;
|
|
8457
|
+
if (typeof this.runtime.character.bio === "string") {
|
|
8458
|
+
characterBio = this.runtime.character.bio;
|
|
8459
|
+
} else if (Array.isArray(this.runtime.character.bio) && this.runtime.character.bio.length > 0) {
|
|
8460
|
+
characterBio = this.runtime.character.bio[0];
|
|
8461
|
+
}
|
|
8462
|
+
}
|
|
8417
8463
|
return {
|
|
8418
8464
|
id: profile2.userId,
|
|
8419
8465
|
username,
|
|
8420
|
-
screenName: profile2.name ||
|
|
8421
|
-
bio: profile2.biography ||
|
|
8466
|
+
screenName: profile2.name || characterName,
|
|
8467
|
+
bio: profile2.biography || characterBio,
|
|
8422
8468
|
nicknames: this.profile?.nicknames || []
|
|
8423
8469
|
};
|
|
8424
8470
|
});
|
|
@@ -8471,7 +8517,45 @@ _ClientBase._twitterClients = {};
|
|
|
8471
8517
|
var ClientBase = _ClientBase;
|
|
8472
8518
|
|
|
8473
8519
|
// src/services/twitter.service.ts
|
|
8474
|
-
|
|
8520
|
+
var TwitterClientInstance = class {
|
|
8521
|
+
constructor(runtime, state) {
|
|
8522
|
+
this.client = new ClientBase(runtime, state);
|
|
8523
|
+
const postEnabledSetting = getSetting(runtime, "TWITTER_ENABLE_POST") ?? process.env.TWITTER_ENABLE_POST;
|
|
8524
|
+
logger8.debug(`TWITTER_ENABLE_POST setting value: ${JSON.stringify(postEnabledSetting)}, type: ${typeof postEnabledSetting}`);
|
|
8525
|
+
const postEnabled = postEnabledSetting === "true" || postEnabledSetting === true;
|
|
8526
|
+
if (postEnabled) {
|
|
8527
|
+
logger8.info("Twitter posting is ENABLED - creating post client");
|
|
8528
|
+
this.post = new TwitterPostClient(this.client, runtime, state);
|
|
8529
|
+
} else {
|
|
8530
|
+
logger8.info("Twitter posting is DISABLED - set TWITTER_ENABLE_POST=true to enable automatic posting");
|
|
8531
|
+
}
|
|
8532
|
+
const repliesEnabled = (getSetting(runtime, "TWITTER_ENABLE_REPLIES") ?? process.env.TWITTER_ENABLE_REPLIES) !== "false";
|
|
8533
|
+
if (repliesEnabled) {
|
|
8534
|
+
logger8.info("Twitter replies/interactions are ENABLED");
|
|
8535
|
+
this.interaction = new TwitterInteractionClient(
|
|
8536
|
+
this.client,
|
|
8537
|
+
runtime,
|
|
8538
|
+
state
|
|
8539
|
+
);
|
|
8540
|
+
} else {
|
|
8541
|
+
logger8.info("Twitter replies/interactions are DISABLED");
|
|
8542
|
+
}
|
|
8543
|
+
const actionsEnabled = (getSetting(runtime, "TWITTER_ENABLE_ACTIONS") ?? process.env.TWITTER_ENABLE_ACTIONS) === "true";
|
|
8544
|
+
if (actionsEnabled) {
|
|
8545
|
+
logger8.info("Twitter timeline actions are ENABLED");
|
|
8546
|
+
this.timeline = new TwitterTimelineClient(this.client, runtime, state);
|
|
8547
|
+
} else {
|
|
8548
|
+
logger8.info("Twitter timeline actions are DISABLED");
|
|
8549
|
+
}
|
|
8550
|
+
const discoveryEnabled = (getSetting(runtime, "TWITTER_ENABLE_DISCOVERY") ?? process.env.TWITTER_ENABLE_DISCOVERY) === "true" || actionsEnabled && (getSetting(runtime, "TWITTER_ENABLE_DISCOVERY") ?? process.env.TWITTER_ENABLE_DISCOVERY) !== "false";
|
|
8551
|
+
if (discoveryEnabled) {
|
|
8552
|
+
logger8.info("Twitter discovery service is ENABLED");
|
|
8553
|
+
this.discovery = new TwitterDiscoveryClient(this.client, runtime, state);
|
|
8554
|
+
} else {
|
|
8555
|
+
logger8.info("Twitter discovery service is DISABLED - set TWITTER_ENABLE_DISCOVERY=true to enable");
|
|
8556
|
+
}
|
|
8557
|
+
}
|
|
8558
|
+
};
|
|
8475
8559
|
var _TwitterService = class _TwitterService extends Service {
|
|
8476
8560
|
constructor() {
|
|
8477
8561
|
super();
|
|
@@ -8481,9 +8565,48 @@ var _TwitterService = class _TwitterService extends Service {
|
|
|
8481
8565
|
static async start(runtime) {
|
|
8482
8566
|
const service = new _TwitterService();
|
|
8483
8567
|
service.runtime = runtime;
|
|
8568
|
+
try {
|
|
8569
|
+
await validateTwitterConfig(runtime);
|
|
8570
|
+
logger8.log("\u2705 Twitter configuration validated successfully");
|
|
8571
|
+
service.twitterClient = new TwitterClientInstance(runtime, {});
|
|
8572
|
+
await service.twitterClient.client.init();
|
|
8573
|
+
if (service.twitterClient.post) {
|
|
8574
|
+
logger8.log("\u{1F4EE} Starting Twitter post client...");
|
|
8575
|
+
await service.twitterClient.post.start();
|
|
8576
|
+
}
|
|
8577
|
+
if (service.twitterClient.interaction) {
|
|
8578
|
+
logger8.log("\u{1F4AC} Starting Twitter interaction client...");
|
|
8579
|
+
await service.twitterClient.interaction.start();
|
|
8580
|
+
}
|
|
8581
|
+
if (service.twitterClient.timeline) {
|
|
8582
|
+
logger8.log("\u{1F4CA} Starting Twitter timeline client...");
|
|
8583
|
+
await service.twitterClient.timeline.start();
|
|
8584
|
+
}
|
|
8585
|
+
if (service.twitterClient.discovery) {
|
|
8586
|
+
logger8.log("\u{1F50D} Starting Twitter discovery client...");
|
|
8587
|
+
await service.twitterClient.discovery.start();
|
|
8588
|
+
}
|
|
8589
|
+
logger8.log("\u2705 Twitter service started successfully");
|
|
8590
|
+
} catch (error) {
|
|
8591
|
+
logger8.error("\u{1F6A8} Failed to start Twitter service:", error);
|
|
8592
|
+
throw error;
|
|
8593
|
+
}
|
|
8484
8594
|
return service;
|
|
8485
8595
|
}
|
|
8486
8596
|
async stop() {
|
|
8597
|
+
if (this.twitterClient?.post) {
|
|
8598
|
+
await this.twitterClient.post.stop();
|
|
8599
|
+
}
|
|
8600
|
+
if (this.twitterClient?.interaction) {
|
|
8601
|
+
await this.twitterClient.interaction.stop();
|
|
8602
|
+
}
|
|
8603
|
+
if (this.twitterClient?.timeline) {
|
|
8604
|
+
await this.twitterClient.timeline.stop();
|
|
8605
|
+
}
|
|
8606
|
+
if (this.twitterClient?.discovery) {
|
|
8607
|
+
await this.twitterClient.discovery.stop();
|
|
8608
|
+
}
|
|
8609
|
+
logger8.log("Twitter service stopped");
|
|
8487
8610
|
}
|
|
8488
8611
|
};
|
|
8489
8612
|
_TwitterService.serviceType = "twitter";
|
|
@@ -8491,27 +8614,27 @@ var TwitterService = _TwitterService;
|
|
|
8491
8614
|
|
|
8492
8615
|
// src/actions/postTweet.ts
|
|
8493
8616
|
import {
|
|
8494
|
-
logger as
|
|
8617
|
+
logger as logger9,
|
|
8495
8618
|
ModelType as ModelType4
|
|
8496
8619
|
} from "@elizaos/core";
|
|
8497
8620
|
var postTweetAction = {
|
|
8498
8621
|
name: "POST_TWEET",
|
|
8499
8622
|
similes: ["TWEET", "SEND_TWEET", "TWITTER_POST", "POST_ON_TWITTER", "SHARE_ON_TWITTER"],
|
|
8500
8623
|
validate: async (runtime, message) => {
|
|
8501
|
-
|
|
8624
|
+
logger9.debug("Validating POST_TWEET action");
|
|
8502
8625
|
const text = message.content?.text?.trim();
|
|
8503
8626
|
if (!text || text.length === 0) {
|
|
8504
|
-
|
|
8627
|
+
logger9.error("No text content for tweet");
|
|
8505
8628
|
return false;
|
|
8506
8629
|
}
|
|
8507
8630
|
if (text.length > 280) {
|
|
8508
|
-
|
|
8631
|
+
logger9.warn(`Tweet too long: ${text.length} characters`);
|
|
8509
8632
|
}
|
|
8510
8633
|
return true;
|
|
8511
8634
|
},
|
|
8512
8635
|
description: "Post a tweet on Twitter",
|
|
8513
8636
|
handler: async (runtime, message, state, _options, callback) => {
|
|
8514
|
-
|
|
8637
|
+
logger9.info("Executing POST_TWEET action");
|
|
8515
8638
|
try {
|
|
8516
8639
|
const client = new ClientBase(runtime, {});
|
|
8517
8640
|
if (!client.twitterClient) {
|
|
@@ -8558,7 +8681,7 @@ Tweet:`;
|
|
|
8558
8681
|
tweetId = Date.now().toString();
|
|
8559
8682
|
}
|
|
8560
8683
|
const tweetUrl = `https://twitter.com/${client.profile.username}/status/${tweetId}`;
|
|
8561
|
-
|
|
8684
|
+
logger9.info(`Successfully posted tweet: ${tweetId}`);
|
|
8562
8685
|
await runtime.createMemory({
|
|
8563
8686
|
entityId: runtime.agentId,
|
|
8564
8687
|
content: {
|
|
@@ -8585,7 +8708,7 @@ View it here: ${tweetUrl}`,
|
|
|
8585
8708
|
throw new Error("Failed to post tweet - no response data");
|
|
8586
8709
|
}
|
|
8587
8710
|
} catch (error) {
|
|
8588
|
-
|
|
8711
|
+
logger9.error("Error posting tweet:", error);
|
|
8589
8712
|
if (callback) {
|
|
8590
8713
|
await callback({
|
|
8591
8714
|
text: `Sorry, I couldn't post the tweet. Error: ${error.message}`,
|
|
@@ -8645,91 +8768,37 @@ View it here: ${tweetUrl}`,
|
|
|
8645
8768
|
};
|
|
8646
8769
|
|
|
8647
8770
|
// src/index.ts
|
|
8648
|
-
var TwitterClientInstance = class {
|
|
8649
|
-
constructor(runtime, state) {
|
|
8650
|
-
this.client = new ClientBase(runtime, state);
|
|
8651
|
-
const getSetting3 = (key) => {
|
|
8652
|
-
if (runtime && typeof runtime.getSetting === "function") {
|
|
8653
|
-
return runtime.getSetting(key);
|
|
8654
|
-
}
|
|
8655
|
-
return void 0;
|
|
8656
|
-
};
|
|
8657
|
-
const postEnabledSetting = getSetting3("TWITTER_ENABLE_POST") ?? process.env.TWITTER_ENABLE_POST;
|
|
8658
|
-
logger9.debug(`TWITTER_ENABLE_POST setting value: ${JSON.stringify(postEnabledSetting)}, type: ${typeof postEnabledSetting}`);
|
|
8659
|
-
const postEnabled = postEnabledSetting === "true" || postEnabledSetting === true;
|
|
8660
|
-
if (postEnabled) {
|
|
8661
|
-
logger9.info("Twitter posting is ENABLED - creating post client");
|
|
8662
|
-
this.post = new TwitterPostClient(this.client, runtime, state);
|
|
8663
|
-
} else {
|
|
8664
|
-
logger9.info("Twitter posting is DISABLED - set TWITTER_ENABLE_POST=true to enable automatic posting");
|
|
8665
|
-
}
|
|
8666
|
-
const repliesEnabled = (getSetting3("TWITTER_ENABLE_REPLIES") ?? process.env.TWITTER_ENABLE_REPLIES) !== "false";
|
|
8667
|
-
if (repliesEnabled) {
|
|
8668
|
-
logger9.info("Twitter replies/interactions are ENABLED");
|
|
8669
|
-
this.interaction = new TwitterInteractionClient(
|
|
8670
|
-
this.client,
|
|
8671
|
-
runtime,
|
|
8672
|
-
state
|
|
8673
|
-
);
|
|
8674
|
-
} else {
|
|
8675
|
-
logger9.info("Twitter replies/interactions are DISABLED");
|
|
8676
|
-
}
|
|
8677
|
-
const actionsEnabled = (getSetting3("TWITTER_ENABLE_ACTIONS") ?? process.env.TWITTER_ENABLE_ACTIONS) === "true";
|
|
8678
|
-
if (actionsEnabled) {
|
|
8679
|
-
logger9.info("Twitter timeline actions are ENABLED");
|
|
8680
|
-
this.timeline = new TwitterTimelineClient(this.client, runtime, state);
|
|
8681
|
-
} else {
|
|
8682
|
-
logger9.info("Twitter timeline actions are DISABLED");
|
|
8683
|
-
}
|
|
8684
|
-
const discoveryEnabled = (getSetting3("TWITTER_ENABLE_DISCOVERY") ?? process.env.TWITTER_ENABLE_DISCOVERY) === "true" || actionsEnabled && (getSetting3("TWITTER_ENABLE_DISCOVERY") ?? process.env.TWITTER_ENABLE_DISCOVERY) !== "false";
|
|
8685
|
-
if (discoveryEnabled) {
|
|
8686
|
-
logger9.info("Twitter discovery service is ENABLED");
|
|
8687
|
-
this.discovery = new TwitterDiscoveryClient(this.client, runtime, state);
|
|
8688
|
-
} else {
|
|
8689
|
-
logger9.info("Twitter discovery service is DISABLED - set TWITTER_ENABLE_DISCOVERY=true to enable");
|
|
8690
|
-
}
|
|
8691
|
-
}
|
|
8692
|
-
};
|
|
8693
|
-
async function startTwitterClient(runtime) {
|
|
8694
|
-
try {
|
|
8695
|
-
logger9.log("\u{1F527} Initializing Twitter plugin...");
|
|
8696
|
-
await validateTwitterConfig(runtime);
|
|
8697
|
-
logger9.log("\u2705 Twitter configuration validated successfully");
|
|
8698
|
-
const twitterClient = new TwitterClientInstance(runtime, {});
|
|
8699
|
-
await twitterClient.client.init();
|
|
8700
|
-
await runtime.registerService(TwitterService);
|
|
8701
|
-
if (twitterClient.post) {
|
|
8702
|
-
logger9.log("\u{1F4EE} Starting Twitter post client...");
|
|
8703
|
-
await twitterClient.post.start();
|
|
8704
|
-
}
|
|
8705
|
-
if (twitterClient.interaction) {
|
|
8706
|
-
logger9.log("\u{1F4AC} Starting Twitter interaction client...");
|
|
8707
|
-
await twitterClient.interaction.start();
|
|
8708
|
-
}
|
|
8709
|
-
if (twitterClient.timeline) {
|
|
8710
|
-
logger9.log("\u{1F4CA} Starting Twitter timeline client...");
|
|
8711
|
-
await twitterClient.timeline.start();
|
|
8712
|
-
}
|
|
8713
|
-
if (twitterClient.discovery) {
|
|
8714
|
-
logger9.log("\u{1F50D} Starting Twitter discovery client...");
|
|
8715
|
-
await twitterClient.discovery.start();
|
|
8716
|
-
}
|
|
8717
|
-
logger9.log("\u2705 Twitter plugin started successfully");
|
|
8718
|
-
} catch (error) {
|
|
8719
|
-
logger9.error("\u{1F6A8} Failed to start Twitter plugin:", error);
|
|
8720
|
-
throw error;
|
|
8721
|
-
}
|
|
8722
|
-
}
|
|
8723
8771
|
var TwitterPlugin = {
|
|
8724
8772
|
name: "twitter",
|
|
8725
8773
|
description: "Twitter client with posting, interactions, and timeline actions",
|
|
8726
8774
|
actions: [postTweetAction],
|
|
8727
8775
|
services: [TwitterService],
|
|
8728
|
-
init:
|
|
8776
|
+
init: async (_config, runtime) => {
|
|
8777
|
+
logger10.log("\u{1F527} Initializing Twitter plugin...");
|
|
8778
|
+
const hasGetSetting = runtime && typeof runtime.getSetting === "function";
|
|
8779
|
+
const apiKey = hasGetSetting ? runtime.getSetting("TWITTER_API_KEY") : process.env.TWITTER_API_KEY;
|
|
8780
|
+
const apiSecretKey = hasGetSetting ? runtime.getSetting("TWITTER_API_SECRET_KEY") : process.env.TWITTER_API_SECRET_KEY;
|
|
8781
|
+
const accessToken = hasGetSetting ? runtime.getSetting("TWITTER_ACCESS_TOKEN") : process.env.TWITTER_ACCESS_TOKEN;
|
|
8782
|
+
const accessTokenSecret = hasGetSetting ? runtime.getSetting("TWITTER_ACCESS_TOKEN_SECRET") : process.env.TWITTER_ACCESS_TOKEN_SECRET;
|
|
8783
|
+
if (!apiKey || !apiSecretKey || !accessToken || !accessTokenSecret) {
|
|
8784
|
+
const missing = [];
|
|
8785
|
+
if (!apiKey) missing.push("TWITTER_API_KEY");
|
|
8786
|
+
if (!apiSecretKey) missing.push("TWITTER_API_SECRET_KEY");
|
|
8787
|
+
if (!accessToken) missing.push("TWITTER_ACCESS_TOKEN");
|
|
8788
|
+
if (!accessTokenSecret) missing.push("TWITTER_ACCESS_TOKEN_SECRET");
|
|
8789
|
+
logger10.warn(
|
|
8790
|
+
`Twitter API credentials not configured - Twitter functionality will be limited. Missing: ${missing.join(", ")}`
|
|
8791
|
+
);
|
|
8792
|
+
logger10.warn(
|
|
8793
|
+
"To enable Twitter functionality, please provide the missing credentials in your .env file"
|
|
8794
|
+
);
|
|
8795
|
+
} else {
|
|
8796
|
+
logger10.log("\u2705 Twitter credentials found");
|
|
8797
|
+
}
|
|
8798
|
+
}
|
|
8729
8799
|
};
|
|
8730
8800
|
var index_default = TwitterPlugin;
|
|
8731
8801
|
export {
|
|
8732
|
-
TwitterClientInstance,
|
|
8733
8802
|
TwitterPlugin,
|
|
8734
8803
|
index_default as default
|
|
8735
8804
|
};
|