Class: Clacky::ChannelConfig

Inherits:
Object
  • Object
show all
Defined in:
lib/clacky/server/channel/channel_config.rb

Overview

ChannelConfig manages IM platform credentials (Feishu, WeCom, etc.).

Config is stored in ~/.clacky/channels.yml:

channels:
  feishu:
    enabled: true
    app_id: cli_xxx
    app_secret: xxx
    domain: https://open.feishu.cn
    allowed_users:
      - ou_xxx
  wecom:
    enabled: false
    bot_id: xxx
    secret: xxx

This class is only responsible for platform credentials. working_dir and permission_mode live in AgentConfig.

Constant Summary collapse

CONFIG_DIR =
File.join(Dir.home, ".clacky")
CONFIG_FILE =
File.join(CONFIG_DIR, "channels.yml")

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(channels: {}) ⇒ ChannelConfig

Returns a new instance of ChannelConfig.

Parameters:

  • channels (Hash<String, Hash>) (defaults to: {})

    string-keyed platform configs (raw from YAML)



32
33
34
# File 'lib/clacky/server/channel/channel_config.rb', line 32

def initialize(channels: {})
  @channels = channels || {}
end

Class Method Details

.load(config_file = CONFIG_FILE) ⇒ ChannelConfig

Load from disk. Returns an empty instance if the file does not exist.

Parameters:

  • config_file (String) (defaults to: CONFIG_FILE)

Returns:



39
40
41
42
43
44
45
46
47
# File 'lib/clacky/server/channel/channel_config.rb', line 39

def self.load(config_file = CONFIG_FILE)
  if File.exist?(config_file)
    data = YAMLCompat.safe_load(File.read(config_file), permitted_classes: [Symbol]) || {}
  else
    data = {}
  end

  new(channels: data["channels"] || {})
end

Instance Method Details

#any_enabled?Boolean

Returns true if at least one channel is enabled.

Returns:

  • (Boolean)


64
65
66
# File 'lib/clacky/server/channel/channel_config.rb', line 64

def any_enabled?
  @channels.any? { |_, cfg| cfg["enabled"] }
end

#deep_copyChannelConfig

Deep copy — prevents callers from mutating shared config state.

Returns:



174
175
176
# File 'lib/clacky/server/channel/channel_config.rb', line 174

def deep_copy
  self.class.new(channels: JSON.parse(JSON.generate(@channels)))
end

#disable_platform(platform) ⇒ Object

Disable a platform (keeps credentials, just sets enabled: false).

Parameters:

  • platform (Symbol, String)


160
161
162
163
164
# File 'lib/clacky/server/channel/channel_config.rb', line 160

def disable_platform(platform)
  key = platform.to_s
  return unless @channels.key?(key)
  @channels[key]["enabled"] = false
end

#enable_platform(platform) ⇒ Object

Enable a platform (requires it to already be configured).

Parameters:

  • platform (Symbol, String)

Raises:

  • (ArgumentError)

    if the platform has no stored credentials yet.



152
153
154
155
156
# File 'lib/clacky/server/channel/channel_config.rb', line 152

def enable_platform(platform)
  key = platform.to_s
  raise ArgumentError, "Platform #{platform} is not configured" unless @channels.key?(key)
  @channels[key]["enabled"] = true
end

#enabled?(platform) ⇒ Boolean

Returns true if the given platform is configured and enabled.

Parameters:

  • platform (Symbol, String)

Returns:

  • (Boolean)


79
80
81
82
# File 'lib/clacky/server/channel/channel_config.rb', line 79

def enabled?(platform)
  cfg = @channels[platform.to_s]
  cfg && cfg["enabled"]
end

#enabled_platformsArray<Symbol>

Returns the list of enabled platform symbols.

Returns:

  • (Array<Symbol>)


70
71
72
73
74
75
# File 'lib/clacky/server/channel/channel_config.rb', line 70

def enabled_platforms
  @channels
    .select { |_, cfg| cfg["enabled"] }
    .keys
    .map(&:to_sym)
end

#platform_config(platform) ⇒ Hash?

Return the symbol-keyed config hash expected by each adapter’s initializer. Returns nil if the platform is not configured.

Parameters:

  • platform (Symbol, String)

Returns:

  • (Hash, nil)


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/clacky/server/channel/channel_config.rb', line 89

def platform_config(platform)
  raw = @channels[platform.to_s]
  return nil unless raw

  case platform.to_sym
  when :feishu
    {
      app_id:        raw["app_id"],
      app_secret:    raw["app_secret"],
      domain:        raw["domain"],
      allowed_users: raw["allowed_users"]
    }.compact
  when :wecom
    {
      bot_id: raw["bot_id"],
      secret: raw["secret"]
    }.compact
  when :weixin
    {
      token:         raw["token"],
      base_url:      raw["base_url"],
      allowed_users: raw["allowed_users"]
    }.compact
  when :discord
    {
      bot_token:     raw["bot_token"]
    }.compact
  when :dingtalk
    {
      client_id:     raw["client_id"],
      client_secret: raw["client_secret"],
      allowed_users: raw["allowed_users"]
    }.compact
  when :telegram
    {
      bot_token:     raw["bot_token"],
      base_url:      raw["base_url"],
      parse_mode:    raw.key?("parse_mode") ? raw["parse_mode"] : "Markdown",
      allowed_users: raw["allowed_users"]
    }.compact
  else
    # Unknown platform — pass all non-meta keys as symbol-keyed hash
    raw.reject { |k, _| k == "enabled" }
       .transform_keys(&:to_sym)
  end
end

#remove_platform(platform) ⇒ Object

Remove a platform entry entirely.

Parameters:

  • platform (Symbol, String)


168
169
170
# File 'lib/clacky/server/channel/channel_config.rb', line 168

def remove_platform(platform)
  @channels.delete(platform.to_s)
end

#save(config_file = CONFIG_FILE) ⇒ Object

Persist to disk.

Parameters:

  • config_file (String) (defaults to: CONFIG_FILE)


51
52
53
54
55
# File 'lib/clacky/server/channel/channel_config.rb', line 51

def save(config_file = CONFIG_FILE)
  FileUtils.mkdir_p(File.dirname(config_file))
  File.write(config_file, to_yaml)
  FileUtils.chmod(0o600, config_file)
end

#set_platform(platform, **fields) ⇒ Object

Set or update a platform’s credentials. Merges provided fields into the existing entry. Automatically sets enabled: true unless explicitly provided.

Parameters:

  • platform (Symbol, String)
  • fields (Hash)

    symbol-keyed credential fields



142
143
144
145
146
147
# File 'lib/clacky/server/channel/channel_config.rb', line 142

def set_platform(platform, **fields)
  key = platform.to_s
  @channels[key] ||= {}
  fields.each { |k, v| @channels[key][k.to_s] = v }
  @channels[key]["enabled"] = true unless @channels[key].key?("enabled")
end

#to_yamlString

Serialize to YAML string.

Returns:

  • (String)


59
60
61
# File 'lib/clacky/server/channel/channel_config.rb', line 59

def to_yaml
  YAML.dump({ "channels" => @channels })
end