Cloudinary UIをアプリケーションに簡単に組み込める「ウィジェット」について解説してみた

2024.02.20

どうも、ベルリンオフィスの小西です。

最近、画像配信・変換のSaaSであるCloudinaryをお仕事でよく使っています。

コンソールやAPIを通じて画像のアップロードできるCloudinaryですが、プロジェクトの要件で 外部アプリケーションから画像を管理する 機能が必要になりました。

その際 Cloudinaryのウィジェット機能 を使い、外部アプリケーション上で直感的な画像アップロードUIを比較的楽に構築できたので、本日はその概要、使い方について紹介します。

Cloudinaryのウィジェットとは?

Cloudinaryのウィジェットは、Webアプリ上でのメディアのアップロードや管理を実現する、JavaScriptツールです。

ウィジェットはモーダルウインドウの形でアプリケーションに統合され、スタイル適用済みのUIとJavascriptメソッドを通じてCloudinaryの各種機能を利用できます。

ウィジェットは単一の機能ではなく、用途に合わせて複数のタイプがあります。

  • Upload Widget … 画像をアップロードし、返り値として画像のURLを受け取る
  • Media Library Widget … CloudinaryコンソールのCRUD機能を外部アプリ上に呼び出す
  • Product Gallery … 特定の画像をギャラリー式に表示する
  • Media Editor … 特定の画像を編集する

今回は Upload WidgetMedia Library Widget を紹介します。

1. Uploaderウィジェットについて

Uploaderウィジェットは、以下のようなコードを埋め込むだけで、シンプルな画像アップロードUIを構築できます。

<script src="https://widget.cloudinary.com/v2.0/global/all.js" type="text/javascript"></script>

<button id="upload_widget" class="cloudinary-button">Upload Files</button>

<script type="text/javascript">
  document.getElementById('upload_widget').addEventListener('click', function () {
    cloudinary.openUploadWidget(
      {
        cloud_name: 'your_cloud_name',
        upload_preset: 'your_upload_preset', //Unsignedモードである必要があります。
      },
      function (error, result) {
        if (!error && result && result.event === 'success') {
          console.log('Done! Here is the image info: ', result.info);
        }
      }
    );
  }, false);
</script>

この例では、CloudinaryのJavaScriptライブラリを読み込み、[Upload Files] ボタンをクリックした際にUploaderウィジェットが開きます。アップロードする先のプリセットやアップロード完了時のコールバックも指定できます。

Uploder タイプのメリット

  • ウィジェットを使うユーザーごとにアカウントは不要のため、利用ユーザー数に対してCloudinaryアカウント数が追いつかない場合に最適
  • アップロードボタンのカスタマイズや、アップロード時の制限(プリセット、フォルダの制限など)が可能

UploaderウィジェットのOption値

主に使いそうなものだけ挙げてみます。

const option = {

    // 必須
    cloud_name: 'your_cloud_name',
    upload_preset: 'your_upload_preset', 

    // オプション
    folder: 'thumbnail/20240219', // アップロード先のフォルダ指定
    sources: 'local, url, camera', // アップロード時のソース選択方法
    publicId: "public_id", // IDを自分で付与したい場合
    tags: ["dog", "family", "home"], // 画像の分類タグ
    clientAllowedFormats: ["webp", "gif", "video"], // クライアントサイドのバリデーション
    maxFiles: 10, // 許容する最大画像数
    maxFileSize: 5000 // 画像の最大容量(bytes)
}

プリセットって何? という方は、弊社伊藤の過去の記事をご参照ください。

https://dev.classmethod.jp/articles/cloudinary-restrict-access-and-signed-url/#toc-4

上記以外のオプションは↓からご確認ください。

https://cloudinary.com/documentation/upload_widget_reference

注意点: 認証

上記読んでお気づきの方がいるかもしれませんが、APIキーなどは特に指定していません。

