Skip to content

Commit 9ac6f3b

Browse files
authored
Merge pull request elizaOS#957 from azep-ninja/discord-telegram-team-agents-and-optimizations
feat: Updated characters types, Discord & Telegram enhancements
2 parents b841009 + 6d3253f commit 9ac6f3b

File tree

5 files changed

+101
-7
lines changed

5 files changed

+101
-7
lines changed

packages/client-discord/src/messages.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,27 @@ export class MessageManager {
507507
}
508508
}
509509

510+
private _isMessageForMe(message: DiscordMessage): boolean {
511+
const isMentioned = message.mentions.users?.has(this.client.user?.id as string);
512+
const guild = message.guild;
513+
const member = guild?.members.cache.get(this.client.user?.id as string);
514+
const nickname = member?.nickname;
515+
const memberId = member?.id;
516+
517+
// Don't consider role mentions as direct mentions
518+
const hasRoleMentionOnly = message.mentions.roles.size > 0 && !isMentioned;
519+
520+
// If it's only a role mention and we're in team mode, let team logic handle it
521+
if (hasRoleMentionOnly && this.runtime.character.clientConfig?.discord?.isPartOfTeam) {
522+
return false;
523+
}
524+
525+
return isMentioned || (!this.runtime.character.clientConfig?.discord?.shouldRespondOnlyToMentions && (
526+
message.content.toLowerCase().includes(this.client.user?.username.toLowerCase() as string) ||
527+
message.content.toLowerCase().includes(this.client.user?.tag.toLowerCase() as string) ||
528+
(nickname && message.content.toLowerCase().includes(nickname.toLowerCase()))));
529+
}
530+
510531
async processMessageMedia(
511532
message: DiscordMessage
512533
): Promise<{ processedContent: string; attachments: Media[] }> {
@@ -1197,7 +1218,7 @@ export class MessageManager {
11971218
return false;
11981219
}
11991220
}
1200-
1221+
12011222
if (message.mentions.has(this.client.user?.id as string)) return true;
12021223

12031224
const guild = message.guild;
@@ -1307,4 +1328,4 @@ export class MessageManager {
13071328
const data = await response.json();
13081329
return data.username;
13091330
}
1310-
}
1331+
}

packages/client-discord/src/utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -297,4 +297,4 @@ export function cosineSimilarity(text1: string, text2: string, text3?: string):
297297
);
298298

299299
return dotProduct / maxMagnitude;
300-
}
300+
}

packages/client-telegram/src/messageManager.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,22 @@ export class MessageManager {
360360
return true;
361361
}
362362

