WhiskeySockets / Baileys

Lightweight full-featured typescript/javascript WhatsApp Web API
https://baileys.whiskeysockets.io/
MIT License
3.64k stars 1.23k forks source link

[BUG] An internal server error occurred - unexpected error in 'init queries' #977

Open leroyanders opened 1 month ago

leroyanders commented 1 month ago
[Nest] 17736  - 08/12/2024, 1:38:16 PM     LOG [BaileysService, qJiKZMjixBZlqO7AAAAB] Reauthorizing WhatsApp session with ID user-id-1 of user ID 1 (admin@example.com) connected
{"level":30,"time":"2024-08-12T10:38:16.524Z","pid":17736,"hostname":"Leroys-MacBook-Air.local","browser":["Baileys","Chrome","4.0.0"],"helloMsg":{"clientHello":{"ephemeral":"Q4samJ+qxnF3aOxqNABwayDvpS9LFn+aohm8uup2AkI="}},"msg":"connected to WA Web"}
{"level":30,"time":"2024-08-12T10:38:16.686Z","pid":17736,"hostname":"Leroys-MacBook-Air.local","node":{"username":"380960994148","passive":true,"userAgent":{"platform":"WEB","appVersion":{"primary":2,"secondary":2413,"tertiary":1},"mcc":"000","mnc":"000","osVersion":"0.1","manufacturer":"","device":"Desktop","osBuildNumber":"0.1","releaseChannel":"RELEASE","localeLanguageIso6391":"en","localeCountryIso31661Alpha2":"US"},"webInfo":{"webSubPlatform":"WEB_BROWSER"},"connectType":"WIFI_UNKNOWN","connectReason":"USER_ACTIVATED","device":27},"msg":"logging in..."}
{"level":30,"time":"2024-08-12T10:38:17.042Z","pid":17736,"hostname":"Leroys-MacBook-Air.local","msg":"30 pre-keys found on server"}
{"level":30,"time":"2024-08-12T10:38:17.180Z","pid":17736,"hostname":"Leroys-MacBook-Air.local","msg":"opened connection to WA"}
{"level":30,"time":"2024-08-12T10:38:17.195Z","pid":17736,"hostname":"Leroys-MacBook-Air.local","msg":"handled 0 offline messages/notifications"}
{"level":50,"time":"2024-08-12T10:38:17.333Z","pid":17736,"hostname":"Leroys-MacBook-Air.local","trace":"Error: bad-request\n    at assertNodeErrorFree (/Users/leroyanders/WebstormProjects/thrivestate-whatsapp-service/node_modules/baileys/lib/WABinary/generic-utils.js:56:15)\n    at query (/Users/leroyanders/WebstormProjects/thrivestate-whatsapp-service/node_modules/baileys/lib/Socket/socket.js:128:48)\n    at processTicksAndRejections (node:internal/process/task_queues:95:5)\n    at fetchProps (/Users/leroyanders/WebstormProjects/thrivestate-whatsapp-service/node_modules/baileys/lib/Socket/chats.js:551:28)\n    at async Promise.all (index 1)\n    at executeInitQueries (/Users/leroyanders/WebstormProjects/thrivestate-whatsapp-service/node_modules/baileys/lib/Socket/chats.js:584:9)","output":{"statusCode":500,"payload":{"statusCode":500,"error":"Internal Server Error","message":"An internal server error occurred"},"headers":{}},"msg":"unexpected error in 'init queries'"}
[Nest] 17736  - 08/12/2024, 1:38:47 PM   ERROR [BaileysService, qJiKZMjixBZlqO7AAAAB] Timed Out
Error: Timed Out
    at /Users/leroyanders/WebstormProjects/thrivestate-whatsapp-service/node_modules/baileys/lib/Utils/generics.js:157:32

here's my code: `import { Injectable } from '@nestjs/common'; import { WsException } from '@nestjs/websockets'; import { User } from '@prisma/client'; import makeWASocket, { AuthenticationState, useMultiFileAuthState, DisconnectReason, ConnectionState, } from 'baileys'; import MAIN_LOGGER from 'baileys/lib/Utils/logger'; import { CustomLogger } from '../../../common/loggers'; import { handleException } from '../../../handlers'; import { MessageBuilder } from '../../../patterns/builders'; import { CloudStorageService } from '../../cloud-storage/services'; import { CreateAttachmentDto } from '../../websocket/dtos/attachment'; import { MessageDto, ReturnMessageDto } from '../../websocket/dtos'; import { ChatService, WebSocketService } from '../../websocket/services'; import { ServerWithEvents, SocketWithEvents } from '../../websocket/types'; import { AttachmentType, MessageWith, ReactionsType, ReplyType, } from '../../websocket/types/dtos'; import { Boom } from '@hapi/boom'; import { readyHandler } from '../handlers';

MAIN_LOGGER.child({}).level = 'silent';

