mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 14:17:22 +01:00
Real-time Chat (#7664)
* feat(realtime-chat): add Pusher library to the server * feat(realtime-chat): only for private groups * feat(realtime-chat): add authentication endpoint for Pusher * feat(realtime-chat): client proof of concept * fix typo in apidoc * feat(realtime-chat): redo authentication and write integration tests * remove firebase code * fix client side tests * fix line ending in bower.json * feat(realtime chat): use presence channels for parties, send events & disconnect clients if user leaves or is removed from party, automatically update UI * pusher: enable all events in the background * fix pusher integration tests
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
import _ from 'lodash';
|
||||
import { removeFromArray } from '../../libs/api-v3/collectionManipulators';
|
||||
import { getUserInfo, getGroupUrl, sendTxn } from '../../libs/api-v3/email';
|
||||
import pusher from '../../libs/api-v3/pusher';
|
||||
import nconf from 'nconf';
|
||||
import Bluebird from 'bluebird';
|
||||
|
||||
@@ -53,8 +54,8 @@ api.getChat = {
|
||||
* @apiGroup Chat
|
||||
*
|
||||
* @apiParam {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam {message} Body parameter - message The message to post
|
||||
* @apiParam {previousMsg} previousMsg Query parameter - The previous chat message which will force a return of the full group chat
|
||||
* @apiParam {string} message Body parameter - message The message to post
|
||||
* @apiParam {UUID} previousMsg Query parameter - The previous chat message which will force a return of the full group chat
|
||||
*
|
||||
* @apiSuccess data An array of chat messages if a new message was posted after previousMsg, otherwise the posted message
|
||||
*/
|
||||
@@ -83,7 +84,7 @@ api.postChat = {
|
||||
let lastClientMsg = req.query.previousMsg;
|
||||
chatUpdated = lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg ? true : false;
|
||||
|
||||
group.sendChat(req.body.message, user);
|
||||
let newChatMessage = group.sendChat(req.body.message, user);
|
||||
|
||||
let toSave = [group.save()];
|
||||
|
||||
@@ -93,6 +94,14 @@ api.postChat = {
|
||||
}
|
||||
|
||||
let [savedGroup] = await Bluebird.all(toSave);
|
||||
|
||||
// real-time chat is only enabled for private groups (for now only for parties)
|
||||
if (savedGroup.privacy === 'private' && savedGroup.type === 'party') {
|
||||
// req.body.pusherSocketId is sent from official clients to identify the sender user's real time socket
|
||||
// see https://pusher.com/docs/server_api_guide/server_excluding_recipients
|
||||
pusher.trigger(`presence-group-${savedGroup._id}`, 'new-chat', newChatMessage, req.body.pusherSocketId);
|
||||
}
|
||||
|
||||
if (chatUpdated) {
|
||||
res.respond(200, {chat: Group.toJSONCleanChat(savedGroup, user).chat});
|
||||
} else {
|
||||
@@ -107,8 +116,8 @@ api.postChat = {
|
||||
* @apiName LikeChat
|
||||
* @apiGroup Chat
|
||||
*
|
||||
* @apiParam {groupId} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam {chatId} chatId The chat message _id
|
||||
* @apiParam {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam {UUID} chatId The chat message _id
|
||||
*
|
||||
* @apiSuccess {Object} data The liked chat message
|
||||
*/
|
||||
@@ -154,8 +163,8 @@ api.likeChat = {
|
||||
* @apiName FlagChat
|
||||
* @apiGroup Chat
|
||||
*
|
||||
* @apiParam {groupId} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam {chatId} chatId The chat message id
|
||||
* @apiParam {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam {UUID} chatId The chat message id
|
||||
*
|
||||
* @apiSuccess {object} data The flagged chat message
|
||||
*/
|
||||
@@ -243,8 +252,8 @@ api.flagChat = {
|
||||
* @apiName ClearFlags
|
||||
* @apiGroup Chat
|
||||
*
|
||||
* @apiParam {groupId} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam {chatId} chatId The chat message id
|
||||
* @apiParam {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam {UUID} chatId The chat message id
|
||||
*
|
||||
* @apiSuccess {Object} data An empty object
|
||||
*/
|
||||
@@ -318,7 +327,7 @@ api.clearChatFlags = {
|
||||
* @apiName SeenChat
|
||||
* @apiGroup Chat
|
||||
*
|
||||
* @apiParam {groupId} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
*
|
||||
* @apiSuccess {Object} data An empty object
|
||||
*/
|
||||
@@ -354,8 +363,8 @@ api.seenChat = {
|
||||
* @apiGroup Chat
|
||||
*
|
||||
* @apiParam {string} previousMsg Query parameter - The last message fetched by the client so that the whole chat will be returned only if new messages have been posted in the meantime
|
||||
* @apiParam {string} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam {string} chatId The chat message id
|
||||
* @apiParam {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam {UUID} chatId The chat message id
|
||||
*
|
||||
* @apiSuccess data The updated chat array or an empty object if no message was posted after previousMsg
|
||||
* @apiSuccess {Object} data An empty object when the previous message was deleted
|
||||
|
||||
Reference in New Issue
Block a user