mbarnach / SwiftySlack

Create Slack messages in Swift.
Apache License 2.0
9 stars 5 forks source link

SwiftySlack

Swift 5.1 Swift PM Compatible Build Status codecov

SwiftySlack is a Swift 5.1 package that allows you to create Slack messages in Swift. It uses the new Block type for Slack messages, and as many property wrappers to prevent invalid messages.

Example

// Create a block:
let section = SectionBlock(text: Text("A message *with some bold text* and _some italicized text_."))

// Create the message:
let message = Message(blocks: blocks, to: "#general", alternateText: "A message.")

// Send the message:
let webAPI = WebAPI(token: "xoxb-123456789")
webAPI.send(message: message)

SwiftySlack is using a simple, yet effective Promises for the response, instead of using the traditional closure completion handlers. These promises are coming from an article by John Sundell: Under the hood of futures and promises in Swift The returned payload is resolved internally: the promise is fulfill if the payload is right, other it is rejected with the error message from Slack. The returned type is the initial Slack message, with metadata fields updated (channel, timestamp for parent manipulation, etc.).

The requests are sent with SwiftyRequest.

You can make complex requests easily, like the Slack Template "Notification":

let blocks = [
  SectionBlock(text: 
                PlainText(text: "Looks like you have a scheduling conflict with this event:",
                          emoji: true)),
  DividerBlock(),
  SectionBlock(text: 
                MarkdownText("*<fakeLink.toUserProfiles.com|Iris / Zelda 1-1>*\nTuesday, January 21 4:00-4:30pm\nBuilding 2 - Havarti Cheese (3)\n2 guests"),
              accessory: ImageElement(image_url: 
                                        URL(string: 
                                              "https://api.slack.com/img/blocks/bkb_template_images/notifications.png")!,
                                      alt_text: "calendar thumbnail")),
  ContextBlock(elements: [
                ContextBlock.ContextElement(image: 
                                              ImageElement(image_url: 
                                                            URL(string: 
                                                                  "https://api.slack.com/img/blocks/bkb_template_images/notificationsWarningIcon.png")!,
                                                           alt_text: "notifications warning icon")),
                ContextBlock.ContextElement(text: 
                                              MarkdownText("*Conflicts with Team Huddle: 4:15-4:30pm*"))
              ]
  ),
  DividerBlock(),
  SectionBlock(text: MarkdownText("*Propose a new time:*")),
  SectionBlock(text: MarkdownText("*Today - 4:30-5pm*\nEveryone is available: @iris, @zelda"),
               accessory: ButtonElement(text: 
                                          PlainText(text: "Choose",
                                                    emoji: true),
                                        value: "click_me_123")),
  SectionBlock(text: MarkdownText("*Tomorrow - 4-4:30pm*\nEveryone is available: @iris, @zelda"),
               accessory: ButtonElement(text: 
                                          PlainText(text: "Choose",
                                                    emoji: true),
                                        value: "click_me_123")),
  SectionBlock(text: MarkdownText("*Tomorrow - 6-6:30pm*\nSome people aren't available: @iris, ~@zelda~"),
               accessory: ButtonElement(text: 
                                          PlainText(text: "Choose",
                                                    emoji: true),
                                        value: "click_me_123")),
  SectionBlock(text: MarkdownText("*<fakelink.ToMoreTimes.com|Show more times>*"))
]

let message = Message(blocks: blocks,
                      to: channel,
                      alternateText: "Notification")

let webAPI = WebAPI(token: "xoxb-123456789")
webAPI.send(message: message).then { parent in 
  webAPI.send(message: Message(
    blocks: [
      SectionBlock(text: MarkdownText("*Custom* reply 1"))
      ],
      to: channel,
      alternateText: "reply to",
      reply: parent.thread_ts)
}.catch { error in
  print("Something went wrong: \(error).")
}

In case of error, you can retrieve a description like that:

webAPI.send(ephemeral: Message(blocks: [],
                               to: self.channel,
                               alternateText: "Not in this channel"),
            to: "unknown user to this channel")
  .catch { error in
  print("Cannot send the message: \(error.description).")
}

Notification template

SwiftySlack has been tested on all the Slack blocks templates (see the tests).

Features:

Currently SwiftySlack supports:

Notes:

SwiftySlack only support the recommanded WebAPI and the Blocks, not the deprecated Attachments.