1 /**
2   The top API abstraction encompassing REST, WS/Gateway, and state tracking.
3 */
4 module dscord.client;
5 
6 import std.stdio;
7 
8 public import std.experimental.logger;
9 
10 import std.algorithm.iteration;
11 
12 import dscord.api,
13        dscord.types,
14        dscord.state,
15        dscord.gateway,
16        dscord.util.emitter;
17 
18 
19 /**
20   Struct containing configuration for Gateway sharding.
21 */
22 struct ShardInfo {
23   /** This shards number. */
24   ushort shard = 0;
25 
26   /** Total number of shards. */
27   ushort numShards = 1;
28 }
29 
30 @JSONIgnore
31 class Client {
32   /** Base log */
33   Logger  log;
34 
35   /** Bot Authentication token */
36   string  token;
37 
38   /** Sharding configuration */
39   ShardInfo* shardInfo;
40 
41   /** APIClient instance */
42   APIClient      api;
43 
44   /** GatewayClient instance */
45   GatewayClient  gw;
46 
47   /** State instance */
48   State  state;
49 
50   /** Emitter for gateway events */
51   Emitter  events;
52 
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     Snowflake[] msgIDs;
93 
94     foreach(message; messages){
95       msgIDs ~= message.id;
96     }
97 
98     return deleteMessages(channelID, msgIDs);
99   }
100 
101   /**
102     Deletes an array of message IDs for a given channel, properly bulking them
103     if required.
104 
105     Params:
106       channelID = the channelID all the messages originate from
107       msgIDs = the array of message IDs
108   */
109   void deleteMessages(Snowflake channelID, Snowflake[] msgIDs) {
110     if (msgIDs.length <= 2) {
111       msgIDs.each!(x => this.api.channelsMessagesDelete(channelID, x));
112     } else {
113       this.api.channelsMessagesDeleteBulk(channelID, msgIDs);
114     }
115   }
116 
117   void updateStatus(uint idleSince, Game game=null) {
118     this.gw.send(new StatusUpdate(idleSince, game));
119   }
120 }