@Injectable() export class BaileysService { private readonly logger = new CustomLogger(this.constructor.name); private clients: Map<string, any> = new Map(); private authStates: Map<string, AuthenticationState> = new Map(); static phoneNumberExtension = '@c.us';

private getClientId(userId: number): string { return user-id-${userId}; }

constructor( private readonly chatService: ChatService, private readonly cloudStorage: CloudStorageService, ) {}

private async reauthorizeClient( user: User, socket: SocketWithEvents, server: ServerWithEvents, ): Promise { const clientId = this.getClientId(user.id); const { state, saveCreds } = await useMultiFileAuthState( ./auth_info/${clientId}, );

const client = makeWASocket({
  version: [2, 2413, 1],
  auth: state,
  printQRInTerminal: true,
  defaultQueryTimeoutMs: 30000,
  syncFullHistory: true,
  retryRequestDelayMs: 30000,
  logger: MAIN_LOGGER,
  fireInitQueries: true,
});

this.logger.log(
  `Reauthorizing WhatsApp session with ID ${clientId} of user ID ${user.id} (${user.email}) connected`,
  socket.id,
);

client.ev.on('creds.update', saveCreds);

client.ev.on('connection.update', (update: Partial<ConnectionState>) => {
  const { connection, lastDisconnect, qr } = update;

  if (connection === 'close') {
    const shouldReconnect =
      (lastDisconnect.error as Boom)?.output?.statusCode !==
      DisconnectReason.loggedOut;

    if (shouldReconnect) {
      this.reauthorizeClient(user, socket, server);
    }
  } else if (connection === 'open') {
    this.clients.set(clientId, client);
    readyHandler.call(this, client, user, server, socket);
  } else if (qr) {
    this.logger.log(
      `QR code for websocket ID ${socket.id} of client ID ${clientId} (${user.email}) was generated successfully`,
      socket.id,
    );

    server
      .in(WebSocketService.getRoomNameFromUser(user))
      .emit('qr', { success: true, data: { qr } });
  }
});

client.ev.on('messages.upsert', async ({ messages, type }) => {
  // handle messages upsert
  if (type !== 'notify') return;

  for (const msg of messages) {
    try {
      this.logger.log(
        `Message from ${msg.key.remoteJid} was sent`,
        socket.id,
      );

      const messageBuilder = new MessageBuilder(msg);
      await messageBuilder.setRepliedMessage(msg);
      const messageWithReply = messageBuilder.getMessage();
      const messageDto = MessageDto.toDto(messageWithReply);

      server
        .in(WebSocketService.getRoomNameFromUser(user))
        .emit('message_created', {
          success: true,
          data: ReturnMessageDto.toDto(messageDto),
        });

      const { repliedMessage, ...rest } = messageWithReply;
      await this.chatService.handleSyncChat(
        user,
        {
          ...rest,
          repliedMessageId: repliedMessage?.key.id ?? null,
        },
        socket.id,
      );
    } catch (error) {
      await handleException({
        exception: error,
        server,
        client: socket,
        rooms: WebSocketService.getRoomNameFromUser(user),
        logger: this.logger,
      });
    }
  }
});

return client;

}

getClientByUserId(userId: number): any { const clientId = this.getClientId(userId); const client = this.clients.get(clientId);

if (!client)
  throw new WsException(
    `The session with client ID ${clientId} does not exist`,
  );

return client;

}

async createWhatsAppSession( socket: SocketWithEvents, user: User, server: ServerWithEvents, ): Promise { await this.reauthorizeClient(user, socket, server); }

async closeWhatsAppSession( user: User, socket: SocketWithEvents, ): Promise { const clientId = this.getClientId(user.id); const clientToClose = this.clients.get(clientId);

if (!clientToClose)
  throw new WsException(`The session with ID '${clientId}' not found`);

const state = this.authStates.get(clientId);

if (state) {
  state.creds = null;
  state.keys = { ...state.keys };
}

this.clients.delete(clientId);
this.authStates.delete(clientId);

this.logger.log(
  `WhatsApp of ID=${user.id} (${user.email}) disconnected`,
  socket.id,
);

}

async isRegisteredWAUser( userId: number, phoneNumber: string, ): Promise { const client = this.getClientByUserId(userId); const [result] = await client.onWhatsApp(phoneNumber);

return !!result.exists;

}

async getWAContactByPhoneNumber( userId: number, phoneNumber: string, ): Promise<string | null> { const client = this.getClientByUserId(userId); const [result] = await client.onWhatsApp(phoneNumber);

return result ? result.jid : null;

}

async sendMessage( userId: number, whatsappChatId: string, messageBody: string, createAttachmentDto?: CreateAttachmentDto, ): Promise { const client = this.getClientByUserId(userId); await this.isChatIdValid(whatsappChatId, userId);

const mediaAttachment:
  | {
      data: string;
      size: number;
      name?: string;
      type: string;
      sendAsDocument: boolean;
    }
  | NonNullable<unknown> = createAttachmentDto
  ? { ...createAttachmentDto }
  : {};

await client.sendMessage(whatsappChatId, {
  text: messageBody,
  ...mediaAttachment,
});

}

async replyToMessage( userId: number, repliedMessageId: string, whatsappChatId: string, messageBody: string, createAttachmentDto?: CreateAttachmentDto, ): Promise { await this.isChatIdValid(whatsappChatId, userId);

const mediaAttachment:
  | {
      data: string;
      size: number;
      name?: string;
      type: string;
      sendAsDocument: boolean;
    }
  | NonNullable<unknown> = createAttachmentDto
  ? { ...createAttachmentDto }
  : {};

const client = this.getClientByUserId(userId);
await client.sendMessage(whatsappChatId, {
  text: messageBody,
  quoted: { key: { id: repliedMessageId } },
  ...mediaAttachment,
});

}

async getContactsByUserId(userId: number): Promise { const client = this.getClientByUserId(userId); return await client.getContacts(); }

async getChatsByUserId(userId: number, contactId: string): Promise<any[]> { const client = this.getClientByUserId(userId); const chats = await client.getChats();

return chats.filter(
  (chat: any) => !chat.archive && chat.jid !== contactId && !chat.isGroup,
);

}

async getChatById(userId: number, whatsappChatId: string): Promise { const client = this.getClientByUserId(userId); return await client.getChat(whatsappChatId); }

async getMessagesFromChat(chat: any): Promise<any[]> { return await chat.messages; }

async ensureClientConnected(userId: number): Promise { const client = this.getClientByUserId(userId);

if (!client || !client.authState.creds.me) {
  throw new WsException(`Client not connected for user ${userId}`);
}

}

async getMessageById(userId: number, id: string): Promise { await this.ensureClientConnected(userId); const client = this.getClientByUserId(userId);

try {
  const messages = await client.loadMessageFromWA(id);

  if (!messages.length) {
    this.logger.error(`Message with id ${id} not found for user ${userId}`);
    return new WsException(`Message with id ${id} not found`);
  }

  return messages[0];
} catch (error) {
  this.logger.error(
    `Error fetching message with id ${id} for user ${userId}: ${error.message}`,
  );
  throw new WsException(
    `Error fetching message with id ${id}: ${error.message}`,
  );
}

}

async getContactByUserId(userId: number): Promise { const client = this.getClientByUserId(userId); return await client.getContact(client.user.jid); }

async sendChatSeen(userId: number, whatsappChatId: string) { const client = this.getClientByUserId(userId); await client.sendReadReceipt(whatsappChatId); }

async editMessage( messageId: string, newBody: string, userId: number, ): Promise { const message = await this.getMessageById(userId, messageId); await message.edit(newBody); }

async setAttachmentReactionAndReply( message: any, ): Promise<MessageWith<AttachmentType & ReactionsType & ReplyType>> { const messageBuilder = new MessageBuilder(message);

await (
  await (
    await messageBuilder.setAttachment(this.cloudStorage, message)
  ).setReaction(message)
).setRepliedMessage(message);

return messageBuilder.getMessage();

}

async reactToMessage( messageId: string, userId: number, reaction: string, ): Promise { const client = this.getClientByUserId(userId); await client.sendMessage(messageId, { react: { text: reaction }, }); }

async deleteMessage(messageId: string, userId: number): Promise { const client = this.getClientByUserId(userId); await client.sendMessage(messageId, { delete: true }); }

async isChatIdValid(chatId: string, userId: number): Promise { const client = this.getClientByUserId(userId); const [result] = await client.onWhatsApp(chatId);

if (!result.exists) {
  throw new WsException(
    `The chat ID ${chatId} is invalid or doesn't exist in WhatsApp`,
  );
}

} } `

gmatisa commented 3 weeks ago

Started getting this error too (JSON is formatted for readability):

{
  "level": 50,
  "time": "2024-08-18T22:19:26.098Z",
  "pid": 1753026,
  "hostname": "XXXXX",
  "err": {
    "type": "Error",
    "message": "bad-request",
    "stack": "Error: bad-request\n    at assertNodeErrorFree (/home/ubuntu/projects/Baileys2/src/WABinary/generic-utils.ts:55:9)\n    at query (/home/ubuntu/projects/Baileys2/src/Socket/socket.ts:180:23)\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n    at async fetchProps (/home/ubuntu/projects/Baileys2/src/Socket/chats.ts:742:22)\n    at async Promise.all (index 1)\n    at async executeInitQueries (/home/ubuntu/projects/Baileys2/src/Socket/chats.ts:827:3)",
    "data": 400,
    "isBoom": true,
    "isServer": true,
    "output": {
      "statusCode": 500,
      "payload": {
        "statusCode": 500,
        "error": "Internal Server Error",
        "message": "An internal server error occurred"
      },
      "headers": {}
    }
  },
  "msg": "unexpected error in 'init queries'"
}