Skip to content
This repository has been archived by the owner on Feb 17, 2022. It is now read-only.

Commit

Permalink
Send message to Slack (#30)
Browse files Browse the repository at this point in the history
Send message to Slack
  • Loading branch information
onmyway133 committed Dec 30, 2019
2 parents 9524607 + 30bce28 commit 3f2624d
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Documentation/GettingStarted.md
Expand Up @@ -128,6 +128,7 @@ Contains the core utilities, Task protocol and some core tasks
- Concurrent: run sub tasks in parallel
- DownloadFile: Download and save file
- MoveFile: Move file to another location
- [Slack](Tasks/Slack.md): send message as a bot to Slack

### PumaiOS

Expand All @@ -149,7 +150,6 @@ Contains Android related tasks. TBD

Contains extra tasks

- Slack: interact with Slack
- AppStoreConnect: interact with AppStore Connect
- AppDistribution: interact with Firebase AppDistribution
- Crashlytics: interact with Firebase Crashlytics
18 changes: 18 additions & 0 deletions Documentation/Tasks/Slack.md
@@ -0,0 +1,18 @@
## Slack

### Post message to a channel in Slack

Follow [Create a bot for your workspace](https://slack.com/intl/en-no/help/articles/115005265703-create-a-bot-for-your-workspace) to create, add a bot to your workspace. Obtain `Bot User OAuth Access Token` to use to authenticate

```swift
Slack {
$0.post(
message: .init(
token: ProcessInfo().environment["slackBotToken"]!,
channel: "random",
text: "Hello from Puma",
username: "onmyway133"
)
)
}
```
15 changes: 15 additions & 0 deletions Example/TestPuma/TestPuma/main.swift
Expand Up @@ -56,6 +56,7 @@ func testDrive() {
}

Screenshot {
$0.isEnabled = false
$0.configure(
projectType: .project("TestApp"),
appScheme: "TestApp",
Expand Down Expand Up @@ -86,6 +87,7 @@ func testDrive() {
}

Archive {
$0.isEnabled = false
$0.configure(
projectType: .project("TestApp"),
scheme: "TestApp",
Expand All @@ -94,6 +96,7 @@ func testDrive() {
}

ExportArchive {
$0.isEnabled = false
$0.configure(
projectType: .project("TestApp"),
archivePath: Directory.downloads.appendingPathComponent("TestApp.xcarchive").path,
Expand All @@ -110,6 +113,7 @@ func testDrive() {
}

UploadApp {
$0.isEnabled = false
$0.authenticate(
username: ProcessInfo().environment["username"]!,
password: ProcessInfo().environment["password"]!
Expand All @@ -119,6 +123,17 @@ func testDrive() {
ipaPath: Directory.downloads.appendingPathComponent("TestApp.ipa").path
)
}

Slack {
$0.post(
message: .init(
token: ProcessInfo().environment["slackBotToken"]!,
channel: "random",
text: "Hello from Puma",
username: "onmyway133"
)
)
}
}

workflow.workingDirectory = Directory.home.appendingPathComponent("XcodeProject2/Puma/Example/TestApp").path
Expand Down
4 changes: 4 additions & 0 deletions Sources/Core/Library/Console/Console.swift
Expand Up @@ -29,6 +29,10 @@ open class Console {
print("\(text)".foreground.Red)
}

open func success(_ text: String) {
print("👍 \(text)".foreground.Green)
}

open func warn(_ text: String) {
print("⚠️ \(text)".foreground.Magenta)
}
Expand Down
11 changes: 9 additions & 2 deletions Sources/Core/Library/PumaError.swift
Expand Up @@ -8,8 +8,15 @@
import Foundation

public enum PumaError: Error {
case unknown
case invalid
case validate(String)
case string(String)
case process(terminationStatus: Int32, output: String, error: String)

static func from(string: String?) -> PumaError {
if let string = string {
return PumaError.string(string)
} else {
return PumaError.invalid
}
}
}
122 changes: 122 additions & 0 deletions Sources/Core/Tasks/Slack/Slack.swift
@@ -0,0 +1,122 @@
//
// Slack.swift
// PumaCore
//
// Created by khoa on 30/12/2019.
//

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("Posted: \(message.text)")
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()
}
}

0 comments on commit 3f2624d

Please sign in to comment.