messages.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. const MessageModel = require('../model/message');
  2. const UserModel = require('../model/user');
  3. const ChatModel = require('../model/chat');
  4. const fs = require('fs').promises;
  5. const s3 = require('../helpers/aws');
  6. const AWS_BUCKET_NAME = process.env.AWS_BUCKET_NAME;
  7. require('dotenv').config();
  8. const listMessages = async (req, res, next) => {
  9. try {
  10. const userId = req.user.id;
  11. const messages = await MessageModel.getList({ owner: userId }, req.query);
  12. return res.json({
  13. status: 'success',
  14. code: 200,
  15. data: messages,
  16. });
  17. } catch (e) {
  18. next(e);
  19. }
  20. };
  21. const listMessagesById = async (req, res, next) => {
  22. try {
  23. const userId = req.user.id;
  24. const companionId = req.params.companionId;
  25. const messages = await MessageModel.getList(
  26. { owner: userId, companionId },
  27. {}
  28. );
  29. return res.json({
  30. status: 'success',
  31. code: 200,
  32. data: messages,
  33. });
  34. } catch (e) {
  35. next(e);
  36. }
  37. };
  38. const updateMessageEmoji = async (req, res, next) => {
  39. try {
  40. const id = req.params.id;
  41. const userId = req.user.id;
  42. const { emoji } = req.body;
  43. const userMessage = await MessageModel.updateMessage(id, userId, { emoji });
  44. await MessageModel.findByFieldsAndUpdate(
  45. userId,
  46. userMessage.idTime,
  47. userMessage.companionId,
  48. {
  49. emojiCompanion: emoji,
  50. }
  51. );
  52. return res.status(200).json({
  53. status: 'success',
  54. code: 200,
  55. data: {},
  56. });
  57. } catch (e) {
  58. next(e);
  59. }
  60. };
  61. const updateMessagePin = async (req, res, next) => {
  62. try {
  63. const id = req.params.id;
  64. const userId = req.user.id;
  65. const { pinned } = req.body;
  66. const userMessage = await MessageModel.updateMessage(id, userId, {
  67. pinned,
  68. });
  69. await MessageModel.findByFieldsAndUpdate(
  70. userId,
  71. userMessage.idTime,
  72. userMessage.companionId,
  73. {
  74. pinned,
  75. }
  76. );
  77. return res.status(200).json({
  78. status: 'success',
  79. code: 200,
  80. data: {},
  81. });
  82. } catch (e) {
  83. next(e);
  84. }
  85. };
  86. const removeMessage = async (req, res, next) => {
  87. try {
  88. const id = req.params.id;
  89. const userId = req.user.id;
  90. const userMessage = await MessageModel.remove(id, userId);
  91. await MessageModel.removeByFields(
  92. userId,
  93. userMessage.idTime,
  94. userMessage.companionId
  95. );
  96. if (userMessage.type !== 'text') {
  97. const params = {
  98. Bucket: AWS_BUCKET_NAME,
  99. Key: `${userMessage.message}`,
  100. };
  101. s3.deleteObject(params, async function (err, _data) {
  102. if (err) throw err;
  103. });
  104. }
  105. const isChat = await ChatModel.getByField(userMessage.companionId, userId);
  106. const isCompanionChat = await ChatModel.getByField(
  107. userId,
  108. userMessage.companionId
  109. );
  110. const { total } = await MessageModel.getList(
  111. { owner: userId, companionId: userMessage.companionId },
  112. {}
  113. );
  114. const { total: Total } = await MessageModel.getList(
  115. { owner: userMessage.companionId, companionId: userId },
  116. {}
  117. );
  118. await ChatModel.update(isChat._id, userId, {
  119. total: total,
  120. seen: total - isChat.seen > 0 ? isChat.seen : total,
  121. watched: false,
  122. });
  123. await ChatModel.update(isCompanionChat._id, userMessage.companionId, {
  124. total: Total,
  125. seen: Total - isCompanionChat.seen > 0 ? isCompanionChat.seen : Total,
  126. watched: true,
  127. });
  128. return res.json({
  129. status: 'success',
  130. code: 200,
  131. data: {},
  132. });
  133. } catch (e) {
  134. next(e);
  135. }
  136. };
  137. const removeSelected = async (req, res, next) => {
  138. try {
  139. const userId = req.user.id;
  140. const { selectedArr, companionId } = req.body;
  141. const totalDeleted = selectedArr.length;
  142. const toDeleteMessage = async (id) => {
  143. const userMessage = await MessageModel.remove(id, userId);
  144. await MessageModel.removeByFields(
  145. userId,
  146. userMessage.idTime,
  147. companionId
  148. );
  149. if (userMessage.type !== 'text') {
  150. const params = {
  151. Bucket: AWS_BUCKET_NAME,
  152. Key: `${userMessage.message}`,
  153. };
  154. s3.deleteObject(params, async function (err, _data) {
  155. if (err) throw err;
  156. });
  157. }
  158. };
  159. await selectedArr.forEach(async (id) => await toDeleteMessage(id));
  160. const isChat = await ChatModel.getByField(companionId, userId);
  161. const isCompanionChat = await ChatModel.getByField(userId, companionId);
  162. const { total } = await MessageModel.getList(
  163. { owner: userId, companionId },
  164. {}
  165. );
  166. const { total: Total } = await MessageModel.getList(
  167. { owner: companionId, companionId: userId },
  168. {}
  169. );
  170. await ChatModel.update(isChat._id, userId, {
  171. total: total,
  172. seen: isChat.seen - totalDeleted > 0 ? isChat.seen - totalDeleted : 0,
  173. watched: false,
  174. });
  175. await ChatModel.update(isCompanionChat._id, companionId, {
  176. total: Total,
  177. seen:
  178. isCompanionChat.seen - totalDeleted > 0
  179. ? isCompanionChat.seen - totalDeleted
  180. : 0,
  181. watched: true,
  182. });
  183. return res.json({
  184. status: 'success',
  185. code: 200,
  186. data: {},
  187. });
  188. } catch (e) {
  189. next(e);
  190. }
  191. };
  192. const sentMessage = async (req, res, next) => {
  193. try {
  194. const { id, message, caption } = req.body;
  195. const idTime = Math.round(Date.now() / 1000);
  196. const user = req.user;
  197. const userId = user.id;
  198. const companion = await UserModel.findById(id);
  199. const isChat = await ChatModel.getByField(id, userId);
  200. const isCompanionChat = await ChatModel.getByField(userId, id);
  201. const { name, lastName, avatarUrl, color, number } = user;
  202. if (companion && isChat && isCompanionChat) {
  203. const newMessage = await MessageModel.add({
  204. message,
  205. name,
  206. lastName,
  207. avatarUrl,
  208. color,
  209. number,
  210. type: 'text',
  211. caption,
  212. idTime,
  213. companionIdFlow: userId,
  214. companionId: id,
  215. owner: userId,
  216. });
  217. await MessageModel.add({
  218. message,
  219. name,
  220. lastName,
  221. avatarUrl,
  222. color,
  223. number,
  224. type: 'text',
  225. caption,
  226. idTime,
  227. companionIdFlow: userId,
  228. companionId: userId,
  229. owner: id,
  230. });
  231. const { total } = await MessageModel.getList(
  232. { owner: userId, companionId: id },
  233. {}
  234. );
  235. await ChatModel.update(isChat._id, userId, {
  236. total,
  237. seen: total,
  238. watched: false,
  239. lastMessage: message,
  240. lastMessageCreatedAt: newMessage.createdAt,
  241. });
  242. const { total: Total } = await MessageModel.getList(
  243. { owner: id, companionId: userId },
  244. {}
  245. );
  246. await ChatModel.update(isCompanionChat._id, id, {
  247. total: Total,
  248. lastMessage: message,
  249. lastMessageCreatedAt: newMessage.createdAt,
  250. });
  251. return res.status(201).json({
  252. status: 'success',
  253. code: 201,
  254. data: newMessage,
  255. });
  256. }
  257. } catch (e) {
  258. next(e);
  259. }
  260. };
  261. const imageMessage = async (req, res, next) => {
  262. try {
  263. const userId = req.user.id;
  264. const [id, ...rest] = req.params.companionIdAndCaption.split(' ');
  265. const caption = rest.join(' ').slice(0, -1);
  266. const idTime = Math.round(Date.now() / 1000);
  267. const isChat = await ChatModel.getByField(id, userId);
  268. const isCompanionChat = await ChatModel.getByField(userId, id);
  269. const originalName = req.file.originalname;
  270. const pathToFile = req.file.path;
  271. const fullType = req.file.mimetype;
  272. const imgUrl = `${Math.round(Date.now() / 1000)}${userId}${originalName}`;
  273. const fileContent = await fs.readFile(pathToFile);
  274. const params = {
  275. Bucket: AWS_BUCKET_NAME,
  276. Key: `${imgUrl}`,
  277. Body: fileContent,
  278. };
  279. s3.upload(params, async (err, _data) => {
  280. if (err) throw err;
  281. fs.unlink(pathToFile);
  282. });
  283. if (isChat && isCompanionChat) {
  284. const { name, lastName, avatarUrl, color, number } = req.user;
  285. const newMessage = await MessageModel.add({
  286. message: imgUrl,
  287. name,
  288. lastName,
  289. avatarUrl,
  290. color,
  291. number,
  292. type: 'image',
  293. fullType,
  294. caption,
  295. idTime,
  296. companionIdFlow: userId,
  297. companionId: id,
  298. owner: userId,
  299. });
  300. await MessageModel.add({
  301. message: imgUrl,
  302. name,
  303. lastName,
  304. avatarUrl,
  305. color,
  306. number,
  307. type: 'image',
  308. fullType,
  309. caption,
  310. idTime,
  311. companionIdFlow: userId,
  312. companionId: userId,
  313. owner: id,
  314. });
  315. const { total } = await MessageModel.getList(
  316. { owner: userId, companionId: id },
  317. {}
  318. );
  319. await ChatModel.update(isChat._id, userId, {
  320. total,
  321. seen: total,
  322. watched: false,
  323. lastMessage: imgUrl,
  324. lastMessageCreatedAt: newMessage.createdAt,
  325. });
  326. const { total: Total } = await MessageModel.getList(
  327. { owner: id, companionId: userId },
  328. {}
  329. );
  330. await ChatModel.update(isCompanionChat._id, id, {
  331. total: Total,
  332. lastMessage: imgUrl,
  333. lastMessageCreatedAt: newMessage.createdAt,
  334. });
  335. return res.status(201).json({
  336. status: 'success',
  337. code: 201,
  338. data: newMessage,
  339. });
  340. }
  341. } catch (e) {
  342. next(e);
  343. }
  344. };
  345. const audioMessage = async (req, res, next) => {
  346. try {
  347. const userId = req.user.id;
  348. const [id, ...rest] = req.params.companionIdAndCaption.split(' ');
  349. let caption = rest.join(' ');
  350. if (caption.length === 1) caption.slice(0, -1);
  351. const idTime = Math.round(Date.now() / 1000);
  352. const isChat = await ChatModel.getByField(id, userId);
  353. const isCompanionChat = await ChatModel.getByField(userId, id);
  354. const originalName = req.file.originalname;
  355. const pathToFile = req.file.path;
  356. const fullType = req.file.mimetype;
  357. const audioUrl = `${Math.round(Date.now() / 1000)}${originalName}`;
  358. const fileContent = await fs.readFile(pathToFile);
  359. const params = {
  360. Bucket: AWS_BUCKET_NAME,
  361. Key: `${audioUrl}`,
  362. Body: fileContent,
  363. };
  364. s3.upload(params, async (err, _data) => {
  365. if (err) throw err;
  366. fs.unlink(pathToFile);
  367. });
  368. if (isChat && isCompanionChat) {
  369. const { name, lastName, avatarUrl, color, number } = req.user;
  370. const newMessage = await MessageModel.add({
  371. message: audioUrl,
  372. name,
  373. lastName,
  374. avatarUrl,
  375. color,
  376. number,
  377. type: 'audio',
  378. fullType,
  379. caption,
  380. idTime,
  381. companionIdFlow: userId,
  382. companionId: id,
  383. owner: userId,
  384. });
  385. await MessageModel.add({
  386. message: audioUrl,
  387. name,
  388. lastName,
  389. avatarUrl,
  390. color,
  391. number,
  392. type: 'audio',
  393. fullType,
  394. caption,
  395. idTime,
  396. companionIdFlow: userId,
  397. companionId: userId,
  398. owner: id,
  399. });
  400. const { total } = await MessageModel.getList(
  401. { owner: userId, companionId: id },
  402. {}
  403. );
  404. await ChatModel.update(isChat._id, userId, {
  405. total,
  406. seen: total,
  407. watched: false,
  408. lastMessage: audioUrl,
  409. lastMessageCreatedAt: newMessage.createdAt,
  410. });
  411. const { total: Total } = await MessageModel.getList(
  412. { owner: id, companionId: userId },
  413. {}
  414. );
  415. await ChatModel.update(isCompanionChat._id, id, {
  416. total: Total,
  417. lastMessage: audioUrl,
  418. lastMessageCreatedAt: newMessage.createdAt,
  419. });
  420. return res.status(201).json({
  421. status: 'success',
  422. code: 201,
  423. data: newMessage,
  424. });
  425. }
  426. } catch (e) {
  427. next(e);
  428. }
  429. };
  430. const videoMessage = async (req, res, next) => {
  431. try {
  432. const userId = req.user.id;
  433. const [id, ...rest] = req.params.companionIdAndCaption.split(' ');
  434. let caption = rest.join(' ');
  435. if (caption.length === 1) caption.slice(0, -1);
  436. const idTime = Math.round(Date.now() / 1000);
  437. const isChat = await ChatModel.getByField(id, userId);
  438. const isCompanionChat = await ChatModel.getByField(userId, id);
  439. const originalName = req.file.originalname;
  440. const pathToFile = req.file.path;
  441. const videoUrl = `${Math.round(Date.now() / 1000)}${originalName}`;
  442. const fullType = req.file.mimetype;
  443. const fileContent = await fs.readFile(pathToFile);
  444. const params = {
  445. Bucket: AWS_BUCKET_NAME,
  446. Key: `${videoUrl}`,
  447. Body: fileContent,
  448. };
  449. s3.upload(params, async (err, _data) => {
  450. if (err) throw err;
  451. fs.unlink(pathToFile);
  452. });
  453. if (isChat && isCompanionChat) {
  454. const { name, lastName, avatarUrl, color, number } = req.user;
  455. const newMessage = await MessageModel.add({
  456. message: videoUrl,
  457. name,
  458. lastName,
  459. avatarUrl,
  460. color,
  461. number,
  462. type: 'video',
  463. fullType,
  464. caption,
  465. idTime,
  466. companionIdFlow: userId,
  467. companionId: id,
  468. owner: userId,
  469. });
  470. await MessageModel.add({
  471. message: videoUrl,
  472. name,
  473. lastName,
  474. avatarUrl,
  475. color,
  476. number,
  477. type: 'video',
  478. fullType,
  479. caption,
  480. idTime,
  481. companionIdFlow: userId,
  482. companionId: userId,
  483. owner: id,
  484. });
  485. const { total } = await MessageModel.getList(
  486. { owner: userId, companionId: id },
  487. {}
  488. );
  489. await ChatModel.update(isChat._id, userId, {
  490. total,
  491. seen: total,
  492. watched: false,
  493. lastMessage: videoUrl,
  494. lastMessageCreatedAt: newMessage.createdAt,
  495. });
  496. const { total: Total } = await MessageModel.getList(
  497. { owner: id, companionId: userId },
  498. {}
  499. );
  500. await ChatModel.update(isCompanionChat._id, id, {
  501. total: Total,
  502. lastMessage: videoUrl,
  503. lastMessageCreatedAt: newMessage.createdAt,
  504. });
  505. return res.status(201).json({
  506. status: 'success',
  507. code: 201,
  508. data: newMessage,
  509. });
  510. }
  511. } catch (e) {
  512. next(e);
  513. }
  514. };
  515. const fileMessage = async (req, res, next) => {
  516. try {
  517. const userId = req.user.id;
  518. const [id, ...rest] = req.params.companionIdAndCaption.split(' ');
  519. let caption = rest.join(' ');
  520. if (caption.length === 1) caption.slice(0, -1);
  521. const idTime = Math.round(Date.now() / 1000);
  522. const isChat = await ChatModel.getByField(id, userId);
  523. const isCompanionChat = await ChatModel.getByField(userId, id);
  524. const pathToFile = req.file.path;
  525. const fullType = req.file.mimetype;
  526. let type;
  527. switch (fullType) {
  528. case 'application/pdf':
  529. type = 'pdf';
  530. break;
  531. case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
  532. type = 'docx';
  533. break;
  534. case 'application/octet-stream':
  535. type = 'docx';
  536. break;
  537. default:
  538. break;
  539. }
  540. const fileUrl = `${Math.round(Date.now() / 1000)}file.${type}`;
  541. const fileContent = await fs.readFile(pathToFile);
  542. const params = {
  543. Bucket: AWS_BUCKET_NAME,
  544. Key: `${fileUrl}`,
  545. Body: fileContent,
  546. };
  547. s3.upload(params, async (err, _data) => {
  548. if (err) throw err;
  549. fs.unlink(pathToFile);
  550. });
  551. if (isChat && isCompanionChat) {
  552. const { name, lastName, avatarUrl, color, number } = req.user;
  553. const newMessage = await MessageModel.add({
  554. message: fileUrl,
  555. name,
  556. lastName,
  557. avatarUrl,
  558. color,
  559. number,
  560. type,
  561. fullType,
  562. caption,
  563. idTime,
  564. companionIdFlow: userId,
  565. companionId: id,
  566. owner: userId,
  567. });
  568. await MessageModel.add({
  569. message: fileUrl,
  570. name,
  571. lastName,
  572. avatarUrl,
  573. color,
  574. number,
  575. type,
  576. fullType,
  577. caption,
  578. idTime,
  579. companionIdFlow: userId,
  580. companionId: userId,
  581. owner: id,
  582. });
  583. const { total } = await MessageModel.getList(
  584. { owner: userId, companionId: id },
  585. {}
  586. );
  587. await ChatModel.update(isChat._id, userId, {
  588. total,
  589. seen: total,
  590. watched: false,
  591. lastMessage: fileUrl,
  592. lastMessageCreatedAt: newMessage.createdAt,
  593. });
  594. const { total: Total } = await MessageModel.getList(
  595. { owner: id, companionId: userId },
  596. {}
  597. );
  598. await ChatModel.update(isCompanionChat._id, id, {
  599. total: Total,
  600. lastMessage: fileUrl,
  601. lastMessageCreatedAt: newMessage.createdAt,
  602. });
  603. return res.status(201).json({
  604. status: 'success',
  605. code: 201,
  606. data: newMessage,
  607. });
  608. }
  609. } catch (e) {
  610. next(e);
  611. }
  612. };
  613. module.exports = {
  614. listMessages,
  615. removeMessage,
  616. removeSelected,
  617. updateMessageEmoji,
  618. updateMessagePin,
  619. listMessagesById,
  620. sentMessage,
  621. imageMessage,
  622. audioMessage,
  623. videoMessage,
  624. fileMessage,
  625. };