Class: Discordrb::Bot

Inherits:
Object
  • Object
show all
Includes:
Events
Defined in:
lib/discordrb/bot.rb

Overview

Represents a Discord bot, including servers, users, etc.

Direct Known Subclasses

Commands::CommandBot

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Events

matches_all

Constructor Details

#initialize(email, password, debug = false) ⇒ Bot

Returns a new instance of Bot.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/discordrb/bot.rb', line 32

def initialize(email, password, debug = false)
  # Make sure people replace the login details in the example files...
  if email.end_with? 'example.com'
    puts 'You have to replace the login details in the example files with your own!'
    exit
  end

  @debug = debug

  @email = email
  @password = password

  @token = 

  @event_handlers = {}

  @channels = {}
  @users = {}

  @awaits = {}
end

Instance Attribute Details

#bot_userObject (readonly)

Returns the value of attribute bot_user.



30
31
32
# File 'lib/discordrb/bot.rb', line 30

def bot_user
  @bot_user
end

#debug(message, important = false) ⇒ Object



284
285
286
# File 'lib/discordrb/bot.rb', line 284

def debug(message, important = false)
  puts "[DEBUG @ #{Time.now}] #{message}" if @debug || important
end

#serversObject (readonly)

Returns the value of attribute servers.



30
31
32
# File 'lib/discordrb/bot.rb', line 30

def servers
  @servers
end

#tokenObject (readonly)

Returns the value of attribute token.



30
31
32
# File 'lib/discordrb/bot.rb', line 30

def token
  @token
end

#usersObject (readonly)

Returns the value of attribute users.



30
31
32
# File 'lib/discordrb/bot.rb', line 30

def users
  @users
end

Instance Method Details

#add_await(key, type, attributes = {}, &block) ⇒ Object



159
160
161
162
163
# File 'lib/discordrb/bot.rb', line 159

def add_await(key, type, attributes = {}, &block)
  fail "You can't await an AwaitEvent!" if type == Discordrb::Events::AwaitEvent
  await = Await.new(self, key, type, attributes, block)
  @awaits[key] = await
end

#add_handler(handler) ⇒ Object Also known as: <<



279
280
281
282
# File 'lib/discordrb/bot.rb', line 279

def add_handler(handler)
  clazz = event_class(handler.class)
  @event_handlers[clazz] << handler
end

#await(attributes = {}, &block) ⇒ Object



270
271
272
# File 'lib/discordrb/bot.rb', line 270

def await(attributes = {}, &block)
  register_event(AwaitEvent, attributes, block)
end

#channel(id) ⇒ Object



96
97
98
99
100
101
102
103
# File 'lib/discordrb/bot.rb', line 96

def channel(id)
  debug("Obtaining data for channel with id #{id}")
  return @channels[id] if @channels[id]

  response = API.channel(@token, id)
  channel = Channel.new(JSON.parse(response), self)
  @channels[id] = channel
end

#channel_create(attributes = {}, &block) ⇒ Object

Handle channel creation Attributes:

  • type: Channel type (‘text’ or ‘voice’)

  • name: Channel name



225
226
227
# File 'lib/discordrb/bot.rb', line 225

def channel_create(attributes = {}, &block)
  register_event(ChannelCreateEvent, attributes, block)
end

#channel_delete(attributes = {}, &block) ⇒ Object

Handle channel deletion Attributes:

  • type: Channel type (‘text’ or ‘voice’)

  • name: Channel name



241
242
243
# File 'lib/discordrb/bot.rb', line 241

def channel_delete(attributes = {}, &block)
  register_event(ChannelDeleteEvent, attributes, block)
end

#channel_update(attributes = {}, &block) ⇒ Object

Handle channel update Attributes:

  • type: Channel type (‘text’ or ‘voice’)

  • name: Channel name



233
234
235
# File 'lib/discordrb/bot.rb', line 233

def channel_update(attributes = {}, &block)
  register_event(ChannelUpdateEvent, attributes, block)
end

#disconnected(attributes = {}, &block) ⇒ Object



205
206
207
# File 'lib/discordrb/bot.rb', line 205

def disconnected(attributes = {}, &block)
  register_event(DisconnectEvent, attributes, block)
end

#find(channel_name, server_name = nil, threshold = 0) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/discordrb/bot.rb', line 128

def find(channel_name, server_name = nil, threshold = 0)
  require 'levenshtein'

  results = []
  @servers.values.each do |server|
    server.channels.each do |channel|
      distance = Levenshtein.distance(channel.name, channel_name)
      distance += Levenshtein.distance(server_name || server.name, server.name)
      next if distance > threshold

      # Make a singleton accessor "distance"
      channel.instance_variable_set(:@distance, distance)
      class << channel
        attr_reader :distance
      end
      results << channel
    end
  end
  results
end

#game=(name_or_id) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/discordrb/bot.rb', line 171

def game=(name_or_id)
  game = Discordrb::Games.find_game(name_or_id)
  @game = game

  data = {
    'op' => 3,
    'd' => {
      'idle_since' => nil,
      'game_id' => game ? game.id : 60 # 60 blanks out the game playing
    }
  }

  @ws.send(data.to_json)
  game
end

#handler_class(event_class) ⇒ Object



288
289
290
# File 'lib/discordrb/bot.rb', line 288

def handler_class(event_class)
  class_from_string(event_class.to_s + 'Handler')
end

#join(invite) ⇒ Object



114
115
116
117
118
# File 'lib/discordrb/bot.rb', line 114

def join(invite)
  invite = invite[invite.rindex('/') + 1..-1] if invite.start_with?('http') || invite.start_with?('discord.gg')
  resolved = JSON.parse(API.resolve_invite(@token, invite))['code']
  API.join_server(@token, resolved)
end

