Class: Clacky::Channel::Adapters::DingTalk::Adapter

Inherits:
Base
  • Object
show all
Defined in:
lib/clacky/server/channel/adapters/dingtalk/adapter.rb

Constant Summary collapse

WEBHOOK_SAFETY_MARGIN_MS =
5 * 60 * 1000

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#platform_id, #supports_message_updates?, #update_message

Constructor Details

#initialize(config) ⇒ Adapter

Returns a new instance of Adapter.



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/clacky/server/channel/adapters/dingtalk/adapter.rb', line 44

def initialize(config)
  @config        = config
  @api_client    = ApiClient.new(
    client_id:     config[:client_id],
    client_secret: config[:client_secret]
  )
  @stream_client = nil
  @running       = false
  # chat_id => { url:, expires_at_ms: } — sessionWebhook is per-message
  # and expires (~2h). We cache it from inbound events and validate on send.
  @webhook_urls  = {}
  @webhook_mutex = Mutex.new
end

Class Method Details

.env_keysObject



16
17
18
# File 'lib/clacky/server/channel/adapters/dingtalk/adapter.rb', line 16

def self.env_keys
  %w[IM_DINGTALK_CLIENT_ID IM_DINGTALK_CLIENT_SECRET IM_DINGTALK_ALLOWED_USERS]
end

.platform_config(data) ⇒ Object



20
21
22
23
24
25
26
# File 'lib/clacky/server/channel/adapters/dingtalk/adapter.rb', line 20

def self.platform_config(data)
  {
    client_id:     data["IM_DINGTALK_CLIENT_ID"],
    client_secret: data["IM_DINGTALK_CLIENT_SECRET"],
    allowed_users: data["IM_DINGTALK_ALLOWED_USERS"]&.split(",")&.map(&:strip)&.reject(&:empty?)
  }
end

.platform_idObject



12
13
14
# File 'lib/clacky/server/channel/adapters/dingtalk/adapter.rb', line 12

def self.platform_id
  :dingtalk
end

.set_env_data(data, config) ⇒ Object



28
29
30
31
32
# File 'lib/clacky/server/channel/adapters/dingtalk/adapter.rb', line 28

def self.set_env_data(data, config)
  data["IM_DINGTALK_CLIENT_ID"]     = config[:client_id]
  data["IM_DINGTALK_CLIENT_SECRET"]  = config[:client_secret]
  data["IM_DINGTALK_ALLOWED_USERS"]  = Array(config[:allowed_users]).join(",")
end

.test_connection(fields) ⇒ Object



34
35
36
37
38
39
40
41
42
# File 'lib/clacky/server/channel/adapters/dingtalk/adapter.rb', line 34

def self.test_connection(fields)
  client = ApiClient.new(
    client_id:     fields[:client_id].to_s.strip,
    client_secret: fields[:client_secret].to_s.strip
  )
  client.test_connection
rescue => e
  { ok: false, error: e.message }
end

Instance Method Details

#send_text(chat_id, text, reply_to: nil) ⇒ Object

Parameters:

  • chat_id (String)

    — for DingTalk Stream Mode, chat_id == webhook URL



77
78
79
80
81
82
83
84
# File 'lib/clacky/server/channel/adapters/dingtalk/adapter.rb', line 77

def send_text(chat_id, text, reply_to: nil)
  webhook_url = resolve_webhook(chat_id)
  unless webhook_url
    Clacky::Logger.warn("[dingtalk] no valid sessionWebhook for chat #{chat_id} (expired or never received)")
    return { ok: false, error: "session_webhook_expired" }
  end
  @api_client.send_via_webhook(webhook_url, text)
end

#start(&on_message) ⇒ Object



60
61
62
63
64
65
66
67
68
69
# File 'lib/clacky/server/channel/adapters/dingtalk/adapter.rb', line 60

def start(&on_message)
  @running    = true
  @on_message = on_message

  @stream_client = StreamClient.new(
    client_id:     @config[:client_id],
    client_secret: @config[:client_secret]
  )
  @stream_client.start { |frame| handle_frame(frame) }
end

#stopObject



71
72
73
74
# File 'lib/clacky/server/channel/adapters/dingtalk/adapter.rb', line 71

def stop
  @running = false
  @stream_client&.stop
end

#validate_config(config) ⇒ Object



86
87
88
89
90
91
# File 'lib/clacky/server/channel/adapters/dingtalk/adapter.rb', line 86

def validate_config(config)
  errors = []
  errors << "client_id is required"     if config[:client_id].to_s.strip.empty?
  errors << "client_secret is required" if config[:client_secret].to_s.strip.empty?
  errors
end