この記事ではSwitt/SwiftUIのアプリとSlackとを連携させる方法について記載します。
実際にはアプリ内である操作(問い合わせ等)をした際に、その情報を自分のSlackへ送信するようなものになります。
Slackの選定理由
以下のポイントからSlackを選定しました。
・メールでの送信の場合、アプリにてフレームワークの追加等、開発が必要
・相手にメールアプリを開かせる、メールアドレスが必要という制約がない
・無料で利用可能
導入ステップ
Slack側の操作
Slackへ登録
- Slackへアクセスし、ユーザーの登録・ワークスペースの作成を行う。
- ワークスペースの画面にアクセスできたことを確認
- 必要な方はチャンネルを作成する(ここにメッセージが届きます)
Webhook URLの作成&取得
Webhook(ウェブフック)は、ウェブアプリケーションやウェブサービスが、特定のイベントが発生した際に外部のシステムに通知を送信する仕組みです。SlackにおいてこのWebhookを作成・取得し、それに向けて情報を渡し、Slackに通知させます。
こちらにアクセスし、以下の画面になっている事を確認
①が自分のワークスペース名になっている事を確認
②でWebhook URLと紐付けたいチャンネルを選択
③を押下する
赤枠のURLがWebhook URLです。メモっておく。
アプリで実装
ここから実際の開発イメージ、ソースコードを記載します。
実装イメージ
以下が実装後のイメージになります。
アプリ側で送りたい情報をテキストフィールドに入力し、作成ボタンを押下することにより、Webhook経由でSlackにメッセージを送信。
ソースコード
以下がアプリとSlackを連携させるソースコードの中身になります。
import SwiftUI
struct ThreadCreate: View {
@State var threadname = ""
@State var explain = ""
//画面を閉じる際の記載に使用
@Environment(\.presentationMode) var presentationMode
//ユーザーの名前を取得
@AppStorage("myname") var nameAppStorage = ""
var body: some View {
VStack {
Text("スレッドを作成").padding().font(.largeTitle).bold()
TextField("作成したいスレッド名", text: $threadname).textFieldStyle(RoundedBorderTextFieldStyle()).padding()
TextField("スレッドの説明", text: $explain).textFieldStyle(RoundedBorderTextFieldStyle()).padding()
Text("*弊社にて審査し、作成しますので反映まで1〜3日期間をいただきます。").padding()
HStack {
Button(action: {
//画面を閉じる(前の画面に戻る)
self.presentationMode.wrappedValue.dismiss()
}){
Text("戻る").padding()
}
Button(action: {
//非同期関数を呼び出す
Task {
//非同期処理を実行
do{
try await post()
}catch{
print("エラーが発生しました")
}
}
//画面を閉じる(前の画面に戻る)
self.presentationMode.wrappedValue.dismiss()
}){
Text("作成").padding()
}
}
}
}
//Slackとアプリ連携をさせメッセージを送る処理
func post() async throws { //非同期関数内でエラーをスローする
// Webhook URLで取得したURL
let url = URL(string: "https://hooks.slack.com/services/T0XXXXXXXXXXX/jSXXXXXXXXXXXXXXXXXX")!
var request = URLRequest(url: url)
// Postする際は必ずhttpMethodにて"POST"を定義する
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
// Slackに投稿する内容
let payload = Payload(attachments: [Attachment(
authorName: "名前:" + nameAppStorage,
title: "スレッド名:" + threadname,
text: "説明:" + explain)])
let jsonEncoder = JSONEncoder()
// エンコードされるJSONデータ内のプロパティ名(キー)の表記を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.network
}
guard (response as? HTTPURLResponse)?.statusCode == 200 else {
throw APIError.unknown("No Clear")
}
print("success:\(data)")
}
}
struct Payload: Codable {
var attachments: [Attachment]
}
//Codable プロトコルを適用した構造体。JSONデータとのエンコードおよびデコードが可能。
struct Attachment: Codable {
var authorName: String
var title: String
var text: String
var footer = "NowShare app"
}
//エラータイプを定義
enum APIError: Error {
case network
case server(Int) // Int型を引数とする
case unknown(String) // String型を引数とする
}
以上がアプリからSlackへメッセージを投げるソースコードになります。
アプリが止まらないようにエラーハンドリングを実装しているため少し複雑に見えますが、やっていることはそこまで難しくないため、ぜひ活用ください。
エラーハンドリングに関しての記事は後日展開予定
以上になります。
皆様のお役に立てれば幸いです。
コメント