Square API/Webhook のリアルタイム性の検証

# 背景 

Square Webhook がどれぐらいリアルタイムに通知が届くのか検証した内容をご紹介します。

# 検証内容

**在庫増減をリアルタイム検知可能か検証する手順**

1. ローカル環境へ Web server 用意 （ngrok）
1. Square Webhook endpoint 用意 
1. ngrok URL を API Test App へ登録
1. 在庫数を減らして Webhook endpoint に通知までに掛かる時間を計測する

- 🔗 在庫数更新の Webhook : https://developer.squareup.com/reference/square/inventory-api/webhooks/inventory.count.updated

# 検証内容・結果 - 在庫増減をリアルタイム検知可能か？

**結論: 400ms ぐらいで Webhook Endpoint へ通知が届く**

## 前提条件

[Square API と Sandbox Seller Dashboard の開発環境を手に入れる \- Qiita](https://qiita.com/codenote_net/items/a0022303b9270893a4bb) を行なっている前提とします。

## 検証用コード Express (Node.js)

`npx express-generator` した Express (Node.js) のコードを以下のように手を加えたものを検証環境として利用しました。

```js:app.js
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');

const indexRouter = require('./routes/index');
const squareWebhooksRouter = require('./routes/square/webhooks');

const app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());

app.use('/', indexRouter);
app.use('/square/webhooks', squareWebhooksRouter);

module.exports = app;
```

```js:routes/square/webhooks.js
const express = require('express');
const router = express.Router();

// POST Square Webhooks
// ex. https://developer.squareup.com/reference/square/inventory-api/webhooks/inventory.count.updated
router.post('/', function(req, res) {
  console.log({ now: new Date()});
  console.log(req.body);
  res.sendStatus(200);
});

module.exports = router;
```

## 事前準備 - Web app/server 起動

```shell
npm start
```

```shell
ngrok http 3000
```

### Webhook Endpoint 設定

Square Application の Webhook Endpoint へ https://8912fc93c51f.ngrok.io/square/webhooks を設定します。

ngrok の URL は適宜変更してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4798/2350226a-f342-e9d9-51a7-9bcbe4a3d2df.png)

### 在庫数を減らす

事前にサンドボックス環境に登録していた商品の在庫数を減らします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4798/b5057522-7c62-59f9-2c4e-bff92ede06f5.png)


### POST /square/webhooks の確認

在庫を減らして、Webhook endpoint に通知までに掛かる時間を計測した。

- 在庫数更新の Webhook : https://developer.squareup.com/reference/square/inventory-api/webhooks/inventory.count.updated

```sh
{ now: 2020-09-04T05:18:56.929Z }
{
  merchant_id: 'MLCDWRWZMHH7G',
  type: 'catalog.version.updated',
  event_id: 'eb96e735-c0b0-45cc-950f-118ea734b340',
  created_at: '2020-09-04T05:18:56.560360478Z',
  data: {
    type: 'catalog',
    id: '4a05fe6c-e749-4ee2-a92b-7cc58fc35e62',
    object: { catalog_version: [Object] }
  }
}
POST /square/webhooks 200 1.028 ms - 2

{ now: 2020-09-04T05:18:58.027Z }
{
  merchant_id: 'MLCDWRWZMHH7G',
  type: 'inventory.count.updated',
  event_id: '8703a1c9-ca27-4895-8561-69c49c5ed525',
  created_at: '2020-09-04T05:18:56.097165426Z',
  data: {
    type: 'inventory',
    id: 'a6a81716-8e11-47ff-aa10-7cf77512557e',
    object: { inventory_counts: [Array] }
  }
}
POST /square/webhooks 200 0.981 ms - 2
```

### 結論: 369ms なのでほぼリアルタイム？

```js
> new Date('2020-09-04T05:18:56.929Z') - new Date('2020-09-04T05:18:56.560360478Z')
369
```

500ms 以内に Webhook の通知が届きました。

よって、Square POS の更新をリアルタイムに検知して、EC 側へ反映できることは技術的に実現可能ということが分かりました。

以上、Square を上手く活用していきたい、現場からお送りしました。