1
+ // Copyright (c) 2021-2025 BuiltByBit (Mick Capital Pty. Ltd.)
2
+ // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3
+
4
+ const { Wrapper, Token, TokenType } = require ( "@builtbybit/api-wrapper" ) ;
5
+ const readline = require ( "readline" ) ;
6
+ const { table } = require ( "table" ) ;
7
+
8
+ const rl = readline . createInterface ( {
9
+ input : process . stdin ,
10
+ output : process . stdout
11
+ } ) ;
12
+
13
+ const config = {
14
+ header : {
15
+ alignment : "center" ,
16
+ content : "BuiltByBit Download Verification"
17
+ }
18
+ } ;
19
+
20
+ let token = new Token ( TokenType . PRIVATE , "Find @ https://builtbybit.com/account/api" ) ;
21
+ let wrapper = new Wrapper ( ) ;
22
+
23
+ async function main ( ) {
24
+ await wrapper . init ( token ) ;
25
+
26
+ let ownedResources = await wrapper . resources ( ) . listOwnedAll ( ) . catch ( e => { console . error ( e ) ; } ) ;
27
+ let resourceIds = [ [ "Resource Title" , "Resource ID" ] ] ;
28
+ for ( const resource of ownedResources ) {
29
+ resourceIds . push ( [ resource . title , resource . resource_id ] ) ;
30
+ }
31
+ const ownedConfig = {
32
+ header : {
33
+ alignment : "center" ,
34
+ content : "BuiltByBit Download Verification\nOwned Resources"
35
+ }
36
+ } ;
37
+ console . log ( table ( resourceIds , ownedConfig ) ) ;
38
+
39
+ rl . question ( "Lookup by (u)sername or by (r)esource id? " , async ( answer ) => {
40
+ let downloadDetails ;
41
+ let user ;
42
+ let downloads = [ ] ;
43
+ switch ( answer . toLowerCase ( ) ) {
44
+ case "u" :
45
+ try {
46
+ rl . question ( "What is the username of the user you'd like to lookup? " , async ( username ) => {
47
+ user = await wrapper . members ( ) . fetchByUsername ( username ) . catch ( e => { console . error ( e ) ; } ) ;
48
+ console . log ( "Fetching..." ) ;
49
+ downloads . push ( [ "Resource Title" , "Resource ID" , "Download Date" ] ) ;
50
+ for ( const resource of ownedResources ) {
51
+ // eslint-disable-next-line max-len
52
+ downloadDetails = await wrapper . resources ( ) . downloads ( ) . listByMemberAll ( resource . resource_id , user . member_id ) . catch ( e => { console . error ( e ) ; } ) ;
53
+ for ( const download of downloadDetails ) {
54
+ // eslint-disable-next-line max-len
55
+ downloads . push ( [ resource . title , resource . resource_id , new Date ( download . download_date * 1000 ) . toLocaleString ( ) ] ) ;
56
+ }
57
+ }
58
+ console . log ( table ( downloads , config ) ) ;
59
+ rl . close ( ) ;
60
+ } ) ;
61
+ } catch ( e ) {
62
+ console . error ( e ) ;
63
+ rl . close ( ) ;
64
+ }
65
+ break ;
66
+ case "r" :
67
+ try {
68
+ rl . question ( "What is the resource id of the resource you'd like to lookup? " , async ( resourceId ) => {
69
+ // eslint-disable-next-line max-len
70
+ downloadDetails = await wrapper . resources ( ) . downloads ( ) . listAll ( resourceId ) . catch ( e => { console . error ( e ) ; } ) ;
71
+ downloads . push ( [ "Username" , "Member ID" , "Download Date" ] ) ;
72
+ console . log ( "Fetching..." ) ;
73
+ for ( const download of downloadDetails ) {
74
+ user = await wrapper . members ( ) . fetch ( download . downloader_id ) . catch ( e => { console . error ( e ) ; } ) ;
75
+ // eslint-disable-next-line max-len
76
+ downloads . push ( [ user . username , user . member_id , new Date ( download . download_date * 1000 ) . toLocaleString ( ) ] ) ;
77
+ }
78
+ console . log ( table ( downloads , config ) ) ;
79
+ rl . close ( ) ;
80
+ } ) ;
81
+ } catch ( e ) {
82
+ console . error ( e ) ;
83
+ rl . close ( ) ;
84
+ }
85
+ break ;
86
+ default :
87
+ console . error ( "Invalid input. Please try again." ) ;
88
+ rl . close ( ) ;
89
+ break ;
90
+ }
91
+ } ) ;
92
+ }
93
+
94
+ main ( ) . catch ( error => console . error ( "ERROR: " + error ) ) ;
0 commit comments