我如何写入 Slack 的套接字模式 websocket 端点以使用 Ruby 发送聊天消息?
What do I write to Slack's Socket-Mode websocket endpoint to send a chat message using Ruby?
我正在尝试使用 Ruby 为我的团队编写一个简单的 Slack 聊天机器人。这有点粗糙,因为 Slack 没有对 Ruby 的官方支持。尽管如此,我已经能够使用我编写的这段代码打开一个 websocket 并收听 Slack 事件:
# frozen_string_literal: true
require "async"
require "async/io/stream"
require "async/http/endpoint"
require "async/websocket/client"
require "excon"
require "json"
module Slack
class Client
Error = Class.new(StandardError)
AquisitionError = Class.new(Error)
ConnectionError = Class.new(Error)
CONNECTION_AQUISITION_ENDPOINT = "https://slack.com/api/apps.connections.open"
def initialize
@token = "my-app-token"
end
def connect
connection_info = Excon.post(CONNECTION_AQUISITION_ENDPOINT, headers: {
"Content-type": "application/x-www-form-urlencoded",
Authorization: "Bearer #{@token}",
})
result = JSON.parse(connection_info.body)
raise(AquisitionError) unless result["ok"] # better error later
websocket = Async::HTTP::Endpoint.parse(result["url"])
Async do |_task|
Async::WebSocket::Client.connect(websocket) do |connection|
payload = connection.read
raise(ConnectionError) unless connection_check(payload)
puts "Listening..."
handle(payload) while (payload = connection.read)
end
end
end
private
def connection_check(payload)
payload[:type] == "hello"
end
def handle(payload)
puts payload.inspect
end
end
end
文档让我相信我可以将 JSON 写入此 connection
例如
connection.write({
# JSON to send a message in Slack here
# Probably need to specify the channel somehow
# Probably need to specify if I'm using markdown
# Have no idea what the form should be
})
但我还没弄清楚 JSON 需要采用什么形式。
我也 运行 参与其中,并试图确定为什么文档没有提供明确的答案。看来您实际上并没有通过 websockets 发送回请求,而是仅使用 websockets 来接受请求。
这意味着您将使用类似 webAPI 的东西来执行响应操作,您可以在 PythonSDK with websockets example provided by Slack.
中看到这种模式
例如:
if req.type == "events_api":
# Acknowledge the request, this ack is sent back over websockets
# the format is: { 'envelope_id': req['envelope_id'] }
response = SocketModeResponse(envelope_id=req.envelope_id)
client.send_socket_mode_response(response)
# Add a reaction to the message if it's a new message
# notice that this request uses the web_client here and not the socket one
if req.payload["event"]["type"] == "message" \
and req.payload["event"].get("subtype") is None:
client.web_client.reactions_add(
name="eyes",
channel=req.payload["event"]["channel"],
timestamp=req.payload["event"]["ts"],
)
我正在尝试使用 Ruby 为我的团队编写一个简单的 Slack 聊天机器人。这有点粗糙,因为 Slack 没有对 Ruby 的官方支持。尽管如此,我已经能够使用我编写的这段代码打开一个 websocket 并收听 Slack 事件:
# frozen_string_literal: true
require "async"
require "async/io/stream"
require "async/http/endpoint"
require "async/websocket/client"
require "excon"
require "json"
module Slack
class Client
Error = Class.new(StandardError)
AquisitionError = Class.new(Error)
ConnectionError = Class.new(Error)
CONNECTION_AQUISITION_ENDPOINT = "https://slack.com/api/apps.connections.open"
def initialize
@token = "my-app-token"
end
def connect
connection_info = Excon.post(CONNECTION_AQUISITION_ENDPOINT, headers: {
"Content-type": "application/x-www-form-urlencoded",
Authorization: "Bearer #{@token}",
})
result = JSON.parse(connection_info.body)
raise(AquisitionError) unless result["ok"] # better error later
websocket = Async::HTTP::Endpoint.parse(result["url"])
Async do |_task|
Async::WebSocket::Client.connect(websocket) do |connection|
payload = connection.read
raise(ConnectionError) unless connection_check(payload)
puts "Listening..."
handle(payload) while (payload = connection.read)
end
end
end
private
def connection_check(payload)
payload[:type] == "hello"
end
def handle(payload)
puts payload.inspect
end
end
end
文档让我相信我可以将 JSON 写入此 connection
例如
connection.write({
# JSON to send a message in Slack here
# Probably need to specify the channel somehow
# Probably need to specify if I'm using markdown
# Have no idea what the form should be
})
但我还没弄清楚 JSON 需要采用什么形式。
我也 运行 参与其中,并试图确定为什么文档没有提供明确的答案。看来您实际上并没有通过 websockets 发送回请求,而是仅使用 websockets 来接受请求。
这意味着您将使用类似 webAPI 的东西来执行响应操作,您可以在 PythonSDK with websockets example provided by Slack.
中看到这种模式例如:
if req.type == "events_api":
# Acknowledge the request, this ack is sent back over websockets
# the format is: { 'envelope_id': req['envelope_id'] }
response = SocketModeResponse(envelope_id=req.envelope_id)
client.send_socket_mode_response(response)
# Add a reaction to the message if it's a new message
# notice that this request uses the web_client here and not the socket one
if req.payload["event"]["type"] == "message" \
and req.payload["event"].get("subtype") is None:
client.web_client.reactions_add(
name="eyes",
channel=req.payload["event"]["channel"],
timestamp=req.payload["event"]["ts"],
)