@imaentity/selfjs 4.0.1 → 4.2.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.
Files changed (3) hide show
  1. package/docs.md +485 -84
  2. package/package.json +5 -3
  3. package/self.js +224 -10
package/docs.md CHANGED
@@ -17,8 +17,6 @@ npm install @imaentity/selfjs
17
17
  const self = require("@imaentity/selfjs");
18
18
  ```
19
19
 
20
- ---
21
-
22
20
  # Constants
23
21
 
24
22
  ## `Status`
@@ -34,8 +32,6 @@ Status.CUSTOM_STATUS // 4
34
32
  Status.COMPETING // 5
35
33
  ```
36
34
 
37
- ---
38
-
39
35
  # Functions
40
36
 
41
37
  ## `validateToken(token)`
@@ -61,20 +57,14 @@ Promise<Object | null>
61
57
  ```javascript
62
58
  const user = await self.validateToken(token);
63
59
 
64
- if(user)
65
- console.log(`Logged in as ${user.username}`);
66
- else
67
- console.log("Invalid token");
60
+ if(user) console.log(`Logged in as ${user.username}`);
61
+ else console.log("Invalid token");
68
62
  ```
69
63
 
70
- ---
71
-
72
64
  ## `createToken(options)`
73
65
 
74
- Attempts to log into a Discord account using an email and password.
75
-
76
- If MFA is not enabled, the returned object contains the token immediately.
77
-
66
+ Attempts to log into a Discord account using an email and password.
67
+ If MFA is not enabled, the returned object contains the token immediately.
78
68
  If MFA is required, the returned object contains the available MFA methods and a `confirmMFA()` function.
79
69
 
80
70
  ### Parameters
@@ -120,12 +110,9 @@ const login = await self.createToken({
120
110
  password: "password"
121
111
  });
122
112
 
