Add group chat functions, slight refactoring

This commit is contained in:
Pedro Lopez
2019-02-20 02:42:19 -04:00
parent 594a65d5e8
commit 1b7376885d
12 changed files with 316 additions and 37 deletions

39
src/structures/Base.js Normal file
View File

@@ -0,0 +1,39 @@
'use strict';
/**
* Represents a WhatsApp data structure
*/
class Base {
constructor(client) {
/**
* The client that instantiated this
* @readonly
*/
Object.defineProperty(this, 'client', { value: client });
}
_clone() {
return Object.assign(Object.create(this), this);
}
_patch(data) { return data; }
/**
* Name that represents this model in the WhatsApp Web Store
* @readonly
*/
static get WAppModel() {
return this.name;
}
/**
* Extra fields to add to model serialization
* @readonly
*/
static get extraFields() {
return [];
}
}
module.exports = Base;

33
src/structures/Chat.js Normal file
View File

@@ -0,0 +1,33 @@
'use strict';
const Base = require('./Base');
/**
* Represents a Chat on WhatsApp
* @extends {Base}
*/
class Chat extends Base {
constructor(client, data) {
super(client);
if(data) this._patch(data);
}
_patch(data) {
this.id = data.id;
this.name = data.formattedTitle;
this.isGroup = data.isGroup;
this.isReadOnly = data.isReadOnly;
this.unreadCount = data.unreadCount;
this.timestamp = data.t;
return super._patch(data);
}
sendMessage(message) {
return this.client.sendMessage(this.id._serialized, message);
}
}
module.exports = Chat;

166
src/structures/GroupChat.js Normal file
View File

@@ -0,0 +1,166 @@
'use strict';
const Chat = require('./Chat');
/**
* Represents a Group Chat on WhatsApp
* @extends {Chat}
*/
class GroupChat extends Chat {
_patch(data) {
this.groupMetadata = data.groupMetadata;
return super._patch(data);
}
/**
* Gets the group owner
*/
get owner() {
return this.groupMetadata.owner;
}
/**
* Gets the date at which the group was created
*/
get createdAt() {
return new Date(this.groupMetadata.creation * 1000);
}
/**
* Gets the group description
*/
get description() {
return this.groupMetadata.desc;
}
/**
* Gets the group participants
*/
get participants() {
return this.groupMetadata.participants;
}
/**
* Adds a list of participants by ID to the group
* @param {Array[string]} participantIds
*/
async addParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => {
return Store.Wap.addParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Removes a list of participants by ID to the group
* @param {Array[string]} participantIds
*/
async removeParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => {
return Store.Wap.removeParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Promotes participants by IDs to admins
* @param {Array[string]} participantIds
*/
async promoteParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => {
return Store.Wap.promoteParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Demotes participants by IDs to regular users
* @param {Array[string]} participantIds
*/
async demoteParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => {
return Store.Wap.demoteParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Updates the group subject
* @param {string} subject
*/
async setSubject(subject) {
let res = await this.client.pupPage.evaluate((chatId, subject) => {
return Store.Chat.get(chatId).setSubject(subject);
}, this.id._serialized, subject);
if(res.status == 200) {
this.name = subject;
}
}
/**
* Updates the group description
* @param {string} description
*/
async setDescription(description) {
let res = await this.client.pupPage.evaluate((chatId, description) => {
return Store.Chat.get(chatId).setGroupDesc(description);
}, this.id._serialized, description);
if (res.status == 200) {
this.groupMetadata.desc = description;
}
}
/**
* Gets the invite code for a specific group
*/
async getInviteCode() {
let res = await this.client.pupPage.evaluate(chatId => {
return Store.Wap.groupInviteCode(chatId);
}, this.id._serialized);
if (res.status == 200) {
return res.code;
}
throw new Error('Not authorized')
}
/**
* Invalidates the current group invite code and generates a new one
*/
async revokeInvite() {
return await this.client.pupPage.evaluate(chatId => {
return Store.Wap.revokeGroupInvite(chatId);
}, chatId);
}
/**
* Returns an object with information about the invite code's group
* @param {string} inviteCode
*/
static async getInviteInfo(inviteCode) {
return await this.client.pupPage.evaluate(inviteCode => {
return Store.Wap.groupInviteInfo(inviteCode);
}, inviteCode);
}
/**
* Joins a group with an invite code
* @param {string} inviteCode
*/
static async join(inviteCode) {
return await this.client.pupPage.evaluate(inviteCode => {
return Store.Wap.acceptGroupInvite(inviteCode);
}, inviteCode);
}
/**
* Makes the bot leave the group
*/
async leave() {
return await this.client.pupPage.evaluate(chatId => {
return Store.Wap.leaveGroup(chatId);
}, this.id._serialized);
}
}
module.exports = GroupChat;

74
src/structures/Message.js Normal file
View File

@@ -0,0 +1,74 @@
'use strict';
const Base = require('./Base');
/**
* Represents a Message on WhatsApp
* @extends {Base}
*/
class Message extends Base {
constructor(client, data) {
super(client);
if(data) this._patch(data);
}
_patch(data) {
this.id = data.id;
this.body = data.body;
this.type = data.type;
this.timestamp = data.t;
this.from = data.from;
this.to = data.to;
this.author = data.author;
this.isForwarded = data.isForwarded;
this.broadcast = data.broadcast;
return super._patch(data);
}
/**
* Returns the Chat this message was sent in
*/
getChat() {
return this.client.getChatById(this.from);
}
/**
* Sends a message as a reply. If chatId is specified, it will be sent
* through the specified Chat. If not, it will send the message
* in the same Chat as the original message was sent.
* @param {string} message
* @param {?string} chatId
*/
async reply(message, chatId) {
if (!chatId) {
chatId = this.from;
}
return await this.client.pupPage.evaluate((chatId, quotedMessageId, message) => {
let quotedMessage = Store.Msg.get(quotedMessageId);
if(quotedMessage.canReply()) {
const chat = Store.Chat.get(chatId);
chat.composeQuotedMsg = quotedMessage;
chat.sendMessage(message, {quotedMsg: quotedMessage});
chat.composeQuotedMsg = null;
} else {
throw new Error('This message cannot be replied to.');
}
}, chatId, this.id._serialized, message);
}
static get WAppModel() {
return 'Msg';
}
static get extraFields() {
return [
'isNewMsg'
];
}
}
module.exports = Message;

View File

@@ -0,0 +1,13 @@
'use strict';
const Chat = require('./Chat');
/**
* Represents a Private Chat on WhatsApp
* @extends {Chat}
*/
class PrivateChat extends Chat {
}
module.exports = PrivateChat;