Skip to content

Commit

Permalink
Handle rate limiting by sleeping required amount
Browse files Browse the repository at this point in the history
  • Loading branch information
kddnewton committed May 21, 2024
1 parent 10cf9d7 commit acfb39f
Showing 1 changed file with 22 additions and 23 deletions.
45 changes: 22 additions & 23 deletions lib/smart_todo/slack_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ def initialize(slack_token)
#
# @see https://api.slack.com/methods/users.lookupByEmail
def lookup_user_by_email(email)
headers = { "Content-Type" => "application/x-www-form-urlencoded" }

request(:get, "/api/users.lookupByEmail?email=#{CGI.escape(email)}", nil, headers)
dispatch(
Net::HTTP::Get.new(
"/api/users.lookupByEmail?email=#{CGI.escape(email)}",
default_headers.merge("Content-Type" => "application/x-www-form-urlencoded"),
),
)
end

# Send a message to a Slack channel or to a user
Expand All @@ -55,7 +58,11 @@ def lookup_user_by_email(email)
#
# @see https://api.slack.com/methods/chat.postMessage
def post_message(channel, text)
request(:post, "/api/chat.postMessage", JSON.dump(channel: channel, text: text))
dispatch(
Net::HTTP::Post.new("/api/chat.postMessage", default_headers).tap do |request|
request.body = JSON.dump(channel: channel, text: text)
end,
)
end

private
Expand All @@ -67,27 +74,19 @@ def post_message(channel, text)
#
# @raise [Net::HTTPError] in case the request to Slack failed
# @raise [SlackClient::Error] in case Slack returns a { ok: false } in the body
def request(method, endpoint, data = nil, headers = {})
response = case method
when :post, :patch
@client.public_send(method, endpoint, data, default_headers.merge(headers))
else
@client.public_send(method, endpoint, default_headers.merge(headers))
end
def dispatch(request)
response = @client.request(request)
attempts = 1

slack_response!(response)
end
while response.is_a?(Net::HTTPTooManyRequests) && attempts < 5
sleep(Integer(response["Retry-After"]))
response = @client.request(request)
attempts += 1
end

# Check if the response to Slack was a 200 and the Slack API request was successful
#
# @param response [Net::HTTPResponse] a net Net::HTTPResponse subclass
# (Net::HTTPOK, Net::HTTPNotFound ...)
# @return [Hash]
#
# @raise [Net::HTTPError] in case the request to Slack failed
# @raise [SlackClient::Error] in case Slack returns a { ok: false } in the body
def slack_response!(response)
raise(Net::HTTPError.new("Request to slack failed", response)) unless response.code_type < Net::HTTPSuccess
unless response.code_type < Net::HTTPSuccess
raise(Net::HTTPError.new("Request to slack failed", response))
end

body = JSON.parse(response.body)

Expand Down

0 comments on commit acfb39f

Please sign in to comment.