Class: DiscordRDA::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/discord_rda/core/configuration.rb

Overview

Immutable configuration for DiscordRDA. Uses frozen hash to prevent mutation after initialization.

Examples:

Creating configuration

config = Configuration.new(
  token: ENV['DISCORD_TOKEN'],
  shards: :auto,
  intents: [:guilds, :guild_messages]
)

Constant Summary collapse

DEFAULTS =

Default configuration values

{
  api_version: 10,
  gateway_encoding: :json,
  gateway_compression: :zlib_stream,
  shards: [0, 1],
  cache: :memory,
  max_reconnect_delay: 60.0,
  initial_reconnect_delay: 1.0,
  enable_resume: true,
  heartbeat_interval_buffer: 0.9,
  rest_timeout: 30.0,
  rest_open_timeout: 10.0,
  rest_read_timeout: 30.0,
  compression_threshold: 1024,
  intents: [:guilds],
  log_level: :info,
  log_format: :structured,
  log_output: :stdout,
  log_file_path: nil,
  log_rotate_age: 7,
  log_rotate_size: 10_485_760,
  trace_enabled: false,
  error_tracking: false
}.freeze
INTENTS =

Valid intents mapping

{
  guilds: 1 << 0,
  guild_members: 1 << 1,
  guild_moderation: 1 << 2,
  guild_emojis_and_stickers: 1 << 3,
  guild_integrations: 1 << 4,
  guild_webhooks: 1 << 5,
  guild_invites: 1 << 6,
  guild_voice_states: 1 << 7,
  guild_presences: 1 << 8,
  guild_messages: 1 << 9,
  guild_message_reactions: 1 << 10,
  guild_message_typing: 1 << 11,
  direct_messages: 1 << 12,
  direct_message_reactions: 1 << 13,
  direct_message_typing: 1 << 14,
  message_content: 1 << 15,
  guild_scheduled_events: 1 << 16,
  auto_moderation_configuration: 1 << 20,
  auto_moderation_execution: 1 << 21,
  guild_message_polls: 1 << 24,
  direct_message_polls: 1 << 25
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Configuration

Create a new configuration

Parameters:

  • options (Hash) (defaults to: {})

    Configuration options

Raises:

  • (ArgumentError)


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/discord_rda/core/configuration.rb', line 134

def initialize(options = {})
  config = DEFAULTS.merge(options)

  # Validate required options
  raise ArgumentError, 'Token is required' unless config[:token]

  @token = config[:token].freeze
  @api_version = config[:api_version].to_i
  @gateway_encoding = config[:gateway_encoding].to_sym
  @gateway_compression = config[:gateway_compression]&.to_sym
  @shards = normalize_shards(config[:shards])
  @cache = config[:cache].to_sym
  @max_reconnect_delay = config[:max_reconnect_delay].to_f
  @initial_reconnect_delay = config[:initial_reconnect_delay].to_f
  @enable_resume = !!config[:enable_resume]
  @heartbeat_interval_buffer = config[:heartbeat_interval_buffer].to_f.clamp(0.0, 1.0)
  @rest_timeout = config[:rest_timeout].to_f
  @rest_open_timeout = config[:rest_open_timeout].to_f
  @rest_read_timeout = config[:rest_read_timeout].to_f
  @compression_threshold = config[:compression_threshold].to_i
  @intents = normalize_intents(config[:intents])
  @log_level = config[:log_level].to_sym
  @log_format = config[:log_format].to_sym
  @log_output = config[:log_output].is_a?(Symbol) ? config[:log_output] : config[:log_output].to_s
  @log_file_path = config[:log_file_path]
  @log_rotate_age = config[:log_rotate_age].to_i
  @log_rotate_size = config[:log_rotate_size].to_i
  @trace_enabled = !!config[:trace_enabled]
  @error_tracking = !!config[:error_tracking]

  freeze
end

Instance Attribute Details

#api_versionInteger (readonly)

Returns Discord API version.

Returns:

  • (Integer)

    Discord API version



73
74
75
# File 'lib/discord_rda/core/configuration.rb', line 73

def api_version
  @api_version
end

#cacheSymbol (readonly)

Returns Cache backend (:memory or :redis).

Returns:

  • (Symbol)

    Cache backend (:memory or :redis)



85
86
87
# File 'lib/discord_rda/core/configuration.rb', line 85

def cache
  @cache
end

#compression_thresholdInteger (readonly)

Returns Compression threshold in bytes.

Returns:

  • (Integer)

    Compression threshold in bytes



109
110
111
# File 'lib/discord_rda/core/configuration.rb', line 109

def compression_threshold
  @compression_threshold
end

#enable_resumeBoolean (readonly)

Returns Enable session resumption.

Returns:

  • (Boolean)

    Enable session resumption



94
95
96
# File 'lib/discord_rda/core/configuration.rb', line 94

def enable_resume
  @enable_resume
end

#error_trackingObject (readonly)

Returns the value of attribute error_tracking.



130
131
132
# File 'lib/discord_rda/core/configuration.rb', line 130

def error_tracking
  @error_tracking
end

#gateway_compressionSymbol (readonly)

Returns Gateway compression (:zlib_stream or nil).

Returns:

  • (Symbol)

    Gateway compression (:zlib_stream or nil)



79
80
81
# File 'lib/discord_rda/core/configuration.rb', line 79

def gateway_compression
  @gateway_compression
end

#gateway_encodingSymbol (readonly)

Returns Gateway encoding (:json or :etf).

Returns:

  • (Symbol)

    Gateway encoding (:json or :etf)



76
77
78
# File 'lib/discord_rda/core/configuration.rb', line 76

def gateway_encoding
  @gateway_encoding
end

#heartbeat_interval_bufferFloat (readonly)

Returns Heartbeat interval multiplier (0.0-1.0).

Returns:

  • (Float)

    Heartbeat interval multiplier (0.0-1.0)



97
98
99
# File 'lib/discord_rda/core/configuration.rb', line 97

def heartbeat_interval_buffer
  @heartbeat_interval_buffer
end

#initial_reconnect_delayFloat (readonly)

Returns Initial reconnect delay in seconds.

Returns:

  • (Float)

    Initial reconnect delay in seconds



91
92
93
# File 'lib/discord_rda/core/configuration.rb', line 91

def initial_reconnect_delay
  @initial_reconnect_delay
end

#intentsArray<Symbol> (readonly)

Returns Enabled gateway intents.

Returns:

  • (Array<Symbol>)

    Enabled gateway intents



112
113
114
# File 'lib/discord_rda/core/configuration.rb', line 112

def intents
  @intents
end

#log_file_pathObject (readonly)

Returns the value of attribute log_file_path.



122
123
124
# File 'lib/discord_rda/core/configuration.rb', line 122

def log_file_path
  @log_file_path
end

#log_formatSymbol (readonly)

Returns Log format (:simple, :structured).

Returns:

  • (Symbol)

    Log format (:simple, :structured)



118
119
120
# File 'lib/discord_rda/core/configuration.rb', line 118

def log_format
  @log_format
end

#log_levelSymbol (readonly)

Returns Log level (:debug, :info, :warn, :error).

Returns:

  • (Symbol)

    Log level (:debug, :info, :warn, :error)



115
116
117
# File 'lib/discord_rda/core/configuration.rb', line 115

def log_level
  @log_level
end

#log_outputObject (readonly)

Returns the value of attribute log_output.



120
121
122
# File 'lib/discord_rda/core/configuration.rb', line 120

def log_output
  @log_output
end

#log_rotate_ageObject (readonly)

Returns the value of attribute log_rotate_age.



124
125
126
# File 'lib/discord_rda/core/configuration.rb', line 124

def log_rotate_age
  @log_rotate_age
end

#log_rotate_sizeObject (readonly)

Returns the value of attribute log_rotate_size.



126
127
128
# File 'lib/discord_rda/core/configuration.rb', line 126

def log_rotate_size
  @log_rotate_size
end

#max_reconnect_delayFloat (readonly)

Returns Maximum reconnect delay in seconds.

Returns:

  • (Float)

    Maximum reconnect delay in seconds



88
89
90
# File 'lib/discord_rda/core/configuration.rb', line 88

def max_reconnect_delay
  @max_reconnect_delay
end

#rest_open_timeoutFloat (readonly)

Returns REST connection open timeout.

Returns:

  • (Float)

    REST connection open timeout



103
104
105
# File 'lib/discord_rda/core/configuration.rb', line 103

def rest_open_timeout
  @rest_open_timeout
end

#rest_read_timeoutFloat (readonly)

Returns REST read timeout.

Returns:

  • (Float)

    REST read timeout



106
107
108
# File 'lib/discord_rda/core/configuration.rb', line 106

def rest_read_timeout
  @rest_read_timeout
end

#rest_timeoutFloat (readonly)

Returns REST request timeout.

Returns:

  • (Float)

    REST request timeout



100
101
102
# File 'lib/discord_rda/core/configuration.rb', line 100

def rest_timeout
  @rest_timeout
end

#shardsArray<Integer>, Symbol (readonly)

Returns Shards configuration or :auto.

Returns:

  • (Array<Integer>, Symbol)

    Shards configuration or :auto



82
83
84
# File 'lib/discord_rda/core/configuration.rb', line 82

def shards
  @shards
end

#tokenString (readonly)

Returns Bot token.

Returns:

  • (String)

    Bot token



70
71
72
# File 'lib/discord_rda/core/configuration.rb', line 70

def token
  @token
end

#trace_enabledObject (readonly)

Returns the value of attribute trace_enabled.



128
129
130
# File 'lib/discord_rda/core/configuration.rb', line 128

def trace_enabled
  @trace_enabled
end

Class Method Details

.load(path, overrides: {}) ⇒ Object



167
168
169
# File 'lib/discord_rda/core/configuration.rb', line 167

def self.load(path, overrides: {})
  new(load_file(path).merge(overrides))
end

.load_file(path) ⇒ Object



216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/discord_rda/core/configuration.rb', line 216

def self.load_file(path)
  content = File.read(path)

  case File.extname(path).downcase
  when '.json'
    symbolize_keys(JSON.parse(content))
  when '.yml', '.yaml'
    symbolize_keys(YAML.safe_load(content, permitted_classes: [Symbol], aliases: true) || {})
  else
    raise ArgumentError, "Unsupported configuration file format: #{path}"
  end
end

.symbolize_keys(value) ⇒ Object



229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/discord_rda/core/configuration.rb', line 229

def self.symbolize_keys(value)
  case value
  when Hash
    value.each_with_object({}) do |(key, nested_value), hash|
      hash[key.to_sym] = symbolize_keys(nested_value)
    end
  when Array
    value.map { |item| symbolize_keys(item) }
  else
    value
  end
end

Instance Method Details

#intents_bitmaskInteger

Calculate the intents bitmask for Gateway identify

Returns:

  • (Integer)

    Intents bitmask



173
174
175
# File 'lib/discord_rda/core/configuration.rb', line 173

def intents_bitmask
  @intents.sum { |intent| INTENTS.fetch(intent, 0) }
end

#to_hHash

Convert configuration to hash

Returns:

  • (Hash)

    Configuration as hash



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/discord_rda/core/configuration.rb', line 186

def to_h
  {
    token: @token,
    api_version: @api_version,
    gateway_encoding: @gateway_encoding,
    gateway_compression: @gateway_compression,
    shards: @shards,
    cache: @cache,
    max_reconnect_delay: @max_reconnect_delay,
    initial_reconnect_delay: @initial_reconnect_delay,
    enable_resume: @enable_resume,
    heartbeat_interval_buffer: @heartbeat_interval_buffer,
    rest_timeout: @rest_timeout,
    rest_open_timeout: @rest_open_timeout,
    rest_read_timeout: @rest_read_timeout,
    compression_threshold: @compression_threshold,
    intents: @intents,
    log_level: @log_level,
    log_format: @log_format,
    log_output: @log_output,
    log_file_path: @log_file_path,
    log_rotate_age: @log_rotate_age,
    log_rotate_size: @log_rotate_size,
    trace_enabled: @trace_enabled,
    error_tracking: @error_tracking
  }
end

#with(**overrides) ⇒ Configuration

Get a new configuration with modified options

Parameters:

  • overrides (Hash)

    Options to override

Returns:



180
181
182
# File 'lib/discord_rda/core/configuration.rb', line 180

def with(**overrides)
  self.class.new(to_h.merge(overrides))
end