whatsapp-web.js 1.28.1-alpha.0 → 1.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +184 -6
- package/index.js +1 -0
- package/package.json +1 -1
- package/src/Client.js +385 -28
- package/src/factories/ChatFactory.js +7 -2
- package/src/structures/Channel.js +382 -0
- package/src/structures/Chat.js +3 -3
- package/src/structures/GroupChat.js +4 -8
- package/src/structures/Message.js +1 -1
- package/src/structures/index.js +1 -0
- package/src/util/Injected/Store.js +34 -5
- package/src/util/Injected/Utils.js +239 -174
- package/src/util/InterfaceController.js +4 -5
package/src/Client.js
CHANGED
|
@@ -15,7 +15,7 @@ const { LoadUtils } = require('./util/Injected/Utils');
|
|
|
15
15
|
const ChatFactory = require('./factories/ChatFactory');
|
|
16
16
|
const ContactFactory = require('./factories/ContactFactory');
|
|
17
17
|
const WebCacheFactory = require('./webCache/WebCacheFactory');
|
|
18
|
-
const {
|
|
18
|
+
const { Broadcast, Buttons, Call, ClientInfo, Contact, GroupNotification, Label, List, Location, Message, MessageMedia, Poll, PollVote, Reaction } = require('./structures');
|
|
19
19
|
const NoAuth = require('./authStrategies/NoAuth');
|
|
20
20
|
const {exposeFunctionIfAbsent} = require('./util/Puppeteer');
|
|
21
21
|
|
|
@@ -820,11 +820,9 @@ class Client extends EventEmitter {
|
|
|
820
820
|
*
|
|
821
821
|
*/
|
|
822
822
|
async sendSeen(chatId) {
|
|
823
|
-
|
|
823
|
+
return await this.pupPage.evaluate(async (chatId) => {
|
|
824
824
|
return window.WWebJS.sendSeen(chatId);
|
|
825
|
-
|
|
826
825
|
}, chatId);
|
|
827
|
-
return result;
|
|
828
826
|
}
|
|
829
827
|
|
|
830
828
|
/**
|
|
@@ -854,6 +852,7 @@ class Client extends EventEmitter {
|
|
|
854
852
|
* @property {string} [stickerName=undefined] - Sets the name of the sticker, (if sendMediaAsSticker is true).
|
|
855
853
|
* @property {string[]} [stickerCategories=undefined] - Sets the categories of the sticker, (if sendMediaAsSticker is true). Provide emoji char array, can be null.
|
|
856
854
|
* @property {MessageMedia} [media] - Media to be sent
|
|
855
|
+
* @property {any} [extra] - Extra options
|
|
857
856
|
*/
|
|
858
857
|
|
|
859
858
|
/**
|
|
@@ -865,6 +864,19 @@ class Client extends EventEmitter {
|
|
|
865
864
|
* @returns {Promise<Message>} Message that was just sent
|
|
866
865
|
*/
|
|
867
866
|
async sendMessage(chatId, content, options = {}) {
|
|
867
|
+
const isChannel = /@\w*newsletter\b/.test(chatId);
|
|
868
|
+
|
|
869
|
+
if (isChannel && [
|
|
870
|
+
options.sendMediaAsDocument, options.quotedMessageId,
|
|
871
|
+
options.parseVCards, options.isViewOnce,
|
|
872
|
+
content instanceof Location, content instanceof Contact,
|
|
873
|
+
content instanceof Buttons, content instanceof List,
|
|
874
|
+
Array.isArray(content) && content.length > 0 && content[0] instanceof Contact
|
|
875
|
+
].includes(true)) {
|
|
876
|
+
console.warn('The message type is currently not supported for sending in channels,\nthe supported message types are: text, image, sticker, gif, video, voice and poll.');
|
|
877
|
+
return null;
|
|
878
|
+
}
|
|
879
|
+
|
|
868
880
|
if (options.mentions) {
|
|
869
881
|
!Array.isArray(options.mentions) && (options.mentions = [options.mentions]);
|
|
870
882
|
if (options.mentions.some((possiblyContact) => possiblyContact instanceof Contact)) {
|
|
@@ -874,7 +886,7 @@ class Client extends EventEmitter {
|
|
|
874
886
|
}
|
|
875
887
|
|
|
876
888
|
options.groupMentions && !Array.isArray(options.groupMentions) && (options.groupMentions = [options.groupMentions]);
|
|
877
|
-
|
|
889
|
+
|
|
878
890
|
let internalOptions = {
|
|
879
891
|
linkPreview: options.linkPreview === false ? undefined : true,
|
|
880
892
|
sendAudioAsVoice: options.sendAudioAsVoice,
|
|
@@ -890,14 +902,14 @@ class Client extends EventEmitter {
|
|
|
890
902
|
extraOptions: options.extra
|
|
891
903
|
};
|
|
892
904
|
|
|
893
|
-
const sendSeen =
|
|
905
|
+
const sendSeen = options.sendSeen !== false;
|
|
894
906
|
|
|
895
907
|
if (content instanceof MessageMedia) {
|
|
896
|
-
internalOptions.
|
|
908
|
+
internalOptions.media = content;
|
|
897
909
|
internalOptions.isViewOnce = options.isViewOnce,
|
|
898
910
|
content = '';
|
|
899
911
|
} else if (options.media instanceof MessageMedia) {
|
|
900
|
-
internalOptions.
|
|
912
|
+
internalOptions.media = options.media;
|
|
901
913
|
internalOptions.caption = content;
|
|
902
914
|
internalOptions.isViewOnce = options.isViewOnce,
|
|
903
915
|
content = '';
|
|
@@ -914,17 +926,19 @@ class Client extends EventEmitter {
|
|
|
914
926
|
internalOptions.contactCardList = content.map(contact => contact.id._serialized);
|
|
915
927
|
content = '';
|
|
916
928
|
} else if (content instanceof Buttons) {
|
|
929
|
+
console.warn('Buttons are now deprecated. See more at https://www.youtube.com/watch?v=hv1R1rLeVVE.');
|
|
917
930
|
if (content.type !== 'chat') { internalOptions.attachment = content.body; }
|
|
918
931
|
internalOptions.buttons = content;
|
|
919
932
|
content = '';
|
|
920
933
|
} else if (content instanceof List) {
|
|
934
|
+
console.warn('Lists are now deprecated. See more at https://www.youtube.com/watch?v=hv1R1rLeVVE.');
|
|
921
935
|
internalOptions.list = content;
|
|
922
936
|
content = '';
|
|
923
937
|
}
|
|
924
938
|
|
|
925
|
-
if (internalOptions.sendMediaAsSticker && internalOptions.
|
|
926
|
-
internalOptions.
|
|
927
|
-
internalOptions.
|
|
939
|
+
if (internalOptions.sendMediaAsSticker && internalOptions.media) {
|
|
940
|
+
internalOptions.media = await Util.formatToWebpSticker(
|
|
941
|
+
internalOptions.media, {
|
|
928
942
|
name: options.stickerName,
|
|
929
943
|
author: options.stickerAuthor,
|
|
930
944
|
categories: options.stickerCategories
|
|
@@ -932,20 +946,60 @@ class Client extends EventEmitter {
|
|
|
932
946
|
);
|
|
933
947
|
}
|
|
934
948
|
|
|
935
|
-
const
|
|
936
|
-
const
|
|
937
|
-
const chat = await window.Store.Chat.find(chatWid);
|
|
949
|
+
const sentMsg = await this.pupPage.evaluate(async (chatId, content, options, sendSeen) => {
|
|
950
|
+
const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
|
938
951
|
|
|
952
|
+
if (!chat) return null;
|
|
939
953
|
|
|
940
954
|
if (sendSeen) {
|
|
941
955
|
await window.WWebJS.sendSeen(chatId);
|
|
942
956
|
}
|
|
943
957
|
|
|
944
|
-
const msg = await window.WWebJS.sendMessage(chat,
|
|
945
|
-
return
|
|
958
|
+
const msg = await window.WWebJS.sendMessage(chat, content, options);
|
|
959
|
+
return msg
|
|
960
|
+
? window.WWebJS.getMessageModel(msg)
|
|
961
|
+
: undefined;
|
|
946
962
|
}, chatId, content, internalOptions, sendSeen);
|
|
947
963
|
|
|
948
|
-
return
|
|
964
|
+
return sentMsg
|
|
965
|
+
? new Message(this, sentMsg)
|
|
966
|
+
: undefined;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
/**
|
|
970
|
+
* @typedef {Object} SendChannelAdminInviteOptions
|
|
971
|
+
* @property {?string} comment The comment to be added to an invitation
|
|
972
|
+
*/
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Sends a channel admin invitation to a user, allowing them to become an admin of the channel
|
|
976
|
+
* @param {string} chatId The ID of a user to send the channel admin invitation to
|
|
977
|
+
* @param {string} channelId The ID of a channel for which the invitation is being sent
|
|
978
|
+
* @param {SendChannelAdminInviteOptions} options
|
|
979
|
+
* @returns {Promise<boolean>} Returns true if an invitation was sent successfully, false otherwise
|
|
980
|
+
*/
|
|
981
|
+
async sendChannelAdminInvite(chatId, channelId, options = {}) {
|
|
982
|
+
const response = await this.pupPage.evaluate(async (chatId, channelId, options) => {
|
|
983
|
+
const channelWid = window.Store.WidFactory.createWid(channelId);
|
|
984
|
+
const chatWid = window.Store.WidFactory.createWid(chatId);
|
|
985
|
+
const chat = window.Store.Chat.get(chatWid) || (await window.Store.Chat.find(chatWid));
|
|
986
|
+
|
|
987
|
+
if (!chatWid.isUser()) {
|
|
988
|
+
return false;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
return await window.Store.SendChannelMessage.sendNewsletterAdminInviteMessage(
|
|
992
|
+
chat,
|
|
993
|
+
{
|
|
994
|
+
newsletterWid: channelWid,
|
|
995
|
+
invitee: chatWid,
|
|
996
|
+
inviteMessage: options.comment,
|
|
997
|
+
base64Thumb: await window.WWebJS.getProfilePicThumbToBase64(channelWid)
|
|
998
|
+
}
|
|
999
|
+
);
|
|
1000
|
+
}, chatId, channelId, options);
|
|
1001
|
+
|
|
1002
|
+
return response.messageSendResult === 'OK';
|
|
949
1003
|
}
|
|
950
1004
|
|
|
951
1005
|
/**
|
|
@@ -971,7 +1025,7 @@ class Client extends EventEmitter {
|
|
|
971
1025
|
* @returns {Promise<Array<Chat>>}
|
|
972
1026
|
*/
|
|
973
1027
|
async getChats() {
|
|
974
|
-
|
|
1028
|
+
const chats = await this.pupPage.evaluate(async () => {
|
|
975
1029
|
return await window.WWebJS.getChats();
|
|
976
1030
|
});
|
|
977
1031
|
|
|
@@ -979,16 +1033,51 @@ class Client extends EventEmitter {
|
|
|
979
1033
|
}
|
|
980
1034
|
|
|
981
1035
|
/**
|
|
982
|
-
*
|
|
1036
|
+
* Gets all cached {@link Channel} instance
|
|
1037
|
+
* @returns {Promise<Array<Channel>>}
|
|
1038
|
+
*/
|
|
1039
|
+
async getChannels() {
|
|
1040
|
+
const channels = await this.pupPage.evaluate(async () => {
|
|
1041
|
+
return await window.WWebJS.getChannels();
|
|
1042
|
+
});
|
|
1043
|
+
|
|
1044
|
+
return channels.map((channel) => ChatFactory.create(this, channel));
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
/**
|
|
1048
|
+
* Gets chat or channel instance by ID
|
|
983
1049
|
* @param {string} chatId
|
|
984
|
-
* @returns {Promise<Chat>}
|
|
1050
|
+
* @returns {Promise<Chat|Channel>}
|
|
985
1051
|
*/
|
|
986
1052
|
async getChatById(chatId) {
|
|
987
|
-
|
|
1053
|
+
const chat = await this.pupPage.evaluate(async chatId => {
|
|
988
1054
|
return await window.WWebJS.getChat(chatId);
|
|
989
1055
|
}, chatId);
|
|
1056
|
+
return chat
|
|
1057
|
+
? ChatFactory.create(this, chat)
|
|
1058
|
+
: undefined;
|
|
1059
|
+
}
|
|
990
1060
|
|
|
991
|
-
|
|
1061
|
+
/**
|
|
1062
|
+
* Gets a {@link Channel} instance by invite code
|
|
1063
|
+
* @param {string} inviteCode The code that comes after the 'https://whatsapp.com/channel/'
|
|
1064
|
+
* @returns {Promise<Channel>}
|
|
1065
|
+
*/
|
|
1066
|
+
async getChannelByInviteCode(inviteCode) {
|
|
1067
|
+
const channel = await this.pupPage.evaluate(async (inviteCode) => {
|
|
1068
|
+
let channelMetadata;
|
|
1069
|
+
try {
|
|
1070
|
+
channelMetadata = await window.WWebJS.getChannelMetadata(inviteCode);
|
|
1071
|
+
} catch (err) {
|
|
1072
|
+
if (err.name === 'ServerStatusCodeError') return null;
|
|
1073
|
+
throw err;
|
|
1074
|
+
}
|
|
1075
|
+
return await window.WWebJS.getChat(channelMetadata.id);
|
|
1076
|
+
}, inviteCode);
|
|
1077
|
+
|
|
1078
|
+
return channel
|
|
1079
|
+
? ChatFactory.create(this, channel)
|
|
1080
|
+
: undefined;
|
|
992
1081
|
}
|
|
993
1082
|
|
|
994
1083
|
/**
|
|
@@ -1058,6 +1147,61 @@ class Client extends EventEmitter {
|
|
|
1058
1147
|
return res.gid._serialized;
|
|
1059
1148
|
}
|
|
1060
1149
|
|
|
1150
|
+
/**
|
|
1151
|
+
* Accepts a channel admin invitation and promotes the current user to a channel admin
|
|
1152
|
+
* @param {string} channelId The channel ID to accept the admin invitation from
|
|
1153
|
+
* @returns {Promise<boolean>} Returns true if the operation completed successfully, false otherwise
|
|
1154
|
+
*/
|
|
1155
|
+
async acceptChannelAdminInvite(channelId) {
|
|
1156
|
+
return await this.pupPage.evaluate(async (channelId) => {
|
|
1157
|
+
try {
|
|
1158
|
+
await window.Store.ChannelUtils.acceptNewsletterAdminInvite(channelId);
|
|
1159
|
+
return true;
|
|
1160
|
+
} catch (err) {
|
|
1161
|
+
if (err.name === 'ServerStatusCodeError') return false;
|
|
1162
|
+
throw err;
|
|
1163
|
+
}
|
|
1164
|
+
}, channelId);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/**
|
|
1168
|
+
* Revokes a channel admin invitation sent to a user by a channel owner
|
|
1169
|
+
* @param {string} channelId The channel ID an invitation belongs to
|
|
1170
|
+
* @param {string} userId The user ID the invitation was sent to
|
|
1171
|
+
* @returns {Promise<boolean>} Returns true if the operation completed successfully, false otherwise
|
|
1172
|
+
*/
|
|
1173
|
+
async revokeChannelAdminInvite(channelId, userId) {
|
|
1174
|
+
return await this.pupPage.evaluate(async (channelId, userId) => {
|
|
1175
|
+
try {
|
|
1176
|
+
const userWid = window.Store.WidFactory.createWid(userId);
|
|
1177
|
+
await window.Store.ChannelUtils.revokeNewsletterAdminInvite(channelId, userWid);
|
|
1178
|
+
return true;
|
|
1179
|
+
} catch (err) {
|
|
1180
|
+
if (err.name === 'ServerStatusCodeError') return false;
|
|
1181
|
+
throw err;
|
|
1182
|
+
}
|
|
1183
|
+
}, channelId, userId);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
/**
|
|
1187
|
+
* Demotes a channel admin to a regular subscriber (can be used also for self-demotion)
|
|
1188
|
+
* @param {string} channelId The channel ID to demote an admin in
|
|
1189
|
+
* @param {string} userId The user ID to demote
|
|
1190
|
+
* @returns {Promise<boolean>} Returns true if the operation completed successfully, false otherwise
|
|
1191
|
+
*/
|
|
1192
|
+
async demoteChannelAdmin(channelId, userId) {
|
|
1193
|
+
return await this.pupPage.evaluate(async (channelId, userId) => {
|
|
1194
|
+
try {
|
|
1195
|
+
const userWid = window.Store.WidFactory.createWid(userId);
|
|
1196
|
+
await window.Store.ChannelUtils.demoteNewsletterAdmin(channelId, userWid);
|
|
1197
|
+
return true;
|
|
1198
|
+
} catch (err) {
|
|
1199
|
+
if (err.name === 'ServerStatusCodeError') return false;
|
|
1200
|
+
throw err;
|
|
1201
|
+
}
|
|
1202
|
+
}, channelId, userId);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1061
1205
|
/**
|
|
1062
1206
|
* Accepts a private invitation to join a group
|
|
1063
1207
|
* @param {object} inviteInfo Invite V4 Info
|
|
@@ -1134,7 +1278,7 @@ class Client extends EventEmitter {
|
|
|
1134
1278
|
*/
|
|
1135
1279
|
async archiveChat(chatId) {
|
|
1136
1280
|
return await this.pupPage.evaluate(async chatId => {
|
|
1137
|
-
let chat = await window.
|
|
1281
|
+
let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
|
1138
1282
|
await window.Store.Cmd.archiveChat(chat, true);
|
|
1139
1283
|
return true;
|
|
1140
1284
|
}, chatId);
|
|
@@ -1146,7 +1290,7 @@ class Client extends EventEmitter {
|
|
|
1146
1290
|
*/
|
|
1147
1291
|
async unarchiveChat(chatId) {
|
|
1148
1292
|
return await this.pupPage.evaluate(async chatId => {
|
|
1149
|
-
let chat = await window.
|
|
1293
|
+
let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
|
1150
1294
|
await window.Store.Cmd.archiveChat(chat, false);
|
|
1151
1295
|
return false;
|
|
1152
1296
|
}, chatId);
|
|
@@ -1158,7 +1302,7 @@ class Client extends EventEmitter {
|
|
|
1158
1302
|
*/
|
|
1159
1303
|
async pinChat(chatId) {
|
|
1160
1304
|
return this.pupPage.evaluate(async chatId => {
|
|
1161
|
-
let chat = window.
|
|
1305
|
+
let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
|
1162
1306
|
if (chat.pin) {
|
|
1163
1307
|
return true;
|
|
1164
1308
|
}
|
|
@@ -1181,7 +1325,7 @@ class Client extends EventEmitter {
|
|
|
1181
1325
|
*/
|
|
1182
1326
|
async unpinChat(chatId) {
|
|
1183
1327
|
return this.pupPage.evaluate(async chatId => {
|
|
1184
|
-
let chat = window.
|
|
1328
|
+
let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
|
1185
1329
|
if (!chat.pin) {
|
|
1186
1330
|
return false;
|
|
1187
1331
|
}
|
|
@@ -1233,7 +1377,7 @@ class Client extends EventEmitter {
|
|
|
1233
1377
|
*/
|
|
1234
1378
|
async markChatUnread(chatId) {
|
|
1235
1379
|
await this.pupPage.evaluate(async chatId => {
|
|
1236
|
-
let chat = await window.
|
|
1380
|
+
let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
|
1237
1381
|
await window.Store.Cmd.markChatUnread(chat, true);
|
|
1238
1382
|
}, chatId);
|
|
1239
1383
|
}
|
|
@@ -1435,7 +1579,7 @@ class Client extends EventEmitter {
|
|
|
1435
1579
|
for (const participant of createGroupResult.participants) {
|
|
1436
1580
|
let isInviteV4Sent = false;
|
|
1437
1581
|
const participantId = participant.wid._serialized;
|
|
1438
|
-
const statusCode = participant.error
|
|
1582
|
+
const statusCode = participant.error || 200;
|
|
1439
1583
|
|
|
1440
1584
|
if (autoSendInviteV4 && statusCode === 403) {
|
|
1441
1585
|
window.Store.Contact.gadd(participant.wid, { silent: true });
|
|
@@ -1474,6 +1618,219 @@ class Client extends EventEmitter {
|
|
|
1474
1618
|
}, title, participants, options);
|
|
1475
1619
|
}
|
|
1476
1620
|
|
|
1621
|
+
/**
|
|
1622
|
+
* An object that handles the result for {@link createChannel} method
|
|
1623
|
+
* @typedef {Object} CreateChannelResult
|
|
1624
|
+
* @property {string} title A channel title
|
|
1625
|
+
* @property {ChatId} nid An object that handels the newly created channel ID
|
|
1626
|
+
* @property {string} nid.server 'newsletter'
|
|
1627
|
+
* @property {string} nid.user 'XXXXXXXXXX'
|
|
1628
|
+
* @property {string} nid._serialized 'XXXXXXXXXX@newsletter'
|
|
1629
|
+
* @property {string} inviteLink The channel invite link, starts with 'https://whatsapp.com/channel/'
|
|
1630
|
+
* @property {number} createdAtTs The timestamp the channel was created at
|
|
1631
|
+
*/
|
|
1632
|
+
|
|
1633
|
+
/**
|
|
1634
|
+
* Options for the channel creation
|
|
1635
|
+
* @typedef {Object} CreateChannelOptions
|
|
1636
|
+
* @property {?string} description The channel description
|
|
1637
|
+
* @property {?MessageMedia} picture The channel profile picture
|
|
1638
|
+
*/
|
|
1639
|
+
|
|
1640
|
+
/**
|
|
1641
|
+
* Creates a new channel
|
|
1642
|
+
* @param {string} title The channel name
|
|
1643
|
+
* @param {CreateChannelOptions} options
|
|
1644
|
+
* @returns {Promise<CreateChannelResult|string>} Returns an object that handles the result for the channel creation or an error message as a string
|
|
1645
|
+
*/
|
|
1646
|
+
async createChannel(title, options = {}) {
|
|
1647
|
+
return await this.pupPage.evaluate(async (title, options) => {
|
|
1648
|
+
let response, { description = null, picture = null } = options;
|
|
1649
|
+
|
|
1650
|
+
if (!window.Store.ChannelUtils.isNewsletterCreationEnabled()) {
|
|
1651
|
+
return 'CreateChannelError: A channel creation is not enabled';
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
if (picture) {
|
|
1655
|
+
picture = await window.WWebJS.cropAndResizeImage(picture, {
|
|
1656
|
+
asDataUrl: true,
|
|
1657
|
+
mimetype: 'image/jpeg',
|
|
1658
|
+
size: 640,
|
|
1659
|
+
quality: 1
|
|
1660
|
+
});
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
try {
|
|
1664
|
+
response = await window.Store.ChannelUtils.createNewsletterQuery({
|
|
1665
|
+
name: title,
|
|
1666
|
+
description: description,
|
|
1667
|
+
picture: picture,
|
|
1668
|
+
});
|
|
1669
|
+
} catch (err) {
|
|
1670
|
+
if (err.name === 'ServerStatusCodeError') {
|
|
1671
|
+
return 'CreateChannelError: An error occupied while creating a channel';
|
|
1672
|
+
}
|
|
1673
|
+
throw err;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
return {
|
|
1677
|
+
title: title,
|
|
1678
|
+
nid: window.Store.JidToWid.newsletterJidToWid(response.idJid),
|
|
1679
|
+
inviteLink: `https://whatsapp.com/channel/${response.newsletterInviteLinkMetadataMixin.inviteCode}`,
|
|
1680
|
+
createdAtTs: response.newsletterCreationTimeMetadataMixin.creationTimeValue
|
|
1681
|
+
};
|
|
1682
|
+
}, title, options);
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
/**
|
|
1686
|
+
* Subscribe to channel
|
|
1687
|
+
* @param {string} channelId The channel ID
|
|
1688
|
+
* @returns {Promise<boolean>} Returns true if the operation completed successfully, false otherwise
|
|
1689
|
+
*/
|
|
1690
|
+
async subscribeToChannel(channelId) {
|
|
1691
|
+
return await this.pupPage.evaluate(async (channelId) => {
|
|
1692
|
+
return await window.WWebJS.subscribeToUnsubscribeFromChannel(channelId, 'Subscribe');
|
|
1693
|
+
}, channelId);
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
/**
|
|
1697
|
+
* Options for unsubscribe from a channel
|
|
1698
|
+
* @typedef {Object} UnsubscribeOptions
|
|
1699
|
+
* @property {boolean} [deleteLocalModels = false] If true, after an unsubscription, it will completely remove a channel from the channel collection making it seem like the current user have never interacted with it. Otherwise it will only remove a channel from the list of channels the current user is subscribed to and will set the membership type for that channel to GUEST
|
|
1700
|
+
*/
|
|
1701
|
+
|
|
1702
|
+
/**
|
|
1703
|
+
* Unsubscribe from channel
|
|
1704
|
+
* @param {string} channelId The channel ID
|
|
1705
|
+
* @param {UnsubscribeOptions} options
|
|
1706
|
+
* @returns {Promise<boolean>} Returns true if the operation completed successfully, false otherwise
|
|
1707
|
+
*/
|
|
1708
|
+
async unsubscribeFromChannel(channelId, options) {
|
|
1709
|
+
return await this.pupPage.evaluate(async (channelId, options) => {
|
|
1710
|
+
return await window.WWebJS.subscribeToUnsubscribeFromChannel(channelId, 'Unsubscribe', options);
|
|
1711
|
+
}, channelId, options);
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
/**
|
|
1715
|
+
* Options for transferring a channel ownership to another user
|
|
1716
|
+
* @typedef {Object} TransferChannelOwnershipOptions
|
|
1717
|
+
* @property {boolean} [shouldDismissSelfAsAdmin = false] If true, after the channel ownership is being transferred to another user, the current user will be dismissed as a channel admin and will become to a channel subscriber.
|
|
1718
|
+
*/
|
|
1719
|
+
|
|
1720
|
+
/**
|
|
1721
|
+
* Transfers a channel ownership to another user.
|
|
1722
|
+
* Note: the user you are transferring the channel ownership to must be a channel admin.
|
|
1723
|
+
* @param {string} channelId
|
|
1724
|
+
* @param {string} newOwnerId
|
|
1725
|
+
* @param {TransferChannelOwnershipOptions} options
|
|
1726
|
+
* @returns {Promise<boolean>} Returns true if the operation completed successfully, false otherwise
|
|
1727
|
+
*/
|
|
1728
|
+
async transferChannelOwnership(channelId, newOwnerId, options = {}) {
|
|
1729
|
+
return await this.pupPage.evaluate(async (channelId, newOwnerId, options) => {
|
|
1730
|
+
const channel = await window.WWebJS.getChat(channelId, { getAsModel: false });
|
|
1731
|
+
const newOwner = window.Store.Contact.get(newOwnerId) || (await window.Store.Contact.find(newOwnerId));
|
|
1732
|
+
if (!channel.newsletterMetadata) {
|
|
1733
|
+
await window.Store.NewsletterMetadataCollection.update(channel.id);
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
try {
|
|
1737
|
+
await window.Store.ChannelUtils.changeNewsletterOwnerAction(channel, newOwner);
|
|
1738
|
+
|
|
1739
|
+
if (options.shouldDismissSelfAsAdmin) {
|
|
1740
|
+
const meContact = window.Store.ContactCollection.getMeContact();
|
|
1741
|
+
meContact && (await window.Store.ChannelUtils.demoteNewsletterAdminAction(channel, meContact));
|
|
1742
|
+
}
|
|
1743
|
+
} catch (error) {
|
|
1744
|
+
return false;
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
return true;
|
|
1748
|
+
}, channelId, newOwnerId, options);
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
/**
|
|
1752
|
+
* Searches for channels based on search criteria, there are some notes:
|
|
1753
|
+
* 1. The method finds only channels you are not subscribed to currently
|
|
1754
|
+
* 2. If you have never been subscribed to a found channel
|
|
1755
|
+
* or you have unsubscribed from it with {@link UnsubscribeOptions.deleteLocalModels} set to 'true',
|
|
1756
|
+
* the lastMessage property of a found channel will be 'null'
|
|
1757
|
+
*
|
|
1758
|
+
* @param {Object} searchOptions Search options
|
|
1759
|
+
* @param {string} [searchOptions.searchText = ''] Text to search
|
|
1760
|
+
* @param {Array<string>} [searchOptions.countryCodes = [your local region]] Array of country codes in 'ISO 3166-1 alpha-2' standart (@see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) to search for channels created in these countries
|
|
1761
|
+
* @param {boolean} [searchOptions.skipSubscribedNewsletters = false] If true, channels that user is subscribed to won't appear in found channels
|
|
1762
|
+
* @param {number} [searchOptions.view = 0] View type, makes sense only when the searchText is empty. Valid values to provide are:
|
|
1763
|
+
* 0 for RECOMMENDED channels
|
|
1764
|
+
* 1 for TRENDING channels
|
|
1765
|
+
* 2 for POPULAR channels
|
|
1766
|
+
* 3 for NEW channels
|
|
1767
|
+
* @param {number} [searchOptions.limit = 50] The limit of found channels to be appear in the returnig result
|
|
1768
|
+
* @returns {Promise<Array<Channel>|[]>} Returns an array of Channel objects or an empty array if no channels were found
|
|
1769
|
+
*/
|
|
1770
|
+
async searchChannels(searchOptions = {}) {
|
|
1771
|
+
return await this.pupPage.evaluate(async ({
|
|
1772
|
+
searchText = '',
|
|
1773
|
+
countryCodes = [window.Store.ChannelUtils.currentRegion],
|
|
1774
|
+
skipSubscribedNewsletters = false,
|
|
1775
|
+
view = 0,
|
|
1776
|
+
limit = 50
|
|
1777
|
+
}) => {
|
|
1778
|
+
searchText = searchText.trim();
|
|
1779
|
+
const currentRegion = window.Store.ChannelUtils.currentRegion;
|
|
1780
|
+
if (![0, 1, 2, 3].includes(view)) view = 0;
|
|
1781
|
+
|
|
1782
|
+
countryCodes = countryCodes.length === 1 && countryCodes[0] === currentRegion
|
|
1783
|
+
? countryCodes
|
|
1784
|
+
: countryCodes.filter((code) => Object.keys(window.Store.ChannelUtils.countryCodesIso).includes(code));
|
|
1785
|
+
|
|
1786
|
+
const viewTypeMapping = {
|
|
1787
|
+
0: 'RECOMMENDED',
|
|
1788
|
+
1: 'TRENDING',
|
|
1789
|
+
2: 'POPULAR',
|
|
1790
|
+
3: 'NEW'
|
|
1791
|
+
};
|
|
1792
|
+
|
|
1793
|
+
searchOptions = {
|
|
1794
|
+
searchText: searchText,
|
|
1795
|
+
countryCodes: countryCodes,
|
|
1796
|
+
skipSubscribedNewsletters: skipSubscribedNewsletters,
|
|
1797
|
+
view: viewTypeMapping[view],
|
|
1798
|
+
categories: [],
|
|
1799
|
+
cursorToken: ''
|
|
1800
|
+
};
|
|
1801
|
+
|
|
1802
|
+
const originalFunction = window.Store.ChannelUtils.getNewsletterDirectoryPageSize;
|
|
1803
|
+
limit !== 50 && (window.Store.ChannelUtils.getNewsletterDirectoryPageSize = () => limit);
|
|
1804
|
+
|
|
1805
|
+
const channels = (await window.Store.ChannelUtils.fetchNewsletterDirectories(searchOptions)).newsletters;
|
|
1806
|
+
|
|
1807
|
+
limit !== 50 && (window.Store.ChannelUtils.getNewsletterDirectoryPageSize = originalFunction);
|
|
1808
|
+
|
|
1809
|
+
return channels
|
|
1810
|
+
? await Promise.all(channels.map((channel) => window.WWebJS.getChatModel(channel, { isChannel: true })))
|
|
1811
|
+
: [];
|
|
1812
|
+
}, searchOptions);
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
/**
|
|
1816
|
+
* Deletes the channel you created
|
|
1817
|
+
* @param {string} channelId The ID of a channel to delete
|
|
1818
|
+
* @returns {Promise<boolean>} Returns true if the operation completed successfully, false otherwise
|
|
1819
|
+
*/
|
|
1820
|
+
async deleteChannel(channelId) {
|
|
1821
|
+
return await this.client.pupPage.evaluate(async (channelId) => {
|
|
1822
|
+
const channel = await window.WWebJS.getChat(channelId, { getAsModel: false });
|
|
1823
|
+
if (!channel) return false;
|
|
1824
|
+
try {
|
|
1825
|
+
await window.Store.ChannelUtils.deleteNewsletterAction(channel);
|
|
1826
|
+
return true;
|
|
1827
|
+
} catch (err) {
|
|
1828
|
+
if (err.name === 'ServerStatusCodeError') return false;
|
|
1829
|
+
throw err;
|
|
1830
|
+
}
|
|
1831
|
+
}, channelId);
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1477
1834
|
/**
|
|
1478
1835
|
* Get all current Labels
|
|
1479
1836
|
* @returns {Promise<Array<Label>>}
|
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
const PrivateChat = require('../structures/PrivateChat');
|
|
4
4
|
const GroupChat = require('../structures/GroupChat');
|
|
5
|
+
const Channel = require('../structures/Channel');
|
|
5
6
|
|
|
6
7
|
class ChatFactory {
|
|
7
8
|
static create(client, data) {
|
|
8
|
-
if(data.isGroup) {
|
|
9
|
+
if (data.isGroup) {
|
|
9
10
|
return new GroupChat(client, data);
|
|
10
11
|
}
|
|
12
|
+
|
|
13
|
+
if (data.isChannel) {
|
|
14
|
+
return new Channel(client, data);
|
|
15
|
+
}
|
|
11
16
|
|
|
12
17
|
return new PrivateChat(client, data);
|
|
13
18
|
}
|
|
14
19
|
}
|
|
15
20
|
|
|
16
|
-
module.exports = ChatFactory;
|
|
21
|
+
module.exports = ChatFactory;
|