363+
private _isMessageForMe(message: Message): boolean {
364+
const botUsername = this.bot.botInfo?.username;
365+
if (!botUsername) return false;
366+
367+
const messageText = 'text' in message ? message.text :
368+
'caption' in message ? (message as any).caption : '';
369+
if (!messageText) return false;
370+
371+
const isReplyToBot = (message as any).reply_to_message?.from?.is_bot === true &&
372+
(message as any).reply_to_message?.from?.username === botUsername;
373+
const isMentioned = messageText.includes(`@${botUsername}`);
374+
const hasUsername = messageText.toLowerCase().includes(botUsername.toLowerCase());
375+
376+
return isReplyToBot || isMentioned || (!this.runtime.character.clientConfig?.telegram?.shouldRespondOnlyToMentions && hasUsername);
377+
}
378+
363379
// Process image messages and generate descriptions
364380
private async processImage(
365381
message: Message
@@ -406,7 +422,7 @@ export class MessageManager {
406422
message: Message,
407423
state: State
408424
): Promise<boolean> {
409-
425+
410426
if (this.runtime.character.clientConfig?.telegram?.shouldRespondOnlyToMentions) {
411427
return this._isMessageForMe(message);
412428
}

packages/client-telegram/src/telegramClient.ts

+55-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Context, Telegraf } from "telegraf";
2+
import { message } from 'telegraf/filters';
23
import { IAgentRuntime, elizaLogger } from "@ai16z/eliza";
34
import { MessageManager } from "./messageManager.ts";
45
import { getOrCreateRecommenderInBe } from "./getOrCreateRecommenderInBe.ts";
@@ -47,11 +48,56 @@ export class TelegramClient {
4748
this.messageManager.bot = this.bot;
4849
}
4950

51+
private async isGroupAuthorized(ctx: Context): Promise<boolean> {
52+
const config = this.runtime.character.clientConfig?.telegram;
53+
if (ctx.from?.id === ctx.botInfo?.id) {
54+
return false;
55+
}
56+
57+
if (!config?.shouldOnlyJoinInAllowedGroups) {
58+
return true;
59+
}
60+
61+
const allowedGroups = config.allowedGroupIds || [];
62+
const currentGroupId = ctx.chat.id.toString();
63+
64+
if (!allowedGroups.includes(currentGroupId)) {
65+
elizaLogger.info(`Unauthorized group detected: ${currentGroupId}`);
66+
try {
67+
await ctx.reply("Not authorized. Leaving.");
68+
await ctx.leaveChat();
69+
} catch (error) {
70+
elizaLogger.error(`Error leaving unauthorized group ${currentGroupId}:`, error);
71+
}
72+
return false;
73+
}
74+
75+
return true;
76+
}
77+
5078
private setupMessageHandlers(): void {
5179
elizaLogger.log("Setting up message handler...");
5280

81+
this.bot.on(message('new_chat_members'), async (ctx) => {
82+
try {
83+
const newMembers = ctx.message.new_chat_members;
84+
const isBotAdded = newMembers.some(member => member.id === ctx.botInfo.id);
85+
86+
if (isBotAdded && !(await this.isGroupAuthorized(ctx))) {
87+
return;
88+
}
89+
} catch (error) {
90+
elizaLogger.error("Error handling new chat members:", error);
91+
}
92+
});
93+
5394
this.bot.on("message", async (ctx) => {
5495
try {
96+
// Check group authorization first
97+
if (!(await this.isGroupAuthorized(ctx))) {
98+
return;
99+
}
100+
55101
if (this.tgTrader) {
56102
const userId = ctx.from?.id.toString();
57103
const username =
@@ -76,12 +122,18 @@ export class TelegramClient {
76122
);
77123
}
78124
}
125+
79126
await this.messageManager.handleMessage(ctx);
80127
} catch (error) {
81128
elizaLogger.error("❌ Error handling message:", error);
82-
await ctx.reply(
83-
"An error occurred while processing your message."
84-
);
129+
// Don't try to reply if we've left the group or been kicked
130+
if (error?.response?.error_code !== 403) {
131+
try {
132+
await ctx.reply("An error occurred while processing your message.");
133+
} catch (replyError) {
134+
elizaLogger.error("Failed to send error message:", replyError);
135+
}
136+
}
85137
}
86138
});
87139

packages/core/src/types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ export type Character = {
731731
discord?: {
732732
shouldIgnoreBotMessages?: boolean;
733733
shouldIgnoreDirectMessages?: boolean;
734+
shouldRespondOnlyToMentions?: boolean;
734735
messageSimilarityThreshold?: number;
735736
isPartOfTeam?: boolean;
736737
teamAgentIds?: string[];
@@ -740,6 +741,9 @@ export type Character = {
740741
telegram?: {
741742
shouldIgnoreBotMessages?: boolean;
742743
shouldIgnoreDirectMessages?: boolean;
744+
shouldRespondOnlyToMentions?: boolean;
745+
shouldOnlyJoinInAllowedGroups?: boolean;
746+
allowedGroupIds?: string[];
743747
messageSimilarityThreshold?: number;
744748
isPartOfTeam?: boolean;
745749
teamAgentIds?: string[];
@@ -749,6 +753,7 @@ export type Character = {
749753
slack?: {
750754
shouldIgnoreBotMessages?: boolean;
751755
shouldIgnoreDirectMessages?: boolean;
756+
752757
};
753758
};
754759

0 commit comments

Comments
 (0)