How to send message from bot to Slack in Swift

Issue #560

Create a bot

Post message

After adding bot to workspace, we’ll get OAuth Access Token and Bot User OAuth Access Token. Use Bot User OAuth Access Token to test drive bot message sending

https://api.slack.com/methods/chat.postMessage/test

The request url is like

1
https://slack.com/api/chat.postMessage?token=xoxb-7212342835698-890815481123-abcdGgDEFfm2joQs1Vj5mABC&channel=random&text=hello&pretty=1

Code from Puma

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
105
106
107
108
109
110
111
112
113
114
115
import Foundation

public class Slack {
public var name: String = "Send message to Slack"
public var isEnabled = true

private var message: Message?

public init(_ closure: (Slack) -> Void = { _ in }) {
closure(self)
}
}

public extension Slack {
struct Message {
let token: String
let channel: String
let text: String
let username: String?

public init(
token: String,
channel: String,
text: String,
username: String
) {
self.token = token
self.channel = channel
self.text = text
self.username = username
}
}

func post(message: Message) {
self.message = message
}
}

extension Slack: Task {
public func run(workflow: Workflow, completion: @escaping TaskCompletion) {
guard let message = message else {
completion(.failure(PumaError.invalid))
return
}

let sender = MessageSender()
sender.send(message: message, completion: { result in
switch result {
case .success:
Deps.console.success("Message posted successfully")
case .failure(let error):
Deps.console.error("Failed: \(error.localizedDescription)")
}
completion(result)
})
}
}

private class MessageSender {
struct Response: Decodable {
let ok: Bool
let error: String?
}

func send(message: Slack.Message, completion: @escaping (Result<(), Error>) -> Void) {
guard let baseUrl = URL(string: "https://slack.com/api/chat.postMessage") else {
completion(.failure(PumaError.invalid))
return
}

var components = URLComponents(url: baseUrl, resolvingAgainstBaseURL: false)
components?.queryItems = [
URLQueryItem(name: "token", value: message.token),
URLQueryItem(name: "channel", value: message.channel),
URLQueryItem(name: "text", value: message.text),
URLQueryItem(name: "pretty", value: "1")
]

if let username = message.username {
components?.queryItems?.append(
URLQueryItem(name: "username", value: username)
)
}

guard let requestUrl = components?.url else {
completion(.failure(PumaError.invalid))
return
}

var request = URLRequest(url: requestUrl)
request.allHTTPHeaderFields = [
"Accept": "application/json"
]

let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
guard let data = data else {
completion(.failure(error ?? PumaError.invalid))
return
}

do {
let response = try JSONDecoder().decode(Response.self, from: data)
if response.ok {
completion(.success(()))
} else {
completion(.failure(PumaError.from(string: response.error)))
}
} catch {
completion(.failure(error))
}
})

task.resume()
}
}

Read more

Comments