本記事は
モバイルアプリWeek
1日目の記事です。
📱
イベント告知
▶▶ 本記事 ▶▶
2日目
📱
SwiftでSlackに投稿するための準備から、実際に投稿してみる所までを試作してみたのでまとめました!
準備:Slack appを作成する
以前はカスタムインテグレーションよりIncoming Webhookを主に利用していたようです。
しかし、2020年よりカスタムインテグレーションを利用することが非推奨になっているので現時点(2022年)で推奨されているSlack Appを利用した方法で実装&紹介させて頂きます。
(カスタムインテグレーションに関するドキュメント)
WebhookのURLを取得する
手順は以下の通りです。
- 右記よりSlack APIの画面を表示 Slack API: Applications | Slack
- Create New Appを選択
- Form scratchを選択
- App Nameに好きな名前を入力し、紐づけたいworkspaceを選択してCreate Appを選択
- Basic InformationよりIncoming Webhooksを選択
- Activate Incoming WebhooksをOnにし、Add New Webhook to Workspaceを選択
- 投稿先チャンネルをダウンリストから選択できるので任意のチャンネルを選択
- Webhook URLが発行されるのでコピーなどしてメモしておく
以上でSlack appを利用する準備は終了です。
実装:コードを書いていく
ここからは実際にコードを書いていく作業になります。
と言っても今回はほぼツールを使ってコードを生成していくのでほぼ書かなくてもできます!w
Slackへ投稿するには上記で取得したWebhook URLにJSONをパラメタとして POSTリクエストします。
今回attachmentsを利用しましたがattachmentsがどういったものか、違いは以下の通りです。
attachments無し
{ "blocks": [ { "type": "context", "elements": [ { "type": "image", "image_url": "https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg", "alt_text": "cute cat" }, { "type": "plain_text", "text": "UserName: Tama", } ] }, { "type": "section", "text": { "type": "plain_text", "text": "今から仕事始める!", } } ] }
attachments有り
{ "attachments": [ { "color": "#f2c744", "blocks": [ { "type": "context", "elements": [ { "type": "image", "image_url": "https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg", "alt_text": "cute cat" }, { "type": "plain_text", "text": "UserName: Tama" } ] }, { "type": "section", "text": { "type": "plain_text", "text": "今から仕事始める!" } } ] } ] }
上記の通りattachmentsを使用する場合はattachmentsを追加し、その中にblockを書いていきます。
またBlock Kit Builderと言うプレビュー表示をしてくれる便利なものが公式にありますので、ここで事前に確認すると良いかと思います。
(以下のURLよりBuild and prototype visuallyにてBlock Kit Builderを試すことができます)
ドキュメントを見ると基本的にはblocks内に(もしくはfields内)にtextやimageを配置してカスタマイズしていきますが、attachments直下に書くこともできます。
今回はこちらのがシンプルにかけるので採用しましたが、Imageをtextの間に表示させたいとかになるとドキュメントを見る限り"elements"を使用しなければできないと思いますので、そこはお好みで採択していただければと思います。
一応下記にattachments直下に書くサンプルコードを掲載しておきます。
{ "channel": "CBR2V3XEX", "attachments": [ { "fallback": "Plain-text summary of the attachment.", "color": "#2eb886", "pretext": "Optional text that appears above the attachment block", "author_name": "Bobby Tables", "author_link": "http://flickr.com/bobby/", "author_icon": "http://flickr.com/icons/bobby.jpg", "title": "Slack API Documentation", "title_link": "https://api.slack.com/", "text": "Optional text that appears within the attachment", "fields": [ { "title": "Priority", "value": "High", "short": false } ], "image_url": "http://my-website.com/path/to/image.jpg", "thumb_url": "http://example.com/path/to/thumb.png", "footer": "Slack API", "footer_icon": "https://platform.slack-edge.com/img/default_application_icon.png", "ts": 123456789 } ] }
以下attachmentsに関してのドキュメント
Creating rich message layouts | Slack
実際に以下のJSONでSlackに投稿してみた様子
{ "attachments": [ { "color": "#2d2d2d", "author_name": "yuji", "author_icon": "icon url", "title": "勤務", "text": "Start", "footer": "OneTapLog app", "footer_icon": "icon url", } ] }
上から順に
author_iconとauthor_nameで指定したnameやurlからImageを取得して表示しています。
次にtitle、textを表示、最後にfooter_iconで指定したurlからImageを取得し、footerで指定したアプリ名(ここではOneTapLog appとしています)を表示しています。
またattachmentsの色はcolorで指定したカラーコードの色が表示されます。
※実際に試してみる際はauthor_iconとfooter_iconには画像ファイルがあるURLを転記してください。
JSONからstructへ
JSONからSwiftのstructへ変換する際、以下のサイトを使用すると一瞬で変換してくれます!
(今回の記事で一番紹介したかった便利ポイントw)
もちろん自分で書いても問題ないです。
変換されたコードはコチラ
import Foundation // MARK: - Welcome struct Welcome: Codable { var attachments: [Attachment] } // MARK: - Attachment struct Attachment: Codable { var color, authorName, authorIcon, title: String var text, footer, footerIcon: String enum CodingKeys: String, CodingKey { case color case authorName case authorIcon case title, text, footer case footerIcon } }
デフォルトではletで吐き出しますが
Use var instead of let for object properties
にチェックを入れておくとvarで吐き出してくれます。
またデフォルトではstructがWelcomeになっていたり、CodingKeyによってキャメルケースになっているので少し手直しします。
以下整理してみたコードです。
import Foundation struct Payload: Codable { var attachments: [Attachment] } struct Attachment: Codable { var color: String var authorName: String var authorIcon: String var title: String var text: String var footer = "OneTapLog app" var footerIcon = "表示させたい画像のURL" }
実装してみる
POSTリクエストするメソッド
func post() async throws { // Webhook URLで取得したURL let url = URL(string: "https://hooks.slack.com/services/XXXXX")! var request = URLRequest(url: url) // Postする際は必ずhttpMethodにて"POST"を定義する request.httpMethod = "POST" request.addValue("application/json", forHTTPHeaderField: "Content-Type") // Slackに投稿する内容 let payload = Payload(attachments: [Attachment( color: "#2d2d2d", authorName: "user name", authorIcon: "https://XXXXX", title: "勤務", text: "Start")]) let jsonEncoder = JSONEncoder() // SnakeCaseへ変換 jsonEncoder.keyEncodingStrategy = .convertToSnakeCase // JSONへ変換 request.httpBody = try jsonEncoder.encode(payload) jsonEncoder.keyEncodingStrategy = .convertToSnakeCase guard let (data, response) = try? await URLSession.shared.data(for: request) else { throw APIError.networkError } guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw APIError.unknown } print("success:\(data)") }
以上です!
後は適当な画面を作ってpostメソッド叩けばWebhook URLのスレッドに投稿されます!
所感
今回はとりあえずアプリからOneTapでSlackに投稿する機能を作りたくて試してみました!
今後はWebhook URLやUserNameを登録する画面や、編集できる画面、ボタンをカスタマイズして色んな投稿をOneTapで投稿できるように作り込んでいきたいと思います!
またできたらどこかのタイミングで公開していきたいと思います!
参考サイト一覧
- Slack App
https://api.slack.com/apps - Block Kit
https://api.slack.com/block-kit - attachmentsのドキュメント
https://api.slack.com/messaging/composing/layouts#attachments - JSONコードからstructを生成してくれるジェネレーター
https://quicktype.io - カスタムインテグレーションに関するドキュメント
https://api.slack.com/legacy/custom-integrations