1 /**
2   The top API abstraction encompassing REST, WS/Gateway, and state tracking.
3 */
4 module dcord.client;
5 
6 import std.stdio;
7 
8 public import std.experimental.logger;
9 
10 import std.algorithm.iteration, std.array;
11 
12 import dcord.api,
13        dcord.types,
14        dcord.state,
15        dcord.gateway,
16        dcord.util.emitter;
17 
18 /**
19   Struct containing configuration for Gateway sharding
20 */
21 struct ShardInfo {
22   /** The number of the current shard */
23   ushort shard = 0;
24 
25   /** Total number of shards */
26   ushort numShards = 1;
27 }
28 
29 @JSONIgnore
30 class Client {
31   /** Base log */
32   Logger log;
33 
34   /** Bot Authentication token */
35   string token;
36 
37   /** Configuration for sharding */
38   ShardInfo* shardInfo;
39 
40   /** APIClient instance */
41   APIClient api;
42 
43   /** GatewayClient instance */
44   GatewayClient gw;
45 
46   /** State instance */
47   State state;
48 
49   /** Emitter for gateway events */
50   Emitter events;
51 
52   /** Initializer */
53   this(string token, LogLevel lvl=LogLevel.all, ShardInfo* shardInfo = null) {
54     this.log = new FileLogger(stdout, lvl);
55     this.token = token;
56     this.shardInfo = shardInfo ? shardInfo : new ShardInfo();
57 
58     this.api = new APIClient(this);
59     this.gw = new GatewayClient(this);
60     this.state = new State(this);
61   }
62 
63   /**
64     Returns the current user.
65   */
66   @property User me() {
67     return this.state.me;
68   }
69 
70   /**
71     Gets an array of messages for a given channel.
72 
73     Params:
74       channelID = the channelID all the messages originate from.
75       limit = the number of messages to retrieve.
76       msgID = the message which other messages are selected, with respect to the filter
77       filter = get messages before, around, or after the supplied msgID
78   */
79   Message[] getMessages(Snowflake channelID, uint limit = 100, Snowflake msgID = 0, MessageFilter filter = MessageFilter.BEFORE) {
80     return this.api.channelsMessagesList(channelID, limit, filter, msgID);
81   }
82 
83   /**
84     Deletes an array of messages for a given channel, properly bulking them
85     if required.
86 
87     Params:
88       channelID = the channelID all the messages originate from.
89       messages = the array of messages.
90   */
91   void deleteMessages(Snowflake channelID, Message[] messages) {
92     deleteMessages(channelID, messages.map!(m => m.id).array);
93   }
94 
95   /**
96     Deletes an array of message IDs for a given channel, properly bulking them
97     if required.
98 
99     Params:
100       channelID = the channelID all the messages originate from
101       msgIDs = the array of message IDs
102   */
103   void deleteMessages(Snowflake channelID, Snowflake[] msgIDs) {
104     if(msgIDs.length <= 2) { // Deleting messages in bulk isn't needed here, the overhead would be less than the speed benefits.
105       msgIDs.each!(x => this.api.channelsMessagesDelete(channelID, x));
106     } else { // It would be fastest to delete in bulk.
107       this.api.channelsMessagesDeleteBulk(channelID, msgIDs);
108     }
109   }
110 }