whatsapp-claude-gpt
Version:
WhatsApp-Claude-GPT is a WhatsApp chatbot that supports multiple AI providers for chat, optional image generation/editing, and voice (speech-to-text and text-to-speech). It’s built for natural, contextual conversations and can now also handle reminders an
127 lines (111 loc) • 4.26 kB
text/typescript
import { db } from '../db';
import { chatConfigsTable } from '../db/schema';
import { eq } from 'drizzle-orm';
import * as fs from 'fs';
import * as path from 'path';
import logger from '../logger';
import { CONFIG } from './index';
import WspWeb from "../bot/wsp-web";
const OLD_CHATCONFIG_FILE = path.join(process.cwd(), 'chat-configurations.json');
export interface ChatConfiguration {
chatId: string;
name: string;
promptInfo: string;
isGroup: boolean;
botName?: string;
maxMsgsLimit?: number;
maxHoursLimit?: number;
}
class ChatConfig {
constructor() {
this.migrateFromJsonIfNeeded();
}
private async migrateFromJsonIfNeeded() {
if (fs.existsSync(OLD_CHATCONFIG_FILE)) {
logger.info('[ChatConfig] Migrating old JSON data to DB...');
const jsonConfigs: (Partial<ChatConfiguration> & { id: string })[] = JSON.parse(fs.readFileSync(OLD_CHATCONFIG_FILE, 'utf8'));
for (const oldConfig of jsonConfigs) {
const existing = await db.select().from(chatConfigsTable).where(eq(chatConfigsTable.chatId, oldConfig.id)).get();
if (!existing) {
await db.insert(chatConfigsTable).values({
chatId: oldConfig.id,
name: oldConfig.name,
promptInfo: oldConfig.promptInfo,
botName: oldConfig.botName,
isGroup: oldConfig.isGroup,
maxMsgsLimit: oldConfig.maxMsgsLimit,
maxHoursLimit: oldConfig.maxHoursLimit,
}).run();
}
}
fs.unlinkSync(OLD_CHATCONFIG_FILE);
logger.info('[ChatConfig] Migration completed and JSON file deleted');
}
}
private async withDefaults(partial: Partial<ChatConfiguration>, chatId: string): Promise<ChatConfiguration> {
const chat = await WspWeb.getWspClient().getChatById(chatId);
const base: ChatConfiguration = {
chatId,
name: chat.name || '<Unnamed>',
isGroup: chat.isGroup,
promptInfo: CONFIG.BotConfig.promptInfo,
botName: CONFIG.BotConfig.botName,
maxMsgsLimit: CONFIG.BotConfig.maxMsgsLimit,
maxHoursLimit: CONFIG.BotConfig.maxHoursLimit,
};
const result = { ...base };
for (const key in partial) {
const value = partial[key as keyof ChatConfiguration];
if (value !== null && value !== undefined) {
(result as any)[key] = value;
}
}
return result;
}
public async getChatConfig(chatId: string, chatName: string): Promise<ChatConfiguration> {
const found = await db.select().from(chatConfigsTable).where(eq(chatConfigsTable.chatId, chatId)).get();
return await this.withDefaults(found || {}, chatId);
}
public async updateChatConfig(
chatId: string,
chatName: string,
isGroup: boolean,
options: {
promptInfo?: string;
botName?: string;
maxMsgsLimit?: number;
maxHoursLimit?: number;
}
): Promise<ChatConfiguration> {
const current = await db.select().from(chatConfigsTable).where(eq(chatConfigsTable.chatId, chatId)).get();
const merged = await this.withDefaults({
...current,
chatId: chatId,
name: chatName,
isGroup,
...(options.promptInfo !== undefined ? { promptInfo: options.promptInfo } : {}),
...(options.botName !== undefined ? { botName: options.botName } : {}),
...(options.maxMsgsLimit !== undefined ? { maxMsgsLimit: options.maxMsgsLimit } : {}),
...(options.maxHoursLimit !== undefined ? { maxHoursLimit: options.maxHoursLimit } : {})
}, chatId);
if (current) {
await db.update(chatConfigsTable)
.set(merged)
.where(eq(chatConfigsTable.chatId, chatId))
.run();
} else {
await db.insert(chatConfigsTable).values(merged).run();
}
logger.info(`Updated configuration for ${isGroup ? 'group' : 'chat'} ${chatName} (${chatId})`);
return merged;
}
public async removeChatConfig(chatId: string): Promise<boolean> {
const result = await db.delete(chatConfigsTable).where(eq(chatConfigsTable.chatId, chatId)).run();
const removed = result.changes > 0;
if (removed) {
logger.info(`Removed configuration for chat ${chatId}`);
}
return removed;
}
}
export const chatConfigurationManager = new ChatConfig();