Cloudinaryのプリセットには UnsignedSigned の2種類あり、Unsigned の場合は特に認証情報は不要なのですが(その代わり誰でもアップロードできてしまう)、Signed の場合は都度署名を生成して渡してあげる必要があります。

署名アップロードのほうがよりセキュアなため、基本的にはSigned 形式が良いかと思います。

署名生成にはSDKが利用できます。

https://cloudinary.com/documentation/authentication_signatures

下記、Pythonの例です。

import cloudinary

cloudinary.config(
    cloud_name=CLOUD_NAME,
    api_key=ENV_API_KEY
)

# 署名を生成 ※利用側でsource以外は同じ情報を利用する必要がある
signature_payload = {
    'timestamp': TIMESTAMP,
    'upload_preset': UPLOAD_PRESET,
    'folder': FOLDER,
    'source': 'uw',
    'context': PAYLOAD_CONTEXT,
}

signature = cloudinary.utils.api_sign_request(signature_payload, API_SECRET)

上記で署名が生成できます。

その署名と、署名に利用したAPIキー、タイムスタンプ、フォルダを使ってJavascriptコード側でwidgetを初期化します。(なぜか source は生成時の情報と一致していなくても問題ないようでした)

const option = {
    apiKey: data.apikey,
    uploadSignatureTimestamp: data.timestamp,
    uploadSignature: data.signature,
    folder: data.folder
}

こんなのも作りました

Javascriptが書ける場所であれば埋め込めるため、ヘッドレスCMSのContentfulのカスタムAppとしてCloudinaryアップローダを作ってみました。興味のある方は使ってみてぜひフィードバックをいただければ喜びます。

https://github.com/xxbxxqxx/contentful-app-cloudinary-uploader

2. Media Library Widget について

Media Library タイプのウィジェットでは、Cloudinaryのコンソールをほぼそのままアプリ内に呼び出すことが可能です。Cloudinaryに保存されているメディアの表示・アップロード・編集・削除が実行できるUIを提供します。

以下基本的な使用例。

<script src="https://widget.cloudinary.com/v2.0/global/all.js" type="text/javascript"></script>

<button id="open_library" class="cloudinary-button">Open Media Library</button>

<script type="text/javascript">
  document.getElementById('open_library').addEventListener('click', function () {
    cloudinary.openMediaLibrary(
      {
        cloud_name: 'your_cloud_name',
        api_key: 'your_api_key',
        multiple: true,
      },
      {
        insertHandler: function (data) {
          data.assets.forEach(function (asset) {
            console.log('Selected asset:', asset);
          });
        },
      }
    );
  }, false);
</script>

先ほどのUploaderとほぼ同じで、ライブラリを開くためのボタンを作成し、UI上で選択されたメディア情報をコールバックで受け取っています。

Uploader タイプに比べてできることは多いですが、その分条件があります。

  • APIキーが必要
  • エンドユーザーはCloudinaryへのログインが必要(つまり利用者ごとのアカウント発行が必要)
  • アップロード以外の操作ができてしまう

また、その他にもウィジェット用の便利なオプションがあります。

  • SAML authentication … CMSやアプリのユーザーがすでにログインしている場合、Cloudinaryの SSOログインを設定することもできます。
  • ログアウト連携 … アプリケーションのログアウトイベントに合わせ、Cloudinaryのログアウトエンドポイントを呼び出し、ログアウト処理を同期させることができます。
  • イベントハンドリング … アップロードや削除に合わせたイベントを処理できます。

まとめ

Cloudinary ウィジェットは開発者にとって非常に使いやすいツールです。Uploader も Media Library も一長一短がありますので、ケースによって使い分けてみてください。

クラスメソッドは Cloudinary のパートナーです。開発・契約・利用に際してお困りの方は、ぜひクラスメソッドにご相談ください。

参考資料

  • https://cloudinary.com/documentation/upload_widget_reference
  • https://cloudinary.com/documentation/media_library_widget