Skip to content

Commit

Permalink
feat: remove a bunch of features and focus on bridging; prepare for m…
Browse files Browse the repository at this point in the history
…atrix self-puppeting support
  • Loading branch information
rikumi committed Oct 22, 2024
1 parent 165a5a1 commit d912327
Show file tree
Hide file tree
Showing 20 changed files with 62 additions and 674 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@ config.test.json
*.db
*.db-journal
package-lock.json
database/search_imports/*
!database/search_imports/README.md
matrix-bot-storage.json
5 changes: 2 additions & 3 deletions config.example.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
{
"telegramBotToken": "",
"openaiApiKey": "",
"xhsWebId": "",
"xhsWebSession": "",
"discordUserToken": "",
"discordUsername": "rikumi_tietie_bot",
"botUsername": "rikumi_tietie_bot",
"matrixUsername": "rikumi_tietie_bot",
"matrixHomeServer": "matrix.org",
"matrixAccessToken": "",
"serverRoot": "example.com"
"serverRoot": "example.com",
"serverPort": 8383
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"start": "pm2 start --name tietie --interpreter tsx src/index.ts",
"restart": "pm2 restart tietie",
"stop": "pm2 stop tietie",
"migrate": "npm run stop; tsx database/search_migration.ts; npm run start",
"ts-check": "tsc --noEmit",
"dev": "tsx --inspect src/index.ts",
"matrix:login": "tsx src/scripts/matrix_login.ts",
"format": "prettier --write ."
Expand Down
16 changes: 7 additions & 9 deletions src/clients/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ export interface GenericMessage {
clientName: string;
text: string;
userId: string;
userHandle: string;
userDisplayName: string;
userHandle?: string;
userDisplayName?: string;
userLink?: string;
chatId: string;
messageId: string;
mediaMessageId?: string;
unixDate: number;
unixDate?: number;

media?: GenericMedia;
entities?: GenericMessageEntity[];
Expand All @@ -21,7 +21,8 @@ export interface GenericMessage {
userLinkReplied?: string;
disableBridging?: boolean;

rawMessage: any;
platformMessage?: any;
bridgedMessage?: GenericMessage;
}

export interface GenericMedia {
Expand Down Expand Up @@ -62,12 +63,9 @@ export interface MessageToSend {
chatId: string;
media?: GenericMedia;
messageIdReplied?: string;
rawMessage?: any;
rawMessageExtra?: any;
platformMessageExtra?: any;
bridgedMessage?: GenericMessage;
entities?: GenericMessageEntity[];
rawUserId?: string;
rawUserHandle?: string;
rawUserDisplayName?: string;
}

export interface MessageToEdit extends MessageToSend {
Expand Down
12 changes: 6 additions & 6 deletions src/clients/discord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,20 @@ export class DiscordUserBotClient extends EventEmitter implements GenericClient
}

public async sendMessage(message: MessageToSend): Promise<GenericMessage> {
if (message.rawUserDisplayName) {
prependMessageText(message, `${message.rawUserHandle}: `); // use handles for discord only
if (message.bridgedMessage?.userDisplayName) {
prependMessageText(message, `${message.bridgedMessage.userHandle}: `); // use handles for discord only
}
const messageSent = await this.bot.send(message.chatId, {
content: `${message.text} ${message.media?.url ?? ''}`.trim(),
reply: message.messageIdReplied ?? null,
...message.rawMessageExtra ?? {},
...message.platformMessageExtra ?? {},
});
return this.transformMessage(messageSent);
}

public async editMessage(message: MessageToEdit): Promise<void> {
if (message.rawUserDisplayName) {
prependMessageText(message, `${message.rawUserHandle}: `); // use handles for discord only
if (message.bridgedMessage?.userDisplayName) {
prependMessageText(message, `${message.bridgedMessage.userHandle}: `); // use handles for discord only
}
await this.bot.edit(message.messageId, message.chatId, `${message.text} ${message.media?.url ?? ''}`.trim());
}
Expand Down Expand Up @@ -120,7 +120,7 @@ export class DiscordUserBotClient extends EventEmitter implements GenericClient
messageIdReplied: message.referenced_message?.id,
messageReplied: message.referenced_message && this.transformMessage(message.referenced_message),
userIdReplied: message.referenced_message?.author?.id,
rawMessage: message,
platformMessage: message,
unixDate: Math.floor(new Date(message.timestamp).getTime() / 1000),
isServiceMessage: !!message.author?.bot,
}
Expand Down
28 changes: 14 additions & 14 deletions src/clients/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getBridgeNickname, getUnidirectionalBridgesByChat } from 'src/database/bridge';
import type { GenericClient, GenericMessage, GenericMessageEntity, MessageToEdit, MessageToSend } from './base';
import { getUnidirectionalBridgesByChat } from 'src/database/bridge';
import type { GenericClient, GenericMessage, MessageToEdit, MessageToSend } from './base';
import { EventEmitter } from 'events';

export const prependMessageText = (message: Pick<GenericMessage, 'text' | 'entities'>, prefix: string) => {
Expand All @@ -24,7 +24,6 @@ export class DefaultClientSet extends EventEmitter {

public async bridgeMessage(fromMessage: GenericMessage & MessageToSend): Promise<GenericMessage[]> {
if (fromMessage.disableBridging) return [];
const userNick = (await getBridgeNickname(fromMessage.clientName, fromMessage.chatId, fromMessage.userId)) || fromMessage.userDisplayName;
const hasCommand = /^\/\w+\b/.test(fromMessage.text);
const rawText = fromMessage.text;
const bridges = await getUnidirectionalBridgesByChat(fromMessage.clientName, fromMessage.chatId);
Expand All @@ -41,12 +40,12 @@ export class DefaultClientSet extends EventEmitter {
chatId: toChatId,
media: fromMessage.media,
messageIdReplied: toMessageIdReplied,
rawMessage: fromMessage.rawMessage,
bridgedMessage: {
...fromMessage,
userHandle: !fromMessage.isServiceMessage && fromMessage.userHandle || '',
userDisplayName: !fromMessage.isServiceMessage && fromMessage.userDisplayName || '',
},
entities: fromMessage.entities,
rawMessageExtra: fromMessage.rawMessageExtra,
rawUserId: fromMessage.isServiceMessage ? undefined : fromMessage.userId,
rawUserHandle: fromMessage.isServiceMessage ? undefined : fromMessage.userHandle,
rawUserDisplayName: fromMessage.isServiceMessage ? undefined : userNick,
});
// build bidirectional message id mapping
this.recordRecentMessageId(fromMessage.clientName, fromMessage.chatId, fromMessage.messageId, toClientName, toChatId, toMessage.messageId, toMessage.mediaMessageId);
Expand All @@ -62,8 +61,7 @@ export class DefaultClientSet extends EventEmitter {
return results.filter(Boolean) as GenericMessage[];
}

public async bridgeEditedMessage(fromMessage: MessageToEdit): Promise<void> {
const userNick = fromMessage.userId && (await getBridgeNickname(fromMessage.clientName, fromMessage.chatId, fromMessage.userId)) || fromMessage.userDisplayName;
public async bridgeEditedMessage(fromMessage: GenericMessage & MessageToEdit): Promise<void> {
const bridges = await getUnidirectionalBridgesByChat(fromMessage.clientName, fromMessage.chatId);
await Promise.all(bridges.map(async ({ toClient: toClientName, toChatId }) => {
const toClient = this.clients.get(toClientName);
Expand All @@ -79,8 +77,11 @@ export class DefaultClientSet extends EventEmitter {
text: fromMessage.text,
media: fromMessage.media,
entities: fromMessage.entities,
rawUserHandle: fromMessage.isServiceMessage ? undefined : fromMessage.userHandle,
rawUserDisplayName: fromMessage.isServiceMessage ? undefined : userNick,
bridgedMessage: {
...fromMessage,
userHandle: fromMessage.isServiceMessage ? undefined : fromMessage.userHandle,
userDisplayName: fromMessage.isServiceMessage ? undefined : fromMessage.userDisplayName,
},
});
}));
}
Expand All @@ -92,7 +93,6 @@ export class DefaultClientSet extends EventEmitter {
const messagesBridged = await this.bridgeMessage({
...messageSent,
isServiceMessage: true,
rawMessageExtra: message.rawMessageExtra,
});
return [messageSent, ...messagesBridged];
}
Expand All @@ -105,7 +105,7 @@ export class DefaultClientSet extends EventEmitter {
return [messageSent, ...messagesBridged];
}

public async editBotMessage(message: MessageToEdit) {
public async editBotMessage(message: GenericMessage & MessageToEdit) {
const client = this.clients.get(message.clientName);
if (!client) return;
await client.editMessage(message);
Expand Down
12 changes: 6 additions & 6 deletions src/clients/matrix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ export class MatrixUserBotClient extends EventEmitter implements GenericClient<a
};

public async sendMessage(message: MessageToSend): Promise<GenericMessage> {
if (message.rawUserDisplayName) {
prependMessageText(message, `${message.rawUserDisplayName}: `);
if (message.bridgedMessage?.userDisplayName) {
prependMessageText(message, `${message.bridgedMessage.userDisplayName}: `);
}
const matrixEventContent: any = {
body: message.text,
Expand Down Expand Up @@ -94,14 +94,14 @@ export class MatrixUserBotClient extends EventEmitter implements GenericClient<a
userId: this.botInfo!.user_id,
userHandle: this.botInfo!.user_id,
userDisplayName: this.botInfo!.user_id,
rawMessage: { id: messageId, content: message.text },
platformMessage: { id: messageId, content: message.text },
unixDate: Math.floor(Date.now() / 1000),
};
}

public async editMessage(message: MessageToEdit): Promise<void> {
if (message.rawUserDisplayName) {
prependMessageText(message, `${message.rawUserDisplayName}: `);
if (message.bridgedMessage?.userDisplayName) {
prependMessageText(message, `${message.bridgedMessage?.userDisplayName}: `);
}
if (message.media && message.mediaMessageId) {
const isSticker = message.media.type === 'sticker';
Expand Down Expand Up @@ -170,7 +170,7 @@ export class MatrixUserBotClient extends EventEmitter implements GenericClient<a
messageReplied: repliedMessage?.content?.['mx.rkm.tietie-bot.message'],
userIdReplied: repliedMessage?.sender,
userNameReplied: repliedMessageId && repliedUser?.displayname,
rawMessage: message,
platformMessage: message,
unixDate: Math.floor(message.origin_server_ts / 1000),
}
}
Expand Down
20 changes: 10 additions & 10 deletions src/clients/telegram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ export class TelegramBotClient extends EventEmitter implements GenericClient<Mes
}

public async sendMessage(message: MessageToSend): Promise<GenericMessage> {
const bot = message.rawUserId ? await this.getBotForUser(message.rawUserId, message.chatId) : this.bot;
if (message.rawUserDisplayName && bot === this.bot) {
prependMessageText(message, `${message.rawUserDisplayName}: `);
const bot = message.bridgedMessage?.userId ? await this.getBotForUser(message.bridgedMessage.clientName, message.bridgedMessage.userId, message.chatId) : this.bot;
if (message.bridgedMessage?.userDisplayName && bot === this.bot) {
prependMessageText(message, `${message.bridgedMessage.userDisplayName}: `);
}
const method = ({
sticker: 'sendSticker',
Expand All @@ -90,7 +90,7 @@ export class TelegramBotClient extends EventEmitter implements GenericClient<Mes
caption: message.media ? message.text : undefined,
[message.media ? 'caption_entities' : 'entities']: entities,
disable_notification: true,
...message.rawMessageExtra ?? {},
...message.platformMessageExtra ?? {},
};
const firstMessageContent = message.media?.telegramFileId ?? message.media?.url ?? message.text;

Expand All @@ -111,8 +111,8 @@ export class TelegramBotClient extends EventEmitter implements GenericClient<Mes
}

public async editMessage(message: MessageToEdit): Promise<void> {
if (message.rawUserDisplayName) {
prependMessageText(message, `${message.rawUserDisplayName}: `);
if (message.bridgedMessage?.userDisplayName) {
prependMessageText(message, `${message.bridgedMessage.userDisplayName}: `);
}
const entities = message.entities?.map(entity => ({
type: entity.type.replace(/^(link|mention)$/, 'text_link') as any,
Expand Down Expand Up @@ -155,7 +155,7 @@ export class TelegramBotClient extends EventEmitter implements GenericClient<Mes
userIdReplied: 'reply_to_message' in message && String(message.reply_to_message?.from?.id ?? '') || undefined,
userNameReplied: 'reply_to_message' in message && this.getUserDisplayName(message.reply_to_message?.from) || undefined,
userLinkReplied: 'reply_to_message' in message && this.getUserLink(message.reply_to_message?.from) || undefined,
rawMessage: message,
platformMessage: message,
unixDate: message.date,
entities: 'entities' in message && message.entities?.map((e) => this.transformEntity(e, text)).filter(Boolean) as any[] || undefined
};
Expand Down Expand Up @@ -277,12 +277,12 @@ export class TelegramBotClient extends EventEmitter implements GenericClient<Mes
}
}

private async getBotForUser(userId: string, chatId: string) {
const puppetBotToken = await getPuppet(userId);
private async getBotForUser(fromClient: string, fromUserId: string, chatId: string) {
const puppetBotToken = await getPuppet(fromClient, fromUserId, 'telegram');
if (!puppetBotToken) {
return this.bot;
}
const key = `${userId}:${chatId}`;
const key = `${fromUserId}:${chatId}`;
if (!this.botPuppetMap.has(key)) {
const bot = new Telegraf(puppetBotToken);
try {
Expand Down
18 changes: 0 additions & 18 deletions src/commands/nick.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/commands/puppet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export const handleSlashCommand = async (message: GenericMessage) => {
return `用法: /puppet ${USAGE}`;
}
if (token === 'clear') {
await delPuppet(message.userId);
await delPuppet(message.clientName, message.userId, 'telegram');
return 'OK';
}
await setPuppet(message.userId, token);
await setPuppet(message.clientName, message.userId, 'telegram', token);
return 'OK';
}
Loading

0 comments on commit d912327

Please sign in to comment.