|
- require("dotenv").config();
- const { DisconnectReason } = require("@whiskeysockets/baileys");
- const makeWASocket = require("@whiskeysockets/baileys").default;
- const express = require("express");
- const app = express();
- const { Server } = require("socket.io");
- const http = require("http");
- const cors = require("cors");
- const qrCode = require("qrcode");
- const mongoConnection = require("./db/dbConnect");
- const cookieParser = require("cookie-parser");
- const bcrypt = require("bcryptjs");
- const User = require("./models/user");
- const path = require("path");
- const { signAccessToken, verifyAccessToken } = require("./helper/jwt_helper");
- const {
- createSignUpValidation,
- createSignInValidation,
- } = require("./validation/user.validity");
- const MyError = require("./config/error");
- const useMongoDBAuthState = require("./auth/mongoAuthState");
- const { MongoClient } = require("mongodb");
-
- mongoConnection();
- app.use(cookieParser());
- app.use(express.urlencoded({ extended: false }));
- app.use(express.json());
- app.use(express.static(path.join(__dirname, "client", "dist")));
-
- const server = http.createServer(app);
- const io = new Server(server, {
- cors: "http://localhost:3000",
- });
-
- const mongoClient = new MongoClient(process.env.mongodb_url, {
- useNewUrlParser: true,
- useUnifiedTopology: true,
- });
- mongoClient.connect().then(() => console.log("mongoClient connected"));
-
- const sock = {};
-
- // Function to set a global variable for a specific ID
- function setSock(id, value) {
- sock[id] = value;
- }
-
- let groupMessageEventListener;
- let connectionUpdateListener;
-
- async function generateQRCode(data) {
- return new Promise((resolve, reject) => {
- qrCode.toDataURL(data, (err, url) => {
- if (err) {
- reject(err);
- } else {
- resolve(url);
- }
- });
- });
- }
-
- async function connectionLogic(id, socket, isError) {
- // const { state, saveCreds } = await useMultiFileAuthState("auth_info_baileys");
- const user = await User.findById(id);
- console.log(user);
-
- const collection = mongoClient
- .db("whatsapp_api")
- .collection(`auth_info_${id}`);
-
- const chatsCollection = mongoClient
- .db("whatsapp_chats")
- .collection(`all_chats_${id}`);
-
- const { state, saveCreds } = await useMongoDBAuthState(collection);
-
- try {
- if (isError || user.isLogged === false) {
- let sock = makeWASocket({
- printQRInTerminal: true,
- auth: state,
- });
- setSock(id, sock);
- } else {
- sock[id].ev.off("messages.upsert", groupMessageEventListener);
- sock[id].ev.off("connection.update", connectionUpdateListener);
- }
- } catch (error) {
- console.error(error);
- }
-
- connectionUpdateListener = async (update) => {
- const { connection, lastDisconnect } = update;
- if (!connection && update?.qr) {
- const qrCodeDataURL = await generateQRCode(update.qr);
- console.log("QR created");
- socket.emit("qrCode", qrCodeDataURL);
- }
-
- if (connection === "close") {
- const shouldReconnect =
- lastDisconnect?.error?.output?.statusCode !==
- DisconnectReason.loggedOut;
- console.log(
- "connection closed due to ",
- lastDisconnect.error,
- ", reconnecting ",
- shouldReconnect
- );
-
- if (
- lastDisconnect.error?.output?.statusCode === DisconnectReason.loggedOut
- ) {
- console.log("User logged out Rereun the connection");
- // Handle user logout, perform cleanup, or redirect as needed
- await mongoClient.db("whatsapp_api").dropCollection(`auth_info_${id}`);
- user.isLogged = false;
- await user.save();
- socket.emit("user disconnected");
- }
-
- // if (lastDisconnect.error?.output?.statusCode === 440) {
- // await mongoClient.db("whatsapp_api").dropCollection(`auth_info_${id}`);
- // connectionLogic(id, socket);
- // }
-
- if (shouldReconnect) {
- connectionLogic(id, socket, true);
- }
- } else if (connection === "open") {
- console.log("opened connection");
- user.isLogged = true;
- await user.save();
- socket.emit("user connected");
- }
- };
-
- groupMessageEventListener = async (messageInfoUpsert) => {
- if (
- messageInfoUpsert.messages[0].key.remoteJid.split("@")[1] === "g.us" &&
- messageInfoUpsert.messages[0].message?.conversation
- ) {
- const user = await User.findById(id);
- const tags = user.tags;
- const newMessage = messageInfoUpsert.messages[0].message?.conversation;
- const isRequiredMessage =
- tags.length === 0
- ? true
- : tags.reduce((accum, curr) => {
- if (accum) return accum;
- else {
- const regex = new RegExp(curr, "i");
- console.log(accum, curr, newMessage);
- console.log(regex.test(newMessage));
- return regex.test(newMessage);
- }
- }, false);
- console.log(isRequiredMessage);
- const newGrpMessage = {
- conversation: messageInfoUpsert.messages[0].message?.conversation,
- username: messageInfoUpsert.messages[0].pushName,
- phoneNumber: messageInfoUpsert.messages[0].key.participant
- .split("@")[0]
- .slice(2),
- timestamp: new Date(
- messageInfoUpsert.messages[0].messageTimestamp * 1000
- ).toISOString(),
- };
- // console.log(messageInfoUpsert.messages[0]);
- if (isRequiredMessage) {
- socket.emit("new message", newGrpMessage);
- chatsCollection.insertOne(newGrpMessage);
- console.log(newGrpMessage);
- }
- }
- };
-
- sock[id].ev.on("connection.update", connectionUpdateListener);
- sock[id].ev.on("messages.upsert", groupMessageEventListener);
-
- sock[id].ev.on("creds.update", saveCreds);
-
- if (user.isLogged === true) {
- socket.emit("user connected");
- }
- }
-
- app.get("/", (req, res) => {
- res.status(200).json("Hey this is done");
- });
-
- app.post("/api/signup", async (req, res, next) => {
- try {
- await createSignUpValidation.validateAsync(req.body);
- const { username, password, email } = req.body;
- const hashedPassword = await bcrypt.hash(password, 10);
- const newUser = new User({ username, password: hashedPassword, email });
- await newUser.save();
- const token = await signAccessToken(newUser.id);
- const maxAgeInSeconds = 10 * 24 * 60 * 60;
- res.cookie("jwt", token, {
- httpOnly: true,
- maxAge: maxAgeInSeconds,
- });
- res.status(201).json(newUser);
- } catch (error) {
- next(error);
- }
- });
-
- app.get("/api/getMe", verifyAccessToken, async (req, res, next) => {
- try {
- const data = req.data;
- res.status(200).json(data);
- } catch (error) {
- next(error);
- }
- });
-
- app.post("/api/signin", async (req, res, next) => {
- try {
- await createSignInValidation.validateAsync(req.body);
- const { email, password } = req.body;
- console.log(email, password);
- const validUser = await User.checkUser(email, password);
-
- if (!validUser) throw new MyError("Invalid email or password");
- const token = await signAccessToken(validUser.id);
- const maxAgeInSeconds = 10 * 24 * 60 * 60;
- res.cookie("jwt", token, {
- httpOnly: true,
- maxAge: maxAgeInSeconds,
- });
-
- res.status(200).json(validUser);
- } catch (error) {
- next(error);
- }
- });
-
- app.get("/api/refreshMessages", verifyAccessToken, async (req, res, next) => {
- try {
- const data = req.data;
- const chatsCollection = mongoClient
- .db("whatsapp_chats")
- .collection(`all_chats_${data.id}`);
- console.log(sock);
-
- const messages = await chatsCollection
- .find({})
- .sort({ timestamp: -1 })
- .limit(20)
- .toArray();
- res.status(200).json(messages);
- } catch (error) {
- next(error);
- }
- });
-
- app.post("/api/tag/add", verifyAccessToken, async (req, res, next) => {
- try {
- const data = req.data;
- const { tag } = req.body;
- const userTag = await User.findByIdAndUpdate(
- data.id,
- { $addToSet: { tags: tag } },
- { new: true }
- );
- if (userTag) {
- return res.status(201).json(userTag);
- } else {
- return res.status(404).json("User not found");
- }
- } catch (error) {
- next(error);
- }
- });
-
- app.post("/api/tag/del", verifyAccessToken, async (req, res, next) => {
- try {
- const data = req.data;
- const { tag: deleteTag } = req.body;
- let user = await User.findById(data.id);
-
- let tags = user.tags;
- tags = tags.filter((tag) => tag !== deleteTag);
- user.tags = tags;
- await user.save();
-
- res.status(200).json(user);
- } catch (error) {
- next(error);
- }
- });
-
- // app.get("/createServer", verifyAccessToken, (req, res) => {
- // const data = req.data;
- // connectionLogic(data.id);
- // res.status(200).json("Server created");
- // });
-
- process.on("exit", async () => {
- User.updateMany({}, { isLogged: false });
- });
-
- io.on("connection", (socket) => {
- console.log("a user connected");
- socket.on("whatsapp connect", (id) => {
- connectionLogic(id, socket, false);
- });
- });
-
- app.get("*", (req, res) => {
- res.sendFile(path.join(__dirname, "client", "dist", "index.html"));
- });
-
- app.use((err, req, res, next) => {
- res.status(err.status || 500);
- res.json({
- status: err.status || 500,
- message: err.message || "Internal Server error",
- });
- });
-
- server.listen(3000, () => {
- console.log("listening on *:3000");
- });
|