Stripe Appsから外部のAPIやフィードを呼び出す方法とその設定方法



この記事は、[Stripe Apps を25日間紹介し続ける Advent Calendar 2022](https://qiita.com/advent-calendar/2022/stripe-apps) 16日目の記事です。

![スクリーンショット 2022-11-24 17.56.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/e0261865-0418-daa2-423a-5f4d70558b1b.png)

Stripeアプリを開発する上で、**Stripe以外のAPIが必要となる**ことは少なくありません。

この記事では、Stripe Appsアプリで外部のAPIを呼び出すための設定・実装方法を紹介します。

## 外部のAPIを呼び出すための設定

Stripe Appsのアプリは、Stripeが用意するサンドボックス内で動作します。

![extensions-structure.d6d4d0512ef2194eda5c7ffd214e894e.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/3d919c65-fa61-5862-cdc5-802c755628a0.jpeg)

そのため、アプリから外部のAPIを呼び出すには、Stripe CLIを利用して`stripe-apps.json`に設定する必要があります。

### Stripe CLIで呼び出すURLを登録する

今回は、Public API for Public APIsを利用してPublic APIの一覧を取得してみましょう。

https://api.publicapis.org/

Stripe CLIで次のコマンドを実行します。

```bash
$ stripe apps grant url "https://api.publicapis.org/" "Load public API data"
✔ Granted url https://api.publicapis.org/
```

`stripe-app.json`を見ると、`content-src`にURLが登録されていることが確認できます。

```diff_json
{
  "id": "com.example.first-stripe-app",
  "version": "0.0.1",
  "name": "First Stripe App",
  "ui_extension": {
...
    "content_security_policy": {
+      "connect-src": [
+        "https://api.publicapis.org/"
+      ],
      "image-src": null,
+      "purpose": "Load public API data"
    }
  },
  "post_install_action": null
...
```

### 登録できるURLのタイプについて

登録できるURLの種類は、2022/12時点では次のとおりです。

- 安全な HTTPS プロトコル (例: https://www.example.com/api/users/) を使用します。
- パスを含みます (例: https://www.example.com/api/users/ URL は有効ですが、https://www.example.com/ は無効です)。ベースパスの末尾にスラッシュを追加することにより、その後のあらゆるパスがカバーされます (例: https://www.example.com/api/ により、 https://www.example.com/api/users/abc123/address へのコールが可能になります)。
- Stripe APIは指定できません
- ワイルドカード ( * ) を使用する場合は、DNS ラベルの一番左で使用する必要があります (例: https://*.example.com/api/users/)。

https://stripe.com/docs/stripe-apps/build-ui#use-third-party-apis

Backlogやkintoneなど、ユーザーやプロジェクトごとにサブドメインが変わるサービスのAPIでは、ワイルドカードを利用しましょう。

### 登録解除の方法

登録の解除もStripe CLIから行えます。

```bash
$ stripe apps revoke connect-src https://api.publicapis.org/
```

もしコマンドで指定したURLが`connect-src`に存在しない場合、対話形式で選択できます。

```bash
? Unable to find connect-src https://qiita.com/hideokamot. Select a connect-src to revoke: 
  ▸ https://qiita.com/hideokamoto/feed.atom
    https://api.publicapis.org/
```

### アプリの再有効化で設定を反映する

`stripe-app.json`を変更しますので、アプリのプレビューを再度有効化する必要があります。

![スクリーンショット 2022-12-12 18.33.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/7b211049-f662-9d4c-2d03-cf779fd0688a.png)

有効化が漏れている場合、設定が反映されませんのでご注意ください。

## Stripe Appsから、外部のAPIを呼び出す

アクセス権の設定が完了すれば、あとは設定したURLへのリクエストをアプリから送信するだけです。

```tsx
import { ContextView, List, ListItem } from "@stripe/ui-extension-sdk/ui"
import BrandIcon from "./brand_icon.svg"
import { useEffect, useState} from 'react'

type PublicAPI = {
  API: string
  Auth: string
  Category: string
  Cors: string
  Description: string
  HTTPS: boolean
  Link: string
}


const App = () => {
  const [items, setItems] = useState<Array<PublicAPI>>([])

  useEffect(() => {
    fetch("https://api.publicapis.org/entries")
      .then(data => data.json())
      .then(data => {
        setItems(data.entries)
      })
      .catch(console.log)
  }, [])
  return (
    <ContextView
      title="Hello World"
      brandColor="#F6F8FA" // replace this with your brand color
      brandIcon={BrandIcon} // replace this with your brand icon
    >
      <List>
        {items.map((item, i) => {
          return (
            <ListItem
              title={`#${i}: ${item.API}`}
              key={i}
            />
          )
        })}
      </List>
    </ContextView>
  )
}

