Claris ConnectでEコマースの在庫連携システムを作成する

# はじめに

この記事は、Qiita Engineer Festa 2022 「**[Claris Connect を使った SaaS 連携ユースケースを紹介しよう！](https://qiita.com/official-events/eeadea1de45a11be944e)**」に参加するために作成した記事です。

在庫連携システムを作成しますが、
実運用に使用できるほど仕様を考えていないので軽い気持ちで見ていただけると幸いです
また、Claris ConnectのIDや本記事で使用する各種サービスの登録方法は省略させて頂きます

# 概要

今回は複数のECを運用する事で必要になる「在庫連携システム」をClaris Connectを使って構築します
実際に運用する事をイメージして複数システムのデータ連携からSlack・Trelloのサービス連携まで行います

# 在庫連携システムとは

実装に移る前に在庫連携システムについて説明します

まずこちらが在庫連携を使用せずに複数のECサイトを運用している図になります
商品在庫を同期していないのでそれぞれのECサイトに在庫を振り分けて出品していますが、
一部のサイトでは品切れが発生してしまっています
![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/f3f8452a-74a9-f6bb-e9b2-af11e4af998f.jpeg)

そしてこちらが在庫連携を使用した場合の図になります
在庫連携でECサイト毎の商品在庫を同期させる事で、
品切れによる機会損失を防ぐ事でより多くの人に商品を売る事ができるメリットがあります
![Untitled Diagram (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/62a84b3e-368b-d39c-7fb1-b0d98d543b46.jpeg)

---

# 構成

![Untitled Diagram (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/2342cd54-7fc9-f81b-bc15-4295c6558acd.jpeg)

## ECサイト

本当であれば実際のECモールを使って連携ができる事を実証したいのですが、
楽天市場などの連携APIを使うには有料アカウントの作成や審査を通さないといけない為、
今回は僕の作成した擬似ECサイトを複数環境使って検証します

- ショップA
    3001portで起動しているlocalアプリ
    ※実際の場合は楽天市場などのECとなります
- ショップB
    3002portで起動しているlocalアプリ
    ※実際の場合は楽天市場などのECとなります
- ショップC
    3003portで起動しているlocalアプリ
    ※実際の場合は楽天市場などのECとなります

localで環境別のアプリを3つ立ち上げるアプリを作ってあるのでこちらを使用します
（ECアプリというにはあまりにも雑ですが、検証に必要な最低限の機能をつけてあります）

https://github.com/git-gen/multi-env-app

## 運用サービス

- Slack
    運用で商品受注が発生した際の通知の受け取り先にします    
- Trello
    運用での作業タスクを管理させます

---

# 実装

ショップAで商品が購入されたら、
その在庫減少分をショップB・Cに反映するというシステムを作成します
なので、在庫の追加などは今回の実装や検証では行いません

## ECアプリを準備

構成で記述したように自前のwebアプリを使います
このアプリには在庫連携用に最低限以下の機能が実装されています
（受注による在庫減少のみ）

- 運用画面
    - /items - 商品の管理画面
    - /orders - 受注の管理画面
    - /shopping - 商品の購入画面
- 連携用API
    - GET /api/item_stock.json - 商品詳細取得API
    - GET /api/search_order.json - 受注情報検索API
    - POST /api/item_stock.json - 商品在庫更新API

使われるDBテーブルのリレーションは以下のようになっており、
商品を注文するとordersと一緒に購入した商品の情報をもったorder_itemsが作られます

```mermaid
erDiagram

items {
  integer id
  string title
  string sku
  integer price
  integer stock
  boolean enabled
}
orders {
  integer id
}
order_items {
  integer id
  integer order_id
  string title
  string sku
  integer price
  integer count
}

orders ||--|{ order_items: ""
```

https://github.com/git-gen/multi-env-app

### 1. セットアップ
まず初めにdockerでアプリとDBを準備します
docker-composeでwebアプリ（ruby on rails）を3環境と合わせてDB（postgresql）が3環境で、
計6つのコンテナができるようになっています
```bash
# docker-composeを使って一括管理してあります
$ docker-compose build

# 各dbにテーブルを追加します
$ docker-compose run -e DB_HOST=db1 app1 rails db:migrate
$ docker-compose run -e DB_HOST=db2 app2 rails db:migrate
$ docker-compose run -e DB_HOST=db3 app3 rails db:migrate

# webアプリが3つ、postgresqlのコンテナが3つずつ立ち上がります
$ docker-compose up -d
```

![スクリーンショット 2022-07-09 9.39.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/a769ed2c-888e-67de-5f43-15ec5c8ebc60.png)

各webアプリも参照できる事を確認できます

http://localhost:3001

http://localhost:3002

http://localhost:3003


### 2. 各アプリに商品データを用意する

3環境毎のDBに商品データを登録します
商品の管理画面（/items/new）
![スクリーンショット 2022-07-09 9.47.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/5a0b0e75-9ffe-f24f-1b20-46791ca9c2de.png)

数パターンで検証ができる様に3環境に3つずつ商品を登録しました
![スクリーンショット 2022-07-09 9.54.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/af3fe246-6488-1cc5-8ed4-913bda1407da.png)

あとは商品の購入画面（/shopping）から商品の購入数を入力するだけで購入処理が行えます
これでECアプリの準備は完了となります
![スクリーンショット 2022-07-09 9.57.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/944b26d6-c96a-e5dd-5143-f77869a60ee6.png)

### 3. ngrokを準備する

localで稼働しているwebアプリにClaris Connectからリクエストを送れるようにします
ngrokを使えば簡単にlocalでのwebアプリを外部へ公開できるので検証などに便利です
※ngrokは無料で使用可能です・導入方法は省略します

ngrokを使って以下のポートを外部公開へします
ngrokにログインしてしまっていると1セッションしか使用できないので、今回はログインせずに使用しています（この場合は制限時間あるので注意）
```bash
$ ngrok http 3001
# Session Expires               1 hour, 59 minutes
# Terms of Service              https://ngrok.com/tos
# Version                       3.0.6
# Region                        Japan (jp)
# Latency                       13ms
# Web Interface                 http://127.0.0.1:4040
# Forwarding                    https://389c-126-51-231-69.jp.ngrok.io -> http://lo
$ ngrok http 3002
$ ngrok http 3003
```

## Claris Connectで全てのアプリを連携

### フローの作成

Claris Connectでアプリの連携をしていきます
初めに新規プロジェクトを作成してCreate New Flowを選択します
![スクリーンショット 2022-07-07 9.01.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/a712a693-2da2-1d28-c433-fb63e582d2b7.png)
![スクリーンショット 2022-07-07 9.01.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/03832ebd-9fdb-dc34-d2f8-3ec901e60665.png)

### 受注情報取得

今回は各ショップの受注状態を定期的に参照しにいくポーリングを使って連携させます
なので、Claris Connectの処理実行のトリガーは短期間のバッチ方式で実行させます

連携用のサービス一覧から「Schedules」を選択して、
実行タイミングをcronで5分に1回というように設定します
![スクリーンショット 2022-07-09 10.18.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/c9509255-f836-74b3-8d8f-39659cbdaeaf.png)
![スクリーンショット 2022-07-09 10.30.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/cfba6d5d-ea49-f7ad-58ce-492d9d1d51cf.png)

トリガーができたので、
次に受注情報検索APIを実行して最新の受注情報を取得するところを作成します

作成したSchedulesにActionを追加して、
「Webhooks」のHTTP GET requestを選択します
![スクリーンショット 2022-07-09 10.32.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/33a601bf-5f77-57c3-7c58-2f4ae123e1ad.png)
![スクリーンショット 2022-07-09 10.34.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/8ef4c00d-793b-489b-d165-a2ade0ee87f3.png)

受注情報検索APIのURLを設定します
![スクリーンショット 2022-07-10 10.56.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/4aab1962-5422-84cd-b839-1d73b475cb64.png)

今回のアプリでは5分前までに作られた受注情報を取得していますが、
Claris Connect側で前回実行したバッチ時間などをパラメータに渡せるのでしっかりやる場合はこっちの方が良いと思います
```ruby
def show
  now = Time.current
  @orders = Order
    .where(created_at: now.ago(5.minutes)...now)
    .order(created_at: :desc)

  respond_to do |format|
    format.json
  end
end
```
![スクリーンショット 2022-07-10 10.56.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/00add85f-3f2e-8ba1-2f46-b866e6b83eb1.png)

試しに受注でデータを作成してClaris ConnectからAPIを実行してみます
右上の「Review and Test」でレビュー画面に切り替わるので、そこからテストする事ができます
![スクリーンショット 2022-07-10 11.05.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/6deae608-91b0-f33c-9a88-21efa829f6e9.png)

### 他ショップへの在庫反映

次に受注情報検索APIを実行して受注が存在した場合の処理を作ります
GET　requestから「If」アクションを増やして条件を受注情報検索APIのordersレスポンスがあった場合とします
作成したIfから「Repeat」を追加して繰り返し処理を設定する事ができます
![スクリーンショット 2022-07-10 11.09.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/78037d07-4f78-1c74-2494-25173fbda713.png)
![スクリーンショット 2022-07-10 14.35.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/b7c02245-e287-0bc8-edde-4b799a9345dc.png)

購入された商品分だけ実行される処理を作ります
商品詳細取得APIで最新の在庫状態を取得して、商品在庫更新APIで他のショップに反映しています
![スクリーンショット 2022-07-10 14.34.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/2dded556-8e96-2f3f-3763-07fef693d7c3.png)

POST requestの方はパラメータをJSONで渡します
![スクリーンショット 2022-07-10 14.45.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/8de0b871-b266-b97c-598c-31c4971daff8.png)

POST requestを他ショップ分だけ作成しました
![スクリーンショット 2022-07-10 14.50.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/648e4233-5728-3b59-7476-0e967dd4b87b.png)

### Slack・Trelloの連携

通知用にSlackへの連携を行います
以下の用に簡単に連携する事ができて、もちろんAPIのレスポンスをメッセージに使う事ができます
![スクリーンショット 2022-07-10 14.54.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/556ec3d4-577d-6f95-c663-dc85d7d4bdd3.png)
![スクリーンショット 2022-07-10 14.59.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/0cfa3f58-e74d-6387-4361-f67daea9ffc8.png)

Slackと同じ用にTrelloへのカード追加連携も簡単に行う事ができました
![スクリーンショット 2022-07-10 14.57.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/f9c2fab8-043d-84cf-05b6-df4491f63370.png)
![スクリーンショット 2022-07-10 14.59.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/2cd15d81-ec6d-7a15-8707-dbc0e8528170.png)

### フローの複製

最後にフローを複製しAPIのドメインと通知周りの文言を差し替えて、
ショップB・C用のバッチも作成しました
![スクリーンショット 2022-07-10 15.05.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/5e4b2b2e-da26-72a3-0acc-ef71ddda9047.png)

### 完成

Claris Connectの操作はほとんど直感的に行えるので、
説明するようなところがなくスクリーンショットばかりの説明になりましたが、
これで完成となります！
![スクリーンショット 2022-07-10 14.58.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/4af5348e-4bb9-4a67-756e-28267fdfb5a9.png)

renameするとこんな感じです！
![スクリーンショット 2022-07-10 15.03.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/76699d37-91de-4415-47a0-de23cb59ef22.png)

---

# 検証

完成した在庫連携システムを実際に使ってみます
※APIの設計が雑で同時購入されると注文片方の在庫減少が同期で上書きされてしまう為、
　購入処理ごとにフロー手動実行で検証しています

ショップBの商品の購入画面（/shopping）から商品を購入
![スクリーンショット 2022-07-10 15.12.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/81af21ca-b8b1-8bfd-eea3-80e87f569ab9.png)

ショップCの商品の購入画面（/shopping）から商品を購入
![スクリーンショット 2022-07-10 15.14.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/d26168e0-e318-8ded-fca4-3eed43d4938c.png)

Slack・Trelloへの連携が行われ、
ショップA・B・Cの在庫が全て同期されている事が確認できました
![スクリーンショット 2022-07-10 15.16.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/3c8a8c49-ce86-51ac-a1b5-be6ebd899d81.png)
![スクリーンショット 2022-07-10 15.19.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/53eaa674-f9d1-0713-cc11-d40a2f9f4f6f.png)

DBクライアントから確認しても、
在庫連携できている事が確認できました
![スクリーンショット 2022-07-10 15.17.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/95802ed8-7d0d-d7b3-97e5-bd3b6e5918b9.png)

---

# 終わりに

今回初めてClaris Connectを触りましたが、
ほとんど調べる事なく扱う事ができてとても便利でした！

デバッグに関しても実行履歴でどのフローでどんなレスポンスがあったかも、
細かく見る事ができるのでほぼ悩む事もありませんでした！
![スクリーンショット 2022-07-10 15.06.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478226/b27de07c-6aae-2e55-4185-da6a9e812393.png)

また、連携できるアプリも多数存在するので、
色々な事に運用する事ができると思います！