Class: Clacky::Channel::Adapters::DingTalk::ApiClient

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

Overview

DingTalk Bot API client — sends messages via session webhook (Stream Mode).

Constant Summary collapse

OPENAPI_BASE =
"https://api.dingtalk.com"

Instance Method Summary collapse

Constructor Details

#initialize(client_id:, client_secret:) ⇒ ApiClient

Returns a new instance of ApiClient.



15
16
17
18
19
20
# File 'lib/clacky/server/channel/adapters/dingtalk/api_client.rb', line 15

def initialize(client_id:, client_secret:)
  @client_id     = client_id
  @client_secret = client_secret
  @token         = nil
  @token_expires_at = 0
end

Instance Method Details

#access_tokenObject

Fetch a short-lived access token (cached for its lifetime).



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/clacky/server/channel/adapters/dingtalk/api_client.rb', line 51

def access_token
  return @token if @token && Time.now.to_i < @token_expires_at - 60

  uri  = URI.parse("#{OPENAPI_BASE}/v1.0/oauth2/accessToken")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  req = Net::HTTP::Post.new(uri.path, "Content-Type" => "application/json")
  req.body = JSON.generate({ appKey: @client_id, appSecret: @client_secret })

  resp = http.request(req)
  data = JSON.parse(resp.body)

  raise "DingTalk token error (#{resp.code}): #{data["message"] || resp.body}" unless resp.code.to_i == 200

  @token = data["accessToken"] || raise("Missing accessToken in response")
  @token_expires_at = Time.now.to_i + (data["expireIn"] || 7200).to_i
  @token
end

#send_via_webhook(webhook_url, text, msg_type: :text) ⇒ Object

Send a text (or Markdown) message via the session webhook URL. In Stream Mode, inbound events carry a ‘sessionWebhook` — use that directly.

Parameters:

  • webhook_url (String)
  • text (String)
  • msg_type (:text, :markdown) (defaults to: :text)

    (default :text)



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/clacky/server/channel/adapters/dingtalk/api_client.rb', line 27

def send_via_webhook(webhook_url, text, msg_type: :text)
  body = if msg_type == :markdown
    { msgtype: "markdown", markdown: { title: "Reply", text: text } }
  else
    { msgtype: "text", text: { content: text } }
  end

  uri = URI.parse(webhook_url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = uri.scheme == "https"
  req = Net::HTTP::Post.new(uri.request_uri, "Content-Type" => "application/json")
  req.body = JSON.generate(body)
  resp = http.request(req)
  data = JSON.parse(resp.body) rescue {}
  if resp.code.to_i != 200 || (data["errcode"] && data["errcode"] != 0)
    Clacky::Logger.warn("[dingtalk] webhook send rejected (#{resp.code}): #{resp.body}")
  end
  data
rescue => e
  Clacky::Logger.warn("[dingtalk] webhook send failed: #{e.message}")
  {}
end

#test_connectionHash

Validate credentials by fetching a token.

Returns:

  • (Hash)

    { ok: Boolean, error: String? }



72
73
74
75
76
77
# File 'lib/clacky/server/channel/adapters/dingtalk/api_client.rb', line 72

def test_connection
  access_token
  { ok: true, message: "DingTalk access token obtained" }
rescue => e
  { ok: false, error: e.message }
end