├── .gitignore ├── routes ├── user.js └── login.js ├── package.json ├── lib └── db.js ├── controller ├── userController.js └── authController.js ├── modals └── chatSchema.js ├── index.html └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | yarn.lock 3 | package-lock.json 4 | node_modules -------------------------------------------------------------------------------- /routes/user.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { allUsers, getData } from "../controller/userController.js"; 3 | 4 | const user = express.Router(); 5 | 6 | user.get("/", allUsers); 7 | user.post('/getdata' , getData) 8 | 9 | export default user; 10 | -------------------------------------------------------------------------------- /routes/login.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { 3 | getroute, 4 | CreateNewAccount, 5 | DeleteNewAccount, 6 | } from "../controller/authController.js"; 7 | 8 | const auth = express.Router(); 9 | 10 | auth.get("/", getroute); 11 | 12 | auth.post("/newuser", CreateNewAccount); 13 | auth.get("/delete", DeleteNewAccount); 14 | 15 | export default auth; 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chatbot-backend", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "type": "module", 7 | "scripts": { 8 | "start": "nodemon index.js" 9 | }, 10 | "dependencies": { 11 | "@socket.io/admin-ui": "^0.5.1", 12 | "body-parser": "^1.20.2", 13 | "cors": "^2.8.5", 14 | "dotenv": "^16.0.3", 15 | "express": "^4.18.2", 16 | "mongoose": "^7.0.2", 17 | "nodemon": "^2.0.21", 18 | "socket.io": "^4.6.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/db.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import { config } from "dotenv"; 3 | config(); 4 | 5 | const dbConnect = async () => { 6 | try { 7 | const uri = 8 | process.env.NODE_ENV === "production" 9 | ? process.env.MONGODB_URI_DEV 10 | : process.env.MONGODB_URI_PROD; 11 | 12 | await mongoose.connect(uri, { 13 | useNewUrlParser: true, 14 | useUnifiedTopology: true, 15 | }); 16 | return uri; 17 | } catch (err) { 18 | return console.error(err); 19 | } 20 | }; 21 | 22 | export default dbConnect; 23 | -------------------------------------------------------------------------------- /controller/userController.js: -------------------------------------------------------------------------------- 1 | import UserModal from "../modals/chatSchema.js"; 2 | 3 | export const allUsers = async (req, res) => { 4 | try { 5 | let ActiveUser = await UserModal.find(); 6 | res.status(200).send(ActiveUser); 7 | } catch (err) { 8 | res.status(500).send(err.message); 9 | } 10 | }; 11 | 12 | export const getData = async (req, res) => { 13 | try { 14 | let { id, subject } = req.body; 15 | console.log(id); 16 | let userData = await UserModal.findById(id); 17 | let data = userData.chats.filter((item) => item.chatFrom === subject); 18 | res.send( 19 | data); 20 | } catch (err) { 21 | res.status(500).send(err.message); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /controller/authController.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import UserModal from "../modals/chatSchema.js"; 3 | 4 | export const getroute = (req, res) => { 5 | res.send("hello world"); 6 | }; 7 | 8 | export const CreateNewAccount = async (req, res) => { 9 | try { 10 | const { user_id, name, avatar_url } = req.body; 11 | 12 | const isUserExist = await UserModal.findOne({ user_id }); 13 | 14 | if (isUserExist) { 15 | return res.send(isUserExist); 16 | } 17 | const newUser = await UserModal({ 18 | name: name, 19 | avatar_url: avatar_url || "", 20 | user_id: user_id, 21 | chats: [], 22 | }); 23 | 24 | newUser.save(); 25 | return res.send(newUser); 26 | } catch (err) { 27 | console.log(err); 28 | return res.send("error: " + err.message, err); 29 | } 30 | }; 31 | export const DeleteNewAccount = (req, res) => {}; 32 | -------------------------------------------------------------------------------- /modals/chatSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const UserSchema = new mongoose.Schema( 4 | { 5 | // _id: { 6 | // type: mongoose.Schema.Types.ObjectId, 7 | // require: true, 8 | // }, 9 | // clientId: { 10 | // type: String, 11 | // require: true, 12 | // }, 13 | name: { 14 | type: String, 15 | require: true, 16 | }, 17 | socketId: { 18 | type: String, 19 | default: "", 20 | }, 21 | avatar_url: { 22 | type: String, 23 | // require: true, 24 | }, 25 | user_id: { 26 | type: Number, 27 | require: true, 28 | }, 29 | chats: [ 30 | { 31 | 32 | chatFrom: { 33 | type: String, 34 | ref: "User", 35 | // require: true, 36 | }, 37 | chatTo: { 38 | type: String, 39 | // require: true, 40 | }, 41 | data: [ 42 | { 43 | key: { 44 | type: String, 45 | // required: true, 46 | }, 47 | value: { 48 | type: String, 49 | // required: true, 50 | }, 51 | }, 52 | ], 53 | }, 54 | ], 55 | }, 56 | { 57 | versionKey: false, 58 | } 59 | ); 60 | 61 | const UserModal = mongoose.model("Chat", UserSchema); 62 | export default UserModal; 63 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Socket.IO chat 5 | 57 | 58 | 59 | 60 |
61 | 62 |
63 | 64 | 65 | 66 | 101 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import http from "http"; 3 | import { Server } from "socket.io"; 4 | import dbConnect from "./lib/db.js"; 5 | import { fileURLToPath } from "url"; 6 | import path from "path"; 7 | import ChatModal from "./modals/chatSchema.js"; 8 | import mongoose from "mongoose"; 9 | import bodyParser from "body-parser"; 10 | import cors from "cors"; 11 | import user from "./routes/user.js"; 12 | import auth from "./routes/login.js"; 13 | import { instrument } from "@socket.io/admin-ui"; 14 | import UserModal from "./modals/chatSchema.js"; 15 | 16 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); 17 | let ActiveUserid; 18 | 19 | const app = express(); 20 | app.use(express.json()); 21 | app.use(cors({ origin: "*" })); 22 | app.use(bodyParser.urlencoded({ extended: true })); 23 | const httpServer = http.createServer(app); 24 | 25 | // request data 26 | app.get("/", (req, res) => { 27 | // res.sendFile(__dirname + "./index.html"); 28 | res.sendFile("hello world!"); 29 | }); 30 | app.use("/authentication", auth); 31 | app.use("/user", user); 32 | 33 | // socket connections 34 | const chatSocket = new Server(httpServer, { 35 | cors: { 36 | origin: ["https://admin.socket.io"], 37 | credentials: true, 38 | }, 39 | }); 40 | 41 | chatSocket.on("connection", async (socket) => { 42 | socket.on("connection established", async (userId, callback) => { 43 | console.log("connection established with user id:", userId); 44 | const socketId = socket.id; 45 | let userObject = await UserModal.updateOne( 46 | { _id: userId }, 47 | { $set: { socketId } } 48 | ); 49 | ActiveUserid = userId; 50 | socket.emit("newUser"); 51 | callback(socketId); 52 | }); 53 | socket.on("reconnectMe", async (_id) => { 54 | console.log("reconnecting with", _id._j); 55 | let data = await UserModal.updateOne( 56 | { 57 | _id: _id._j, 58 | }, 59 | { 60 | $set: { socketId: socket.id }, 61 | } 62 | ); 63 | socket.emit("newUser"); 64 | console.log("data", data); 65 | }); 66 | socket.on("disconnectMe", async () => { 67 | console.log(`Disconnecting client with ID ${socket.id}-and `); 68 | let data = await UserModal.updateOne( 69 | { 70 | socketId: socket.id, 71 | }, 72 | { 73 | $set: { socketId: "" }, 74 | } 75 | ); 76 | console.log("data", data); 77 | }); 78 | socket.on("sendMessage", async (targetId, { _j }, message) => { 79 | let current = _j; 80 | let targetUser = await UserModal.findById(targetId); 81 | if (!targetUser) return; 82 | let _id = new mongoose.Types.ObjectId(current._id); 83 | let mydata = await UserModal.find({ 84 | _id: _id, 85 | }); 86 | let isIchatWithOtherUser = mydata[0]?.chats?.filter( 87 | (item) => item.chatFrom === targetId 88 | ); 89 | if (isIchatWithOtherUser.length == 0) { 90 | // first time chatting let start chat from here 91 | // my side chatdata add 92 | let mySideChatData = await UserModal.updateOne( 93 | { 94 | _id: current._id, 95 | }, 96 | { 97 | $push: { 98 | chats: { 99 | chatFrom: targetId, 100 | chatTo: current._id, 101 | data: [ 102 | { 103 | key: current, 104 | value: message, 105 | }, 106 | ], 107 | }, 108 | }, 109 | } 110 | ); 111 | 112 | // // target side chat data 113 | let targetSideChatData = await UserModal.updateOne( 114 | { 115 | _id: targetId, 116 | }, 117 | { 118 | $push: { 119 | chats: { 120 | chatFrom: current._id, 121 | chatTo: targetId, 122 | data: [ 123 | { 124 | key: current, 125 | value: message, 126 | }, 127 | ], 128 | }, 129 | }, 130 | } 131 | ); 132 | } else { 133 | let mySideChatData = await UserModal.updateOne( 134 | { 135 | _id: current._id, 136 | chats: { 137 | $elemMatch: { chatFrom: targetId, chatTo: current._id }, 138 | }, 139 | }, 140 | { 141 | $push: { 142 | "chats.$.data": { 143 | key: current._id, 144 | value: message, 145 | }, 146 | }, 147 | } 148 | ); 149 | let targetSideChatData = await UserModal.updateOne( 150 | { 151 | _id: targetId, 152 | chats: { 153 | $elemMatch: { chatFrom: current._id, chatTo: targetId }, 154 | }, 155 | }, 156 | { 157 | $push: { 158 | "chats.$.data": { 159 | key: current._id, 160 | value: message, 161 | }, 162 | }, 163 | } 164 | ); 165 | } 166 | console.log(mydata[0].socketId); 167 | 168 | new Promise((res) => { 169 | res(mydata[0].socketId); 170 | }).then((myid) => { 171 | socket.to(targetUser.socketId).to(myid).emit("getMessage", message); 172 | }); 173 | }); 174 | 175 | socket.on("disconnect", async (id) => { 176 | console.log("user disconnected", id); 177 | }); 178 | }); 179 | 180 | instrument(chatSocket, { 181 | auth: false, 182 | type: "basic", 183 | username: "admin", 184 | password: "admin", 185 | }); 186 | dbConnect().then((res) => { 187 | httpServer.listen(3000, () => { 188 | console.log("listening on *:3000", `with database ${res}`); 189 | }); 190 | }); 191 | --------------------------------------------------------------------------------