123
- if(!login)
124
- throw new Error("Login failed");
125
-
126
- if(!login.mfaRequired) {
127
- console.log(login.token);
128
- } else {
113
+ if(!login) throw new Error("Login failed");
114
+ if(!login.mfaRequired) console.log(login.token);
115
+ else {
129
116
  console.log("MFA methods:", login.mfaMethods);
130
117
 
131
118
  const result = await login.confirmMFA("totp", {
@@ -136,15 +123,12 @@ if(!login.mfaRequired) {
136
123
  }
137
124
  ```
138
125
 
139
- > [!NOTE]
126
+ > [!NOTE]
140
127
  > SMS MFA is currently unsupported.
141
128
 
142
- ---
143
-
144
129
  ## `snowflakeToUTC(snowflake)`
145
130
 
146
- Converts a Discord snowflake into a UTC timestamp.
147
-
131
+ Converts a Discord snowflake into a UTC timestamp.
148
132
  The returned timestamp is in milliseconds since Unix epoch.
149
133
 
150
134
  ### Parameters
@@ -163,16 +147,12 @@ Number
163
147
 
164
148
  ```javascript
165
149
  const timestamp = self.snowflakeToUTC("1329029486758592595");
166
-
167
150
  console.log(new Date(timestamp));
168
151
  ```
169
152
 
170
- ---
171
-
172
153
  ## `UTCToSnowflake(timestamp)`
173
154
 
174
- Converts a UTC timestamp into a Discord snowflake.
175
-
155
+ Converts a UTC timestamp into a Discord snowflake.
176
156
  The generated snowflake only contains the timestamp portion. Worker ID, process ID, and sequence values are zero.
177
157
 
178
158
  ### Parameters
@@ -191,12 +171,9 @@ String
191
171
 
192
172
  ```javascript
193
173
  const snowflake = self.UTCToSnowflake(Date.now());
194
-
195
174
  console.log(snowflake);
196
175
  ```
197
176
 
198
- ---
199
-
200
177
  # Client
201
178
 
202
179
  `Client` provides an interface for connecting to Discord and interacting with the account.
@@ -218,7 +195,6 @@ const client = new self.Client({
218
195
  },
219
196
 
220
197
  debugLogs: true,
221
-
222
198
  intents: 0
223
199
  });
224
200
  ```
@@ -229,8 +205,6 @@ const client = new self.Client({
229
205
  | `debugLogs` | `Boolean` | `true` | Enables SelfJS debug logging. |
230
206
  | `intents` | `Number` | `null` | Gateway intents, used for bot accounts. |
231
207
 
232
- ---
233
-
234
208
  # Properties
235
209
 
236
210
  ## `client.user`
@@ -243,8 +217,6 @@ console.log(client.user);
243
217
 
244
218
  This is populated after the `READY` event.
245
219
 
246
- ---
247
-
248
220
  ## `client.token`
249
221
 
250
222
  The token currently being used by the client.
@@ -253,8 +225,6 @@ The token currently being used by the client.
253
225
  console.log(client.token);
254
226
  ```
255
227
 
256
- ---
257
-
258
228
  ## `client.latency`
259
229
 
260
230
  The time between sending a heartbeat and receiving its acknowledgement.
@@ -265,8 +235,6 @@ console.log(client.latency);
265
235
 
266
236
  The value is in milliseconds.
267
237
 
268
- ---
269
-
270
238
  # Login
271
239
 
272
240
  ## `client.login(token)`
@@ -287,8 +255,6 @@ client.login(token);
287
255
 
288
256
  Once connected, events can be received using `client.on()`.
289
257
 
290
- ---
291
-
292
258
  # Events
293
259
 
294
260
  `Client` extends Node.js `EventEmitter`, so events can be listened to using `.on()`.
@@ -309,8 +275,6 @@ client.on("READY", data => {
309
275
  });
310
276
  ```
311
277
 
312
- ---
313
-
314
278
  ## `MESSAGE_CREATE`
315
279
 
316
280
  Emitted when a message is received.
@@ -350,8 +314,6 @@ client.on("MESSAGE_CREATE", message => {
350
314
  });
351
315
  ```
352
316
 
353
- ---
354
-
355
317
  ## `DISCONNECT`
356
318
 
357
319
  Emitted when the Gateway connection closes.
@@ -362,8 +324,6 @@ client.on("DISCONNECT", () => {
362
324
  });
363
325
  ```
364
326
 
365
- ---
366
-
367
327
  ## `INVALID_SESSION`
368
328
 
369
329
  Emitted when Discord invalidates the current session and it cannot be resumed.
@@ -374,8 +334,6 @@ client.on("INVALID_SESSION", () => {
374
334
  });
375
335
  ```
376
336
 
377
- ---
378
-
379
337
  # Messages
380
338
 
381
339
  ## `client.sendMessage(message)`
@@ -436,8 +394,6 @@ await client.sendMessage({
436
394
  });
437
395
  ```
438
396
 
439
- ---
440
-
441
397
  ## `client.editMessage(message)`
442
398
 
443
399
  Edits an existing message.
@@ -462,8 +418,6 @@ await client.editMessage({
462
418
  });
463
419
  ```
464
420
 
465
- ---
466
-
467
421
  ## `client.getMessages(options)`
468
422
 
469
423
  Gets recent messages from a channel.
@@ -479,7 +433,7 @@ Gets recent messages from a channel.
479
433
  ### Returns
480
434
 
481
435
  ```javascript
482
- Promise<Array>
436
+ Promise<Array<Object>>
483
437
  ```
484
438
 
485
439
  Messages are returned from newest to oldest.
@@ -493,8 +447,6 @@ const messages = await client.getMessages({
493
447
  });
494
448
  ```
495
449
 
496
- ---
497
-
498
450
  ## `client.ackMessage(message)`
499
451
 
500
452
  Acknowledges a message, removing its unread notification.
@@ -521,8 +473,6 @@ await client.ackMessage({
521
473
  });
522
474
  ```
523
475
 
524
- ---
525
-
526
476
  # Reactions
527
477
 
528
478
  ## `client.addReaction(options)`
@@ -547,8 +497,6 @@ await client.addReaction({
547
497
  });
548
498
  ```
549
499
 
550
- ---
551
-
552
500
  ## `client.removeReaction(options)`
553
501
 
554
502
  Removes the client's reaction from a message.
@@ -571,9 +519,25 @@ await client.removeReaction({
571
519
  });
572
520
  ```
573
521
 
574
- ---
522
+ # Channels
523
+
524
+ ## `client.getOpenChannels()`
525
+
526
+ Gets the channels currently present in the account's DM list.
527
+ This can contain both direct messages and group DMs.
528
+
529
+ ### Returns
530
+
531
+ ```javascript
532
+ Promise<Array<Object>>
533
+ ```
534
+
535
+ ### Example
575
536
 
576
- # Search
537
+ ```javascript
538
+ const channels = await client.getOpenChannels();
539
+ console.log(channels);
540
+ ```
577
541
 
578
542
  ## `client.search(options)`
579
543
 
@@ -650,15 +614,16 @@ const results = await client.search({
650
614
  });
651
615
  ```
652
616
 
653
- ---
654
617
 
655
- # Channels
618
+ ## `client.createGroupDM(recipients)`
656
619
 
657
- ## `client.getOpenChannels()`
620
+ Creates a group DM with the specified users.
658
621
 
659
- Gets the channels currently present in the account's DM list.
622
+ ### Parameters
660
623
 
661
- This can contain both direct messages and group DMs.
624
+ | Name | Type | Description |
625
+ | ------------ | --------------- | ----------------------------- |
626
+ | `recipients` | `Array<String>` | User IDs to add to the group. |
662
627
 
663
628
  ### Returns
664
629
 
@@ -666,15 +631,463 @@ This can contain both direct messages and group DMs.
666
631
  Promise<Object>
667
632
  ```
668
633
 
634
+ The new channel object.
635
+
669
636
  ### Example
670
637
 
671
638
  ```javascript
672
- const channels = await client.getOpenChannels();
673
- console.log(channels);
639
+ const group = await client.createGroupDM([
640
+ "123456789",
641
+ "987654321"
642
+ ]);
643
+
644
+ console.log(group.id);
645
+ ```
646
+
647
+ ## `client.addToGroup(options)`
648
+
649
+ Adds a user to a group DM. The logged-in account must be friends with the user.
650
+
651
+ ### Parameters
652
+
653
+ | Name | Type | Description |
654
+ | -------------------- | -------- | -------------------- |
655
+ | `options.channel_id` | `String` | Group DM channel ID. |
656
+ | `options.user_id` | `String` | User ID to add. |
657
+
658
+ ### Returns
659
+
660
+ ```javascript
661
+ Promise<void>
662
+ ```
663
+
664
+ ### Example
665
+
666
+ ```javascript
667
+ await client.addToGroup({
668
+ channel_id: "123456789",
669
+ user_id: "987654321"
670
+ });
671
+ ```
672
+
673
+ ## `client.removeFromGroup(options)`
674
+
675
+ Removes a user from a group DM. The logged-in account must own the group.
676
+
677
+ ### Parameters
678
+
679
+ | Name | Type | Description |
680
+ | -------------------- | -------- | -------------------- |
681
+ | `options.channel_id` | `String` | Group DM channel ID. |
682
+ | `options.user_id` | `String` | User ID to remove. |
683
+
684
+ ### Returns
685
+
686
+ ```javascript
687
+ Promise<void>
688
+ ```
689
+
690
+ ### Example
691
+
692
+ ```javascript
693
+ await client.removeFromGroup({
694
+ channel_id: "123456789",
695
+ user_id: "987654321"
696
+ });
697
+ ```
698
+
699
+ ## `client.transferGroup(options)`
700
+
701
+ Transfers ownership of a group DM to another member.
702
+
703
+ ### Parameters
704
+
705
+ | Name | Type | Description |
706
+ | -------------------- | -------- | ----------------------------- |
707
+ | `options.channel_id` | `String` | Group DM channel ID. |
708
+ | `options.user_id` | `String` | User ID to give ownership to. |
709
+
710
+ ### Returns
711
+
712
+ ```javascript
713
+ Promise<Object>
714
+ ```
715
+
716
+ The updated channel object.
717
+
718
+ ### Example
719
+
720
+ ```javascript
721
+ const group = await client.transferGroup({
722
+ channel_id: "123456789",
723
+ user_id: "987654321"
724
+ });
725
+
726
+ console.log(group.owner_id);
727
+ ```
728
+
729
+ ## `client.leaveGroup(options)`
730
+
731
+ Leaves a group DM.
732
+
733
+ ### Parameters
734
+
735
+ | Name | Type | Description |
736
+ | -------------------- | --------- | -------------------------------------------------- |
737
+ | `options.channel_id` | `String` | Group DM channel ID. |
738
+ | `options.silent` | `Boolean` | If `true`, does not notify the group of the leave. |
739
+
740
+ ### Returns
741
+
742
+ ```javascript
743
+ Promise<Object>
744
+ ```
745
+
746
+ ### Example
747
+
748
+ ```javascript
749
+ await client.leaveGroup({
750
+ channel_id: "123456789",
751
+ silent: true
752
+ });
753
+ ```
754
+
755
+ ## `client.startTyping(channel_id)`
756
+
757
+ Starts the typing indicator in a channel.
758
+ The indicator lasts for 10 seconds. Calling this again before it expires resets the timer. Sending a message clears the indicator.
759
+
760
+ ### Parameters
761
+
762
+ | Name | Type | Description |
763
+ | ------------ | -------- | ------------------------------ |
764
+ | `channel_id` | `String` | Channel ID to start typing in. |
765
+
766
+ ### Returns
767
+
768
+ ```javascript
769
+ Promise<void>
770
+ ```
771
+
772
+ ### Example
773
+
774
+ ```javascript
775
+ await client.startTyping("123456789");
776
+ ```
777
+
778
+ ## `client.pinMessage(options)`
779
+
780
+ Pins a message in a channel.
781
+
782
+ ### Parameters
783
+
784
+ | Name | Type | Description |
785
+ | -------------------- | -------- | ----------- |
786
+ | `options.channel_id` | `String` | Channel ID. |
787
+ | `options.message_id` | `String` | Message ID. |
788
+
789
+ ### Returns
790
+
791
+ ```javascript
792
+ Promise<void>
793
+ ```
794
+
795
+ ### Example
796
+
797
+ ```javascript
798
+ await client.pinMessage({
799
+ channel_id: "123456789",
800
+ message_id: "987654321"
801
+ });
802
+ ```
803
+
804
+ ## `client.unpinMessage(options)`
805
+
806
+ Unpins a message from a channel.
807
+
808
+ ### Parameters
809
+
810
+ | Name | Type | Description |
811
+ | -------------------- | -------- | ----------- |
812
+ | `options.channel_id` | `String` | Channel ID. |
813
+ | `options.message_id` | `String` | Message ID. |
814
+
815
+ ### Returns
816
+
817
+ ```javascript
818
+ Promise<void>
819
+ ```
820
+
821
+ ### Example
822
+
823
+ ```javascript
824
+ await client.unpinMessage({
825
+ channel_id: "123456789",
826
+ message_id: "987654321"
827
+ });
828
+ ```
829
+
830
+ ## `client.getChannelObject(channel_id)`
831
+
832
+ Gets the current channel object using its ID.
833
+ This works for DMs, group DMs, server text channels, and server voice channels.
834
+
835
+ ### Parameters
836
+
837
+ | Name | Type | Description |
838
+ | ------------ | -------- | ----------- |
839
+ | `channel_id` | `String` | Channel ID. |
840
+
841
+ ### Returns
842
+
843
+ ```javascript
844
+ Promise<Object>
845
+ ```
846
+
847
+ The current channel object.
848
+
849
+ ### Example
850
+
851
+ ```javascript
852
+ const channel = await client.getChannelObject("123456789");
853
+ console.log(channel);
854
+ ```
855
+
856
+ ## `client.getDMChannel(user_id)`
857
+
858
+ Gets the channel object for DMs with a certain user
859
+ Getting the channel object also opens the channel in the active DM list
860
+
861
+ ### Parameters
862
+
863
+ | Name | Type | Description |
864
+ | --------- | -------- | ----------- |
865
+ | `user_id` | `String` | User ID. |
866
+
867
+ ### Returns
868
+
869
+ ```javascript
870
+ Promise<Object>
871
+ ```
872
+
873
+ The DM channel object.
874
+
875
+ ### Example
876
+
877
+ ```javascript
878
+ const channel = await client.getDMChannel("123456789");
879
+ console.log(channel);
880
+ ```
881
+
882
+ ## `client.closeDMChannel(user_id)`
883
+
884
+ Closes and hides the DM channel for a certain user from the active list
885
+
886
+ ### Parameters
887
+
888
+ | Name | Type | Description |
889
+ | --------- | -------- | ----------- |
890
+ | `user_id` | `String` | User ID. |
891
+
892
+ ### Returns
893
+
894
+ ```javascript
895
+ Promise<Object>
896
+ ```
897
+
898
+ The DM channel object.
899
+
900
+ ### Example
901
+
902
+ ```javascript
903
+ const channel = await client.getDMChannel("123456789");
904
+ console.log(channel);
905
+ ```
906
+
907
+ # Users
908
+
909
+ ## `client.getUserProfile(options)`
910
+
911
+ Gets a user's profile.
912
+ The request succeeds if at least one of these is true:
913
+
914
+ * The client shares a server with the user.
915
+ * The client is friends with the user.
916
+ * The user has sent a friend request to the client.
917
+ * The user is a bot.
918
+
919
+ ### Parameters
920
+
921
+ | Name | Type | Description |
922
+ | ----------------------------------- | --------- | ---------------------------------------------- |
923
+ | `options` | `Object` | Profile request options. |
924
+ | `options.user_id` | `String` | ID of the user to get. |
925
+ | `options.with_mutual_guilds` | `Boolean` | Include mutual servers. Defaults to `true`. |
926
+ | `options.with_mutual_friends` | `Boolean` | Include mutual friends. |
927
+ | `options.with_mutual_friends_count` | `Boolean` | Include the number of mutual friends. |
928
+ | `options.guild_id` | `String` | Get the user's server profile for this server. |
929
+
930
+ ### Returns
931
+
932
+ ```javascript
933
+ Promise<Object>
934
+ ```
935
+
936
+ The user's profile.
937
+
938
+ If none of the access conditions are met, Discord returns a `404` error.
939
+
940
+ ### Example
941
+
942
+ ```javascript
943
+ const profile = await client.getUserProfile({
944
+ user_id: "123456789"
945
+ });
946
+
947
+ console.log(profile);
948
+ ```
949
+
950
+ ### Example with mutual friends
951
+
952
+ ```javascript
953
+ const profile = await client.getUserProfile({
954
+ user_id: "123456789",
955
+ with_mutual_friends: true,
956
+ with_mutual_friends_count: true
957
+ });
958
+ ```
959
+
960
+ ### Example with a server profile
961
+
962
+ ```javascript
963
+ const profile = await client.getUserProfile({
964
+ user_id: "123456789",
965
+ guild_id: "987654321"
966
+ });
967
+ ```
968
+
969
+ # User Settings
970
+
971
+ ## `client.getUserSettings()`
972
+
973
+ Gets the `PreloadedUserSettings` protobuf containing general account settings.
974
+ The protobuf is decoded into a JavaScript object.
975
+
976
+ ### Returns
977
+
978
+ ```javascript
979
+ Promise<Object>
980
+ ```
981
+
982
+ ### Example
983
+
984
+ ```javascript
985
+ const settings = await client.getUserSettings();
986
+ console.log(settings);
987
+ ```
988
+
989
+ ## `client.getFrecencySettings()`
990
+
991
+ Gets the `FrecencyUserSettings` protobuf.
992
+ This contains frecency and favorite data for GIFs, emojis, stickers, and similar items.
993
+ The protobuf is decoded into a JavaScript object.
994
+
995
+ ### Returns
996
+
997
+ ```javascript
998
+ Promise<Object>
999
+ ```
1000
+
1001
+ ### Example
1002
+
1003
+ ```javascript
1004
+ const settings = await client.getFrecencySettings();
1005
+ console.log(settings);
674
1006
  ```
675
1007
 
676
1008
  ---
677
1009
 
1010
+ ## `client.updateUserSettings(buf)`
1011
+
1012
+ Updates the `PreloadedUserSettings` protobuf.
1013
+ The provided object is encoded into a protobuf and sent to Discord.
1014
+
1015
+ ### Parameters
1016
+
1017
+ | Name | Type | Description |
1018
+ | ----- | -------- | ------------------ |
1019
+ | `buf` | `Object` | New settings data. |
1020
+
1021
+ ### Returns
1022
+
1023
+ ```javascript
1024
+ Promise<Object>
1025
+ ```
1026
+
1027
+ The updated settings.
1028
+
1029
+ ### Example
1030
+
1031
+ ```javascript
1032
+ const settings = await client.updateUserSettings({
1033
+ // settings data
1034
+ });
1035
+
1036
+ console.log(settings);
1037
+ ```
1038
+
1039
+ ## `client.updateFrecencySettings(buf)`
1040
+
1041
+ Updates the `FrecencyUserSettings` protobuf.
1042
+ The provided object is encoded into a protobuf and sent to Discord.
1043
+ This controls frecency and favorite data for GIFs, emojis, stickers, and similar items.
1044
+
1045
+ ### Parameters
1046
+
1047
+ | Name | Type | Description |
1048
+ | ----- | -------- | --------------------------- |
1049
+ | `buf` | `Object` | New frecency settings data. |
1050
+
1051
+ ### Returns
1052
+
1053
+ ```javascript
1054
+ Promise<Object>
1055
+ ```
1056
+
1057
+ The updated settings.
1058
+
1059
+ ### Example
1060
+
1061
+ ```javascript
1062
+ const settings = await client.updateFrecencySettings({
1063
+ // frecency settings data
1064
+ });
1065
+
1066
+ console.log(settings);
1067
+ ```
1068
+
1069
+ # Servers
1070
+
1071
+ ## `client.getServerList()`
1072
+
1073
+ Gets the full list of servers the account is currently in.
1074
+
1075
+ ### Returns
1076
+
1077
+ ```javascript
1078
+ Promise<Array<Object>>
1079
+ ```
1080
+
1081
+ An array containing the server objects.
1082
+
1083
+ ### Example
1084
+
1085
+ ```javascript
1086
+ const servers = await client.getServerList();
1087
+
1088
+ console.log(servers);
1089
+ ```
1090
+
678
1091
  # Status
679
1092
 
680
1093
  ## `client.setStatus(options)`
@@ -702,7 +1115,6 @@ Activity objects contain:
702
1115
  ```javascript
703
1116
  client.setStatus({
704
1117
  status: "dnd",
705
-
706
1118
  activities: [{
707
1119
  name: "with the Discord API",
708
1120
  type: Status.PLAYING
@@ -715,7 +1127,6 @@ client.setStatus({
715
1127
  ```javascript
716
1128
  client.setStatus({
717
1129
  status: "online",
718
-
719
1130
  activities: [{
720
1131
  name: "my custom status",
721
1132
  type: Status.CUSTOM_STATUS
@@ -730,7 +1141,6 @@ Streaming activities automatically receive the activity's name as `details`.
730
1141
  ```javascript
731
1142
  client.setStatus({
732
1143
  status: "online",
733
-
734
1144
  activities: [{
735
1145
  name: "Minecraft",
736
1146
  type: Status.STREAMING
@@ -738,8 +1148,6 @@ client.setStatus({
738
1148
  });
739
1149
  ```
740
1150
 
741
- ---
742
-
743
1151
  # Authentication
744
1152
 
745
1153
  ## `client.logout()`
@@ -758,8 +1166,6 @@ Promise<Object>
758
1166
  await client.logout();
759
1167
  ```
760
1168
 
761
- ---
762
-
763
1169
  # Connection
764
1170
 
765
1171
  ## `client.disconnect(code)`
@@ -786,13 +1192,10 @@ Or with a specific close code:
786
1192
  client.disconnect(1000);
787
1193
  ```
788
1194
 
789
- ---
790
-
791
1195
  # Complete Example
792
1196
 
793
1197
  ```javascript
794
1198
  const self = require("@imaentity/selfjs");
795
-
796
1199
  const client = new self.Client({
797
1200
  debugLogs: true
798
1201
  });
@@ -819,8 +1222,6 @@ client.on("DISCONNECT", () => {
819
1222
  client.login(process.env.DISCORD_TOKEN);
820
1223
  ```
821
1224
 
822
- ---
823
-
824
1225
  # Exported API
825
1226
 
826
1227
  SelfJS currently exports:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imaentity/selfjs",
3
- "version": "4.0.1",
3
+ "version": "4.2.0",
4
4
  "description": "Breaking Discord's TOS to bot user accounts.",
5
5
  "main": "self.js",
6
6
  "repository": {
@@ -10,7 +10,8 @@
10
10
  "keywords": [
11
11
  "bot",
12
12
  "discord",
13
- "library"
13
+ "library",
14
+ "selfbot"
14
15
  ],
15
16
  "author": "ImaEntity",
16
17
  "license": "ISC",
@@ -19,6 +20,7 @@
19
20
  },
20
21
  "homepage": "https://github.com/ImaEntity/SelfJS#readme",
21
22
  "dependencies": {
22
- "ws": "^7.5.4"
23
+ "ws": "^7.5.4",
24
+ "discord-protos": "^1.2.305"
23
25
  }
24
26
  }
package/self.js CHANGED
@@ -2,19 +2,20 @@
2
2
  * @name SelfJS
3
3
  * @description Breaking Discord's TOS to bot user accounts.
4
4
  * @author Entity
5
- * @version 4.0.1
5
+ * @version 4.2
6
6
  */
7
7
 
8
+ const proto = require("discord-protos");
8
9
  const EventEmitter = require("events");
9
10
  const https = require("https");
10
11
  const ws = require("ws");
11
12
 
12
13
  const DISCORD_EPOCH = 1420070400000n;
13
- const SELF_VERSION = "v4.0";
14
+ const SELF_VERSION = "v4.2";
14
15
  const WS_ENDPOINT = "wss://gateway.discord.gg?v=10&encoding=json";
15
16
  const LOGIN_PROPS = {
16
17
  os: process.platform,
17
- browser: "SelfJS",
18
+ browser: `SelfJS ${SELF_VERSION}`,
18
19
  device: "NodeJS"
19
20
  };
20
21
 
@@ -190,25 +191,35 @@ async function validateToken(token) {
190
191
  * @param {Object} options Options for getting a token
191
192
  * @param {String} options.email The email to use for finding a token
192
193
  * @param {String} options.password The password to use for getting a token
193
- * @returns {Promise<Object|null>} An object containing a token, mfa methods and a callback, or null
194
+ * @returns {Promise<Object>} An object containing a token, mfa methods and a callback, or an error message
194
195
  */
195
196
  async function createToken(options) {
196
197
  const {email, password} = options;
197
- if(!email || !password) return null;
198
+ if(!email || !password) return {
199
+ success: false,
200
+ error: "Missing email or password"
201
+ };
198
202
 
199
203
  const loginData = await POST({
200
204
  path: "/auth/login",
201
205
  body: {login: email, password}
202
206
  });
203
207
 
204
- if(!loginData.user_id) return null;
208
+ if(loginData.captcha_service) return {
209
+ success: false,
210
+ error: "Captcha required, but not yet supported",
211
+ ...loginData
212
+ };
213
+
205
214
  if(!loginData.mfa) return {
215
+ success: true,
206
216
  token: loginData.token,
207
217
  user_id: loginData.user_id,
208
218
  mfaRequired: false
209
219
  };
210
220
 
211
221
  return {
222
+ success: true,
212
223
  user_id: loginData.user_id,
213
224
  mfaRequired: true,
214
225
  mfaMethods: Object.entries(loginData)
@@ -574,9 +585,19 @@ class Client extends EventEmitter {
574
585
 
575
586
  /**
576
587
  * Gets the channels active in the DM list of the user, channels can be both DMs and group chats
577
- * @returns {Promise<Object>} The list of channels open in the user's DM list
588
+ * @returns {Promise<Array<Object>>} The list of channels open in the user's DM list
589
+ */
590
+ getOpenChannels() {
591
+ return this.#GET({path: "/users/@me/channels"});
592
+ }
593
+
594
+ /**
595
+ * Gets the full list of servers the user is in
596
+ * @returns {Promise<Array<Object>>} The list of servers
578
597
  */
579
- getOpenChannels() { return this.#GET({path: "/users/@me/channels"}); }
598
+ getServerList() {
599
+ return this.#GET({ path: "/users/@me/guilds" });
600
+ }
580
601
 
581
602
  /**
582
603
  * Closes the current session and disconnects from discord
@@ -607,7 +628,8 @@ class Client extends EventEmitter {
607
628
  * }>} options.activities Used to provide a list of activities
608
629
  *
609
630
  * @returns {void}
610
- */
631
+ */
632
+ // TODO: Send protobuf chunk to endpoint 1
611
633
  setStatus(options) {
612
634
  for(const activity of options.activities) {
613
635
  if(activity.type == Status.CUSTOM_STATUS) {
@@ -712,7 +734,7 @@ class Client extends EventEmitter {
712
734
  * @param {String} options.channel_id The channel id to get messages from
713
735
  * @param {Number} [options.limit] The max amount of messages to return
714
736
  * @param {String} [options.before] Only return messages before this message id
715
- * @returns {Promise<Array>} The list of messages in order from newest to oldest
737
+ * @returns {Promise<Object<Array>>} The list of messages in order from newest to oldest
716
738
  */
717
739
  getMessages(options) {
718
740
  return this.#GET({
@@ -720,6 +742,198 @@ class Client extends EventEmitter {
720
742
  query: {limit: options.limit, before: options.before}
721
743
  });
722
744
  }
745
+
746
+ /**
747
+ * Creates a group DM with certain members
748
+ * @param {Array<String>} recipients A list of user ids to add to the created group
749
+ * @returns {Promise<Object>} The new channel object after creation
750
+ */
751
+ createGroupDM(recipients) {
752
+ return this.#POST({path: `/users/@me/channels`, body: {recipients}});
753
+ }
754
+
755
+ /**
756
+ * Removes a user from a group dm if the logged in account owns the group
757
+ * @param {Object} options Options specifying which user to remove and from what group
758
+ * @param {String} options.channel_id The id of the group to remove the user from
759
+ * @param {String} options.user_id The id of the user to be removed from the group
760
+ * @returns {Promise<void>} No content returned on success
761
+ */
762
+ removeFromGroup(options) {
763
+ return this.#DELETE({path: `/channels/${options.channel_id}/recipients/${options.user_id}`});
764
+ }
765
+
766
+ /**
767
+ * Adds a user to a group dm if the logged in account is friends with the user
768
+ * @param {Object} options Options specifying which user to add and to what group
769
+ * @param {String} options.channel_id The id of the group to add the user to
770
+ * @param {String} options.user_id The id of the user to be added to the group
771
+ * @returns {Promise<void>} No content returned on success
772
+ */
773
+ addToGroup(options) {
774
+ return this.#PUT({path: `/channels/${options.channel_id}/recipients/${options.user_id}`});
775
+ }
776
+
777
+ /**
778
+ * Transfers ownership of a group to another user if that user is in the group
779
+ * @param {Object} options Options specifying which user to give owner and in what group
780
+ * @param {String} options.channel_id The id of the group to be transfered
781
+ * @param {String} options.user_id The id of the user to given ownership of the group
782
+ * @returns {Promise<Object>} The new channel object after the transfer
783
+ */
784
+ transferGroup(options) {
785
+ return this.#PATCH({
786
+ path: `/channels/${options.channel_id}`,
787
+ body: {owner: options.user_id}
788
+ });
789
+ }
790
+
791
+ /**
792
+ * Leaves a group while optionally not notifying members of that group
793
+ * @param {Object} options Options specifying what group to leave and if the leave should notify
794
+ * @param {String} options.channel_id The id of the group to leave
795
+ * @param {Boolean} [options.silent] If true, the group will not receive a leave notification
796
+ * @returns {Promise<Object>} The new channel object after the group has been left
797
+ */
798
+ leaveGroup(options) {
799
+ return this.#DELETE({
800
+ path: `/channels/${options.channel_id}`,
801
+ query: {silent: options.silent}
802
+ });
803
+ }
804
+
805
+ /**
806
+ * Shows the typing indicator for other users in a certain channel for 10 seconds
807
+ * Calling this again before the indicator expires resets the timer, while sending a message clears the indicator
808
+ * @param {String} channel_id The id of the channel to start typing in
809
+ * @returns {Promise<void>} No content returned on success
810
+ */
811
+ startTyping(channel_id) {
812
+ return this.#POST({path: `/channels/${channel_id}/typing`});
813
+ }
814
+
815
+ /**
816
+ * Pins a message to a certain channel
817
+ * @param {Object} options Specifies the message and channel to pin it in
818
+ * @param {String} options.channel_id The id of the channel to pin the message in
819
+ * @param {String} options.message_id The id of the message to pin in the channel
820
+ * @returns {Promise<void>} No content returned on success
821
+ */
822
+ pinMessage(options) {
823
+ return this.#PUT({path: `/api/v10/channels/${options.channel_id}/pins/${options.message_id}`});
824
+ }
825
+
826
+ /**
827
+ * Unpins a message from a certain channel
828
+ * @param {Object} options Specifies the message and channel to unpin it from
829
+ * @param {String} options.channel_id The id of the channel to unpin the message from
830
+ * @param {String} options.message_id The id of the message to unpin from the channel
831
+ * @returns {Promise<void>} No content returned on success
832
+ */
833
+ unpinMessage(options) {
834
+ return this.#DELETE({path: `/api/v10/channels/${options.channel_id}/pins/${options.message_id}`});
835
+ }
836
+
837
+ /**
838
+ * Gets the current representation of a channel via its id
839
+ * Channels can be DMs, group DMs, server text, or server voice channels
840
+ * @param {String} channel_id
841
+ * @returns {Promise<Object>} The current channel object
842
+ */
843
+ getChannelObject(channel_id) {
844
+ return this.#GET({path: `/channels/${channel_id}`});
845
+ }
846
+
847
+ /**
848
+ * Gets the channel object for DMs with a certain user
849
+ * Getting the channel object also opens the channel in the active DM list
850
+ * @param {String} user_id The id of the user to get the DM channel of
851
+ * @returns {Promise<Object>} The DM channel object
852
+ */
853
+ getDMChannel(user_id) {
854
+ return this.#POST({path: "/users/@me/channels", body: {recipients: [user_id]}});
855
+ }
856
+
857
+ /**
858
+ * Closes and hides the DM channel for a certain user from the active list
859
+ * @param {String} user_id The id of the user to close the DM channel of
860
+ * @returns {Promise<Object>} Returns the channel after closing on success
861
+ */
862
+ async closeDMChannel(user_id) {
863
+ const channel = await this.getDMChannel(user_id);
864
+ if(!("id" in channel)) return null;
865
+ return this.#DELETE({path: `/channels/${channel.id}`});
866
+ }
867
+
868
+ /**
869
+ * Get a user's profile if one of the following is true:
870
+ * The client shares a server with the user, is friends with the user
871
+ * The user sent a friend request to the client, or the user is a bot
872
+ * @param {Object} options The options specifying what the response should contain
873
+ * @param {String} options.user_id The id of the user to request the profile of
874
+ * @param {Boolean} [options.with_mutual_servers] If true or absent, include mutual servers in the response
875
+ * @param {Boolean} [options.with_mutual_friends] If true, include mutual friends in the response
876
+ * @param {Boolean} [options.with_mutual_friends_count] If true, include the number of mutual friends in the response
877
+ * @param {String} [options.guild_id] If present respond with the server profile for this guild
878
+ * @returns {Promise<Object>} The user's profile on success, 404 error if no conditions were met
879
+ */
880
+ getUserProfile(options) {
881
+ return this.#GET({
882
+ path: `/users/${options.user_id}/profile`,
883
+ query: {
884
+ guild_id: options.guild_id,
885
+ with_mutual_guilds: options.with_mutual_servers,
886
+ with_mutual_friends: options.with_mutual_friends,
887
+ with_mutual_friends_count: options.with_mutual_friends_count
888
+ }
889
+ });
890
+ }
891
+
892
+ /**
893
+ * Gets the "PreloadedUserSettings" protobuf, containing general user settings
894
+ * @returns {Promise<Object>} The protobuf content converted to JSON
895
+ */
896
+ async getUserSettings() {
897
+ const buf = await this.#GET({path: "/users/@me/settings-proto/1"});
898
+ if(buf?.settings) return proto.PreloadedUserSettings.fromBase64(buf.settings);
899
+ return buf;
900
+ }
901
+
902
+ /**
903
+ * Gets the "FrecencyUserSettings" protobuf converted to JSON
904
+ * Containing frecency and favorite data for gifs, emojis, stickers, and other similar things
905
+ * @returns {Promise<Object>} The protobuf content converted to JSON
906
+ */
907
+ async getFrecencySettings() {
908
+ const buf = await this.#GET({path: "/users/@me/settings-proto/2"});
909
+ if(buf?.settings) return proto.FrecencyUserSettings.fromBase64(buf.settings);
910
+ return buf;
911
+ }
912
+
913
+ /**
914
+ * Updates the "PreloadedUserSettings" protobuf, containing general user settings
915
+ * @param {Object} buf The new data to set the protobuf to
916
+ * @returns {Promise<Object>} The updated protobuf stored on the server
917
+ */
918
+ async updateUserSettings(buf) {
919
+ const b64 = proto.PreloadedUserSettings.toBase64(buf);
920
+ const res = await this.#PATCH({path: "/users/@me/settings-proto/1", body: {settings: b64}});
921
+ if(res?.settings) return proto.PreloadedUserSettings.fromBase64(res.settings);
922
+ return res;
923
+ }
924
+
925
+ /**
926
+ * Updates the "FrecencyUserSettings" protobuf
927
+ * Contains frecency and favorite data for gifs, emojis, stickers, and other similar things
928
+ * @param {Object} buf The new data to set the protobuf to
929
+ * @returns {Promise<Object>} The updated protobuf stored on the server
930
+ */
931
+ async updateFrecencySettings(buf) {
932
+ const b64 = proto.FrecencyUserSettings.toBase64(buf);
933
+ const res = await this.#PATCH({path: "/users/@me/settings-proto/2", body: {settings: b64}});
934
+ if(res?.settings) return proto.FrecencyUserSettings.fromBase64(res.settings);
935
+ return res;
936
+ }
723
937
  }
724
938
 
725
939
  module.exports = {