#member_join(attributes = {}, &block) ⇒ Object



258
259
260
# File 'lib/discordrb/bot.rb', line 258

def member_join(attributes = {}, &block)
  register_event(GuildMemberAddEvent, attributes, block)
end

#member_leave(attributes = {}, &block) ⇒ Object



266
267
268
# File 'lib/discordrb/bot.rb', line 266

def member_leave(attributes = {}, &block)
  register_event(GuildMemberDeleteEvent, attributes, block)
end

#member_update(attributes = {}, &block) ⇒ Object



262
263
264
# File 'lib/discordrb/bot.rb', line 262

def member_update(attributes = {}, &block)
  register_event(GuildMemberUpdateEvent, attributes, block)
end

#mention(attributes = {}, &block) ⇒ Object



217
218
219
# File 'lib/discordrb/bot.rb', line 217

def mention(attributes = {}, &block)
  register_event(MentionEvent, attributes, block)
end

#message(attributes = {}, &block) ⇒ Object

## ### ## ## ######## ## ######## ######## ######

##   ## ##   ###   ## ##     ## ##       ##       ##     ## ##    ##
##  ##   ##  ####  ## ##     ## ##       ##       ##     ## ##

## ## ## ## ## ## ## ## ###### ######## ######

## ######### ##  #### ##     ## ##       ##       ##   ##         ##
## ##     ## ##   ### ##     ## ##       ##       ##    ##  ##    ##
## ##     ## ##    ## ########  ######## ######## ##     ##  ######


197
198
199
# File 'lib/discordrb/bot.rb', line 197

def message(attributes = {}, &block)
  register_event(MessageEvent, attributes, block)
end

#parse_mention(mention) ⇒ Object



165
166
167
168
169
# File 'lib/discordrb/bot.rb', line 165

def parse_mention(mention)
  # Mention format: <@id>
  return nil unless /\<@(?<id>\d+)\>?/ =~ mention
  user(id)
end

#presence(attributes = {}, &block) ⇒ Object



213
214
215
# File 'lib/discordrb/bot.rb', line 213

def presence(attributes = {}, &block)
  register_event(PresenceEvent, attributes, block)
end

#private_channel(id) ⇒ Object



105
106
107
108
109
110
111
112
# File 'lib/discordrb/bot.rb', line 105

def private_channel(id)
  debug("Creating private channel with user id #{id}")
  return @private_channels[id] if @private_channels[id]

  response = API.create_private(@token, @bot_user.id, id)
  channel = Channel.new(JSON.parse(response), self)
  @private_channels[id] = channel
end

#ready(attributes = {}, &block) ⇒ Object



201
202
203
# File 'lib/discordrb/bot.rb', line 201

def ready(attributes = {}, &block)
  register_event(ReadyEvent, attributes, block)
end

#remove_handler(handler) ⇒ Object



274
275
276
277
# File 'lib/discordrb/bot.rb', line 274

def remove_handler(handler)
  clazz = event_class(handler.class)
  @event_handlers[clazz].delete(handler)
end

#run(async = false) ⇒ Object



54
55
56
57
58
59
60
# File 'lib/discordrb/bot.rb', line 54

def run(async = false)
  run_async
  return if async

  debug('Oh wait! Not exiting yet as run was run synchronously.')
  sync
end

#run_asyncObject



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/discordrb/bot.rb', line 62

def run_async
  # Handle heartbeats
  @heartbeat_interval = 1
  @heartbeat_active = false
  @heartbeat_thread = Thread.new do
    loop do
      sleep @heartbeat_interval
      send_heartbeat if @heartbeat_active
    end
  end

  @ws_thread = Thread.new do
    loop do
      websocket_connect
      debug('Disconnected! Attempting to reconnect in 5 seconds.')
      sleep 5
      @token = 
    end
  end

  debug('WS thread created! Now waiting for confirmation that everything worked')
  @ws_success = false
  sleep(0.5) until @ws_success
  debug('Confirmation received! Exiting run.')
end

#send_file(channel_id, file) ⇒ Object



155
156
157
# File 'lib/discordrb/bot.rb', line 155

def send_file(channel_id, file)
  API.send_file(@token, channel_id, file)
end

#send_message(channel_id, content) ⇒ Object



149
150
151
152
153
# File 'lib/discordrb/bot.rb', line 149

def send_message(channel_id, content)
  debug("Sending message to #{channel_id} with content '#{content}'")
  response = API.send_message(@token, channel_id, content)
  Message.new(JSON.parse(response), self)
end

#server(id) ⇒ Object



124
125
126
# File 'lib/discordrb/bot.rb', line 124

def server(id)
  @servers[id]
end

#stopObject



92
93
94
# File 'lib/discordrb/bot.rb', line 92

def stop
  @ws_thread.kill
end

#syncObject



88
89
90
# File 'lib/discordrb/bot.rb', line 88

def sync
  @ws_thread.join
end

#typing(attributes = {}, &block) ⇒ Object



209
210
211
# File 'lib/discordrb/bot.rb', line 209

def typing(attributes = {}, &block)
  register_event(TypingEvent, attributes, block)
end

#user(id) ⇒ Object



120
121
122
# File 'lib/discordrb/bot.rb', line 120

def user(id)
  @users[id]
end

#voice_state_update(attributes = {}, &block) ⇒ Object

Handle a change to a voice state. This includes joining a voice channel or changing mute or deaf state. Attributes:

  • from: User whose voice state changed

  • mute: server mute status

  • deaf: server deaf status

  • self_mute: self mute status

  • self_deaf: self deaf status

  • channel: channel the user joined



254
255
256
# File 'lib/discordrb/bot.rb', line 254

def voice_state_update(attributes = {}, &block)
  register_event(VoiceStateUpdateEvent, attributes, block)
end