🏞️

[Part 6] Canva APIを使ったアプリ作成 事始め

2022/11/04に公開約5,900字

Part 5はこちら👇です。
https://zenn.dev/aninomiya/articles/efb055fda7d8cb

他サービスとの連携 (Fetch)

この記事では、新Canva APIの5種類の機能のうち、「他サービスとの連携 (Fetch)」について、サンプルを使って詳細をみていきたいと思います。

  • 他サービスの認証 (Authentication)
  • 一括作成用のデータ作成 (Data Provider)
  • 要素の追加・更新 (Design Interaction)
  • ドラッグ & ドロップ (Drag & Drop)
  • 👉他サービスとの連携 (Fetch)

Canva API ドキュメント

サンプルアプリ

Canvaのスターターキットの他サービス連携に関するサンプルアプリは、下記の3つです。

  • get_image
  • fetch_post
  • polling

サンプルアプリ1

まずは、他サービスから画像を取得するサンプルアプリをみてみたいと思います。

下記のコマンドを実行します。

npm start get_image

Canvaを開くと下記のような画面が表示されます。

そして、「Fetch and add image」をクリックすると、https://picsum.photos/200/200.jpg から画像を取得し、ネイティブ要素として画像を追加します。

リバースプロキシ

上記の例で画像を取得した https://picsum.photos というサイトは、どんなオリジンからもアクセスできるようになっているので(Access-Control-Allow-Origin: *)、ブラウザから画像を取得して表示することができましたが、CORSの設定がより厳しい画像ストレージの場合、ブラウザから直接画像を取得することはできません。

そのような場合は、リバースプロキシを建てて、そこを経由することでブラウザからも画像を取得することができます。

このサンプルアプリでは、リバースプロキシを建てる方法も、少し設定を変えるだけでできるようになっているので、そちらも試してみたいと思います。

まずは、/examples/get_image/App.tsxを下記のように書き換えます。

- const HTTPS_BACKEND_URL = 'enter-your-https-backend-route-here';
+ const HTTPS_BACKEND_URL = 'https://random-subdomain-name.ngrok.io';
-     const image = await getImageFromUrl({
-       type: ImageType.JPEG,
-       url: IMAGE_URL, // const IMAGE_URL = "https://picsum.photos/200/200.jpg";
-     });

+     const image = await getImageFromUrl({
+       type: ImageType.JPEG,
+       url: PROXIED_IMAGE_URL, // const PROXIED_IMAGE_URL = `${HTTPS_BACKEND_URL}/image?url=${IMAGE_URL}`;
+     });

続いて、下記のコマンドを実行して、サンプルアプリとバックエンドを起動します。

npm start get_image --ngrok

※ngrokの設定は、Part 5をご確認ください。

続いて、Canva Developer Portalにてアプリの設定を行います。「Base URL」という項目にngrokで発行されたURLを、「Endpoint allowlist」という項目にこのサンプルアプリの/backend/server.jsで定義されているエンドポイントを追加します。

※もし「Add authentication」のタブで「This app requires authentication」の項目が有効になっていたら無効に戻します。

ngrok無料バージョンの罠

これで万事OKと思いきや、このままアプリを開いて、「Fetch and add image」をクリックしても、「Something went wrong」になり、画像が取得できません。

ブラウザのログには、下記のエラーが表示されます。

Access to image at 'https://random-subdomain-name.ngrok.io/image?url=https://picsum.photos/200/200.jpg' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

これは、ngrokの無料バージョンだと、ローカルで動いているバックエンドにリクエストが到達する前に、下記のような確認画面が返され、そのレスポンスヘッダには、Access-Control-Allow-Originが設定されていないためです。

ngrokを有料プランにすれば、この画面を表示しないようにできるそうですが、今回は、上記画面にも記載がある通り、ブラウザからバックエンドにリクエストを送る際にngrok-skip-browser-warningヘッダーを付与する方法で回避したいと思います。

リクエストヘッダを設定するため、サンプルアプリのコードを書き変えることもできますが、今回はただサンプルアプリを動かしたいだけなので、ModHeaderというChromeの拡張機能で対応することにしました。

この設定を行うことで、Chromeから送られるリクエストに上記のヘッダがセットされます。

再度、アプリを開いて、「Fetch and add image」をクリックすると、無事、リバースプロキシとして動作しているバックエンドサーバ経由で画像を取得し、ブラウザで表示することができました。

サンプルアプリ2

続いて、アプリからバックエンドにPOSTリクエストを送り、JSONデータを取得するサンプルアプリをみてみたいと思います。

下記のコマンドを実行します。

npm start fetch_post --ngrok

次に、アプリの設定を変更します。

これでCanvaを開くと、下記のような画面が表示されます。

「Send POST request」をクリックすると、バックエンドにPOSTリクエストを送り、返ってきたJSONデータがアプリに表示されます。

GETだけではなく、POSTリクエストを送ることが確認できました。

サンプルアプリ3

続いて、非同期処理のサンプルアプリをみてみたいと思います。

Canvaの他サービス連携では、タイムアウトが3秒に設定されています。ただ、重い処理を行う場合は、レスポンスが返ってくるまで3秒以上かかってしまうかもしれません。そのようなケースで使えるのが非同期処理です。

サンプルアプリでは下記のような実装になっています。

  • バックエンドに処理の受付用と確認用の2つのエンドポイントを用意する
  • 最初にアプリから受付用のエンドポイントにリクエストを送り、トークンを取得する
  • アプリから定期的に確認用のエンドポイントにリクエストを送る (繰り返し)
  • 処理が完了していたら、処理の結果を受け取り、それ以降リクエストは送らない

このように実装することで、3秒以上かかるような処理の結果も取得できます。

それでは、実際にサンプルアプリを動かしてみます。

npm start polling --ngrok

次に、アプリの設定を変更します。

これでCanvaを開くと、下記のような画面が表示されます。

「Start long-running task」をクリックすると、ボタンの文字がスピナーに変更します。

ブラウザのコンソールを確認すると、3秒おきにリクエストを送り、4回目の確認で結果を取得できていることがわかります。

The polling has started.
Request #1 sent at Sat Nov 05 2022 23:10:31 GMT+0900 (日本標準時)
The polling is ongoing.
Request #2 sent at Sat Nov 05 2022 23:10:35 GMT+0900 (日本標準時)
The polling is ongoing.
Request #3 sent at Sat Nov 05 2022 23:10:39 GMT+0900 (日本標準時)
The polling is ongoing.
Request #4 sent at Sat Nov 05 2022 23:10:43 GMT+0900 (日本標準時)
The long-running task is done!
Here is the result: 
  Object
    message: "The long-running task is complete!"

画面を確認すると、ボタンの文字がスピナーも終了しています。

他サービス連携の利用用途

他サービスと連携ができると、アプリでできることの幅が広がります。ただ、返ってきた結果の使い道は、要素の追加 (Part 2)と、一括作成用のデータ作成 (Part 4)に限られます。

つまり、Canva上で画像や動画をよりデザインしやすくするためにしか、連携機能は使えないようになっています。完成したデザインを他サービスに送るようなことはできません。

Canva以外のサービスの利便性を高めるというよりは、Canva自体の利便性を高めるために、連携機能は用意されているようです。

具体的な利用用途としては、画像等のデータを他サービスから取得し要素を追加する、重い処理を他サービスで行う、等になるかと思います。

まとめ

他サービス連携について、サンプルアプリを動かしてみました。これにて、Canva APIの各機能とサンプルアプリの確認は終わりです。次以降の記事では、実際にアプリをつくってみたいと思います。

Discussion

ログインするとコメントできます