export default App
```

権限設定に成功していれば、次のようにAPIのリストが表示されます。

![スクリーンショット 2022-12-12 18.49.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/6e7ce170-7dcf-0e47-c998-2f9465e75030.png)

## テストアカウントのローカル環境プレビューモードで、localhostのAPIを呼び出す方法

APIも並行して開発している場合、テストアカウントのローカル環境プレビューモードではlocalhostへのアクセスに設定したくなります。

その場合は、`stripe-app.json`を拡張させましょう。

https://stripe.com/docs/stripe-apps/reference/app-manifest#extended-manifest

`stripe-app.local.json`を作成し、次のように設定します。

```json
{
  "extends": "stripe-app.json",
  "ui_extension": {
    "content_security_policy": {
      "connect-src": ["http://localhost:3000/api/"]
    }
  },
  "constants": {
    "API_BASE": "http://localhost:3000/api"
  }
}
```

`stripe-app.json`にも`constants`を追加しましょう。

```diff_json

    "actions": [],
    "content_security_policy": {
      "connect-src": [
        "https://api.publicapis.org/"
      ],
      "image-src": null,
      "purpose": "Load api data"
    }
  },
  "post_install_action": null,
+  "constants": {
+    "API_BASE": "https://api.publicapis.org"
+  }
}
```

続いて`src/view/App.tsx`のAPI呼び出し箇所を次のように変更しましょう。

```diff_typescript
import { useEffect, useState } from 'react'
+import { ExtensionContextValue } from "@stripe/ui-extension-sdk/context"


...


-const App = () => {
+const App = ({environment}: ExtensionContextValue) => {
  const [items, setItems] = useState<Array<PublicAPI>>([])

  useEffect(() => {
  useEffect(() => {
-    fetch("https://api.publicapis.org/entries")
+    fetch(`${environment?.constants.API_BASE}/entries`)
      .then(data => data.json())
      .then(data => {
        setItems(data.entries)
      })
      .catch(console.log)
  }, [])
```

### マニフェストファイルを指定して、起動する

Stripe CLIで、ローカル環境用のマニフェストファイルを指定して、アプリを起動させましょう。

```bash
$ stripe ap start --manifest ./stripe-app.local.json 
[18:58:04] ERROR ./stripe-app.local.json
found violations for connect-src "http://localhost:3100/api/": protocol has to be https, publicsuffix: cannot derive eTLD+1 for domain "localhost"
[18:58:04] compiled successfully
💻 Running development server on http://localhost:4242 (^C to quit)
✨ You can now preview First Stripe App in your Stripe account.
```

エラーメッセージが表示されますが、アプリ自体は起動します。

あくまでローカル環境でのプレビュー用途ですので、`stripe-app.json`そのものには`localhost`を設定しないようにしましょう。

## Stripe Appsひとりアドベントカレンダー 2022

今年ベータリリースされたばかりのStripe Appsは、まだ日本語の情報が多くありません。

そこでQiita Advent Calendar 2022にて、毎日Stripe Appsについての情報を投稿します。

https://qiita.com/advent-calendar/2022/stripe-apps

ノーコードで利用する方法や、開発するためのTipsなども紹介予定ですので、ぜひ購読をお願いします。