Class: BrowserSession

Inherits:
Object
  • Object
show all
Defined in:
lib/clacky/default_skills/channel-setup/feishu_setup.rb

Overview


BrowserSession — minimal browser wrapper, only used for login check + cookies


Instance Method Summary collapse

Constructor Details

#initialize(client) ⇒ BrowserSession

Returns a new instance of BrowserSession.



123
124
125
# File 'lib/clacky/default_skills/channel-setup/feishu_setup.rb', line 123

def initialize(client)
  @client = client
end

Instance Method Details

#cookiesObject

Extract all cookies for open.feishu.cn from the browser. The browser evaluate output may be wrapped in MCP markdown — parse it out.



152
153
154
155
156
157
158
# File 'lib/clacky/default_skills/channel-setup/feishu_setup.rb', line 152

def cookies
  result = @client.call("act",
    kind: "evaluate",
    js: "document.cookie")
  raw = result["output"].to_s
  extract_string_value(raw)
end

#csrf_tokenObject

Get CSRF token — try multiple sources



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/clacky/default_skills/channel-setup/feishu_setup.rb', line 161

def csrf_token
  # Try x-csrf-token from cookie
  all_cookies = cookies
  all_cookies.split(";").each do |pair|
    k, v = pair.strip.split("=", 2)
    return v.strip if k.strip =~ /csrf.token/i && v
  end

  # Try lark_oapi_csrf_token specifically via JS
  result = @client.call("act",
    kind: "evaluate",
    js: "document.cookie.split(';').map(c=>c.trim()).find(c=>c.startsWith('lark_oapi_csrf_token='))?.split('=')[1] || document.cookie.split(';').map(c=>c.trim()).find(c=>c.startsWith('lgw_csrf_token='))?.split('=')[1] || document.cookie.split(';').map(c=>c.trim()).find(c=>c.startsWith('swp_csrf_token='))?.split('=')[1] || ''")
  token = extract_string_value(result["output"].to_s)
  return token unless token.empty?

  # Try from window object
  result = @client.call("act",
    kind: "evaluate",
    js: "window.csrfToken || ''")
  extract_string_value(result["output"].to_s)
end

#evaluate(js) ⇒ Object

Run JavaScript in the page context and return the raw output string.



145
146
147
148
# File 'lib/clacky/default_skills/channel-setup/feishu_setup.rb', line 145

def evaluate(js)
  result = @client.call("act", kind: "evaluate", js: js)
  result["output"].to_s
end

#extract_string_value(raw) ⇒ Object

The MCP tool wraps evaluate results in markdown code blocks:

"Script ran on page and returned:\n```json\n\"value\"\n```\n"

This extracts the actual string value.



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/clacky/default_skills/channel-setup/feishu_setup.rb', line 186

def extract_string_value(raw)
  # Try to find a JSON string value inside ```json ... ``` block
  if raw =~ /```json\s*(.*?)\s*```/m
    inner = $1.strip
    begin
      parsed = JSON.parse(inner)
      return parsed.to_s if parsed.is_a?(String)
      # If it's not a string (e.g. already the cookie text), return as-is
      return inner
    rescue JSON::ParserError
      return inner
    end
  end
  # No markdown wrapper — return raw stripped
  raw.strip
end


127
128
129
130
131
# File 'lib/clacky/default_skills/channel-setup/feishu_setup.rb', line 127

def navigate(url)
  @client.call("navigate", url: url)
  sleep 2
  snapshot
end

#open(url) ⇒ Object



133
134
135
136
137
# File 'lib/clacky/default_skills/channel-setup/feishu_setup.rb', line 133

def open(url)
  @client.call("open", url: url)
  sleep 2
  snapshot
end

#snapshot(interactive: true, compact: true) ⇒ Object



139
140
141
142
# File 'lib/clacky/default_skills/channel-setup/feishu_setup.rb', line 139

def snapshot(interactive: true, compact: true)
  result = @client.call("snapshot", interactive: interactive, compact: compact)
  result["output"].to_s
end