-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathslackrequest.rkt
104 lines (95 loc) · 4.48 KB
/
slackrequest.rkt
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
(require net/http-client json)
(include "./version.rkt")
(define SlackRequest%
(let ([CLIENT_NAME MODULE_NAME]
[CLIENT_VERSION VERSION])
(class object%
(super-new)
(init [slackRequestProxies #f])
(define userAgent (list
(cons 'client (string-append CLIENT_NAME "/"
CLIENT_VERSION))
(cons 'racket (string-append "Racket/" (version)))
(cons 'system (let ([m (string-split
(system-type 'machine))])
(string-append (car m) "/"
(caddr m))))
(cons 'custom "")))
(define proxies slackRequestProxies)
(define/public (get-user-agent)
(foldl (lambda (keyValue previous)
(string-append
previous
(cdr keyValue)
(if (eq? (car keyValue) 'custom) "" " "))) "" userAgent))
(define/public (append-user-agent name versn)
;; Concatenate and format the user-agent
;; string to be passed into request headers
(set! userAgent (list-set userAgent 3 (string-append
(cdr (assoc 'custom userAgent))
(string-replace name "/" ":")
" "
(string-replace versn "/" ":")
" ")))
userAgent)
(define/public (call token
[request "?"]
#:postData [postData (hash)]
#:timeout [timeout #f]
#:domain [domain "slack.com"])
#|
Perform a POST request to the Slack Web API
Args:
token (str): your authentication token
request (str): the method to call from the Slack API.
For example: 'channels.list'
timeout (float): stop waiting for a response after
a given number of seconds
postData (hash): key/value arguments to pass for the request.
For example: {'channel': 'CABC12345'}
domain (str): if for some reason you want to send your
request to something other than slack.com
|#
;; Check for plural fields and convert them
;; to comma-separated strings, if needed
(define finalPD (sequence-fold
(lambda (previous key value)
(hash-set
previous
key
(if (and (list? value) (member key '(users types
channels)))
(string-join value ",")
value)))
(hash)
(in-hash postData)))
;; Pull file out so it isn't JSON encoded like normal fields.
;; Only do this for requests that are UPLOADING files; downloading files
(when-let ([files (and
(string=? request "files.upload")
(hash-ref finalPD 'file #f))])
(hash 'file files)
(hash-remove finalPD 'file))
;; Fix this if we can send files
(define-values (status headers in)
(http-sendrecv
domain
(string-append "/api/" request)
#:ssl? #t
#:method "POST"
#:headers (list
(string-append
"user-agent: "
(send this get-user-agent))
"Content-Type: application/json"
(string-append
"Authorization: Bearer "
(or token (hash-ref finalPD 'token #f))))
#:data (jsexpr->string finalPD)
;; Check if you can use a timeout
;; Check if you can use proxies
))
(define body (string->jsexpr (port->string in)))
(close-input-port in)
(list (cons 'status status) (cons 'headers headers)
(cons 'body body))))))