1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
require 'httpx'
require 'http/form_data'
module Dingtalk
class HttpClient
attr_reader :http
def initialize
@http = HTTPX.with(**RailsDingtalk.config.httpx)
end
def get(path, headers: {}, params: {}, base: nil, **options)
headers['Accept'] ||= 'application/json'
url = base + path
response = @http.with_headers(headers).get(url, params: params)
parse_response(response, options[:as])
end
def post(path, payload, headers: {}, params: {}, base: nil, **options)
headers['Accept'] ||= 'application/json'
headers['Content-Type'] ||= 'application/json'
url = base + path
response = @http.with_headers(headers).post(url, params: params, body: payload)
parse_response(response, options[:as])
end
def post_file(path, file, headers: {}, params: {}, base: nil, **options)
headers['Accept'] ||= 'application/json'
url = base + path
form_file = file.is_a?(HTTP::FormData::File) ? file : HTTP::FormData::File.new(file)
response = @http.plugin(:multipart).with_headers(headers).post(
url,
params: params,
form: { media: form_file }
)
parse_response(response, options[:as])
end
private
def parse_response(response, parse_as)
raise "Request get fail, response status #{response.status}" if response.status != 200
content_type = response.content_type.mime_type
body = response.body.to_s
if content_type =~ /image|audio|video/
data = Tempfile.new('tmp')
data.binmode
data.write(body)
data.rewind
return data
elsif content_type =~ /html|xml/
data = Hash.from_xml(body)
else
data = JSON.parse body.gsub(/[\u0000-\u001f]+/, '')
end
case data['errcode']
when 0 # for request didn't expect results
data
# 42001: access_token timeout
# 40014: invalid access_token
# 40001, invalid credential, access_token is invalid or not latest hint
# 48001, api unauthorized hint, should not handle here # GH-230
when 42001, 40014, 40001, 41001
raise Wechat::AccessTokenExpiredError
# 40029, invalid code for mp # GH-225
# 43004, require subscribe hint # GH-214
when 2
raise Wechat::ResponseError.new(data['errcode'], data['errmsg'])
else
data
end
end
end
end