IBM Cloud Object Storage(ICOS)へのアップロードをIBM Cloud FunctionsでSlackに通知してみる

# はじめに

IBM Cloudでは、AWSのS3に相当するオブジェクトストレージ「IBM Cloud Object Storage」(ICOS)、および、Lambdaに相当するFunction as a Serviceプラットフォームとして「IBM Cloud Functions」が提供されています。

当記事では、この2つのサービスを利用し、**「ICOSにファイルがアップロード・削除されたときに、自動でSlackのチャンネルに通知する」**処理を作成してみます。

処理の流れは以下のようになります。
<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/4a6413a3-abff-c50f-04c7-807cc52f2ce7.png">

ICOSにファイルがアップロードされたり、既存のファイルが削除されたりすると、IBM Cloud Functionsに対してトリガーが発行され、それを受けてSlackへの通知処理が起動するというものです。

なお、当記事の作成にあたり、IBM Cloud FunctionsでのSlack通知処理について、以下の記事を参考にしています。

[IBM Cloud Functions からPythonで Slack にメッセージをPostする](https://qiita.com/c_u/items/5399b5bef20158787ca2)


# SlackのIncoming Webhook URLの発行

まず、任意のSlackワークスペースで、通知したいチャンネルに対するIncoming Webhookを発行します。
Webhookの発行方法は以下を参考にしてください。

[Slack での Incoming Webhook の利用](https://slack.com/intl/ja-jp/help/articles/115005265063-Slack-%E3%81%A7%E3%81%AE-Incoming-Webhook-%E3%81%AE%E5%88%A9%E7%94%A8)
[Sending messages using Incoming Webhooks](https://api.slack.com/messaging/webhooks#posting_with_webhooks)


# IBM Cloud Object Storageの作成

IBM Cloudにログイン後、画面上部の「カタログ」をクリックし、「カタログを検索...」フィールドで「Object Storage」と入力し、検索します。
以下の「Object Storage」が出てくるのでこれをクリックします。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/5735f695-d2aa-9eb0-985f-410e194fb876.png">

無料の「ライト」プランを選択し、他はデフォルトのままで「作成」ボタンをクリックします。
<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/b54b310c-d76b-17f4-bfe2-91a8f85087bb.png">

「バケットの作成」をクリックします。
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/79b0e920-4450-6852-b682-591de87716c3.png">

「カスタム・バケット」をクリックします。
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/637061c0-1a51-4e35-a2ae-6ddec9bb1a71.png">

「固有のバケット名」に任意の名前を入力し、「ロケーション」を「jp-tok」とし、他はデフォルトのままで「バケットの作成」をクリックします。
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/13daacdb-d5f8-9870-1dc5-7bc0b8af573e.png">

これでICOSのバケットが作成され、ファイルをアップロードできる状態になりました。


# IBM Cloud Functionsの名前空間の作成

IBM Cloud Functionsのトリガー・アクションを作成する前に、それらを含める名前空間を作成します。

[IBM Cloud Functionsのページ](https://cloud.ibm.com/functions/)にアクセスします。

「現在の名前空間」欄を展開し、「名前空間の作成」をクリックします。
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/52e9fef5-eae8-c330-916c-9f29faaef257.png">


「名前」に任意の名前、「デプロイするロケーションの選択」で「東京」を選択し、「作成」ボタンをクリックします。ICOSのバケットと、Cloud Functionsの名前空間は同じリージョンである必要があります。
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/d4757995-11c5-3fcc-2913-14de32ee12ec.png">



# Cloud Functionsの名前空間への通知マネージャロールの割り当て

ICOSからトリガーを発行するにあたり、Cloud Functionsの名前空間に権限を付与する必要があります。
[IAMダッシュボード](https://cloud.ibm.com/iam/authorizations/grant)にアクセスします。

サービス許可の付与画面で、以下のように入力し、「許可」ボタンをクリックします。

- ソース・サービス：Functions
- ソース・サービス・インスタンス：上記で作成したFunctionsの名前空間
- ターゲット・サービス：Cloud Object Storage
- サービス・インスタンス：上記で作成したCloud Object Storageのインスタンス
- サービス・アクセス：「Notification Manager」にチェックを入れる
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/5977f6e2-3bb5-fd63-91dd-15a21c31104f.png">


# Cloud Functionsのトリガー・アクションの作成

Cloud Functionsの[トリガーのページ](https://cloud.ibm.com/functions/triggers)にアクセスします。

「現在の名前空間」が上記で作成した名前空間であることを確認し、「作成」ボタンをクリックします。
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/a0424097-21d0-14e4-4a0c-7b8c08d7550f.png">

「トリガー」をクリックします。
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/e07659cf-3bb3-1071-0a10-647fb63a2ee5.png">

「Cloud Object Storage」をクリックします。
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/9df70743-539b-c72f-59e6-60a3cd1e625f.png">

「トリガー名」に任意の名前を入力し、「COSサービス・インスタンス」「バケット」で上記で作成したICOSインスタンス、バケットを選択し、「作成」ボタンをクリックします。
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/dba60ff3-a501-c7bd-2933-3047f672ec1b.png">


トリガーが作成できたので、次は、トリガー発生により実行されるアクションを作成します。

「接続されたアクション」の右側にある「追加」をクリックします。
<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/799a4048-59e2-7ff2-3eb6-ad792f68952d.png">

「アクション名」に任意の名前を入力し、「ランタイム」で「Python 3.7」を選択し、「作成&追加」ボタンをクリックします。
<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/24c30c8f-792c-2e05-4e27-88ea8fe9f3af.png">

作成されたアクション(以下では「cos-update-slack-notify」)をクリックします。
<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/bb9a7280-09df-5900-18c9-3538c09b3b25.png">

アクションのコードが表示されるので、以下の内容に置き換えて、「保存」ボタンをクリックします。
urlの部分は、上記で取得したSlackのIncoming WebhookのURLに変更します。

```python
import requests
import json

def main(dict):

 body={'username':'ICOS','icon_emoji':':donut:','text': "バケット=" + dict["bucket"] + ", ファイル=" + dict["key"] + ", 操作=" + dict["operation"]}

 url = "https://hooks.slack.com/services/xxxxxxxxxxxxxx" # 取得済みのSlack Incoming WebhookのURLに置き換える
 response = requests.post(url,data=json.dumps(body))
 return { "message" : "Slack notified" }
```

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/90e76207-948d-1c4e-2805-bd21e2937b49.png">



# ファイルアップロードとSlack通知の確認

作成したICOSのバケットにファイルをアップロードし、Slackチャンネルに通知されることを確認します。

[リソース・リストのページ](https://cloud.ibm.com/resources)にアクセスします。

「Storage」以下に作成したObject Storageのインスタンスが表示されるのでクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/a1f75a80-7fc7-6a7c-9d8b-ec61dd4ac562.png)

作成したバケットをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/eb99cf50-90fe-2dd2-39d3-814abb803a55.png)

「アップロードするにはファイルまたはフォルダーをドラッグ・アンド・ドロップします」の箇所をクリックし、任意のファイルをアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/b018a786-1a81-cd08-eb51-21e9792dc2ac.png)

ファイルアップロードをトリガーとして、対象のSlackチャンネルに以下のようなメッセージが投稿されます。
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/f22bd5fb-5012-02ac-8099-bd41183958dd.png">


以上、ICOSへのアップロードなどの通知をSlackに通知する方法でした。

---
なお、IBM Cloud Functionsの[マニュアル](https://cloud.ibm.com/docs/openwhisk?topic=openwhisk-pkg_obstorage&locale=en#pkg_cos_limits)では、
> Triggers created with /whisk.system/cos package have the following limitations.
> - The trigger is available in the us-east, us-south, and eu-gb regions.

のように、jp-tokはトリガーの利用可能リージョンになっていませんが、2020年8月10日時点では上記のようにjp-tokでも利用できています。

以下のように、/whisk.system/cos パッケージも含まれているようです（sample-ns-3はjp-tokの名前空間）。

```
❯ ibmcloud fn namespace target sample-ns-3
ok: whisk namespace set to sample-ns-3

~
❯ ibmcloud fn package list /whisk.system
packages
/whisk.system/samples                                                  shared
/whisk.system/websocket                                                shared
/whisk.system/slack                                                    shared
/whisk.system/weather                                                  shared
/whisk.system/utils                                                    shared
/whisk.system/cloudant                                                 shared
/whisk.system/cos                                                      shared
/whisk.system/messaging                                                shared
/whisk.system/alarms                                                   shared
```