全2回のシリーズでは、Integrate.ioを使ってShopifyストアのデータを効率的に抽出し、Google Data Studioのようなツールを使って有益なビジュアライゼーションを作成する方法をご紹介します。チャートやビジュアライゼーションの助けを借りて、あなたのShopifyストアに関する分析を行うための質問に答えるためのシステムを設定してみます。これらの質問の例としては、以下のようなものがあります。

  • 現在、日/週/月にどのくらいの売上があったか?
  • 先月/四半期/年と比較して、売上はどのくらい変化しているか?
  • 私の注文はどこから来ているのか?今月は何人の新規顧客を獲得したか?
  • 何件の注文が返金になったか?
  • 何件の注文が未処理(未引当や未出荷)となっているか?どのくらいの支払いが保留状態になっているのか?

これから、みなさんがこれらの質問に答えるための一般的なプロセスを見ていきます。Shopifyのアプリストアを見てみると、このようなビジュアライゼーションを作成するアプリは、セットで年間数百ドルのコストがかかることがわかります。

パート1では、データソース(Shopifyストア)とデータの送信先を設定します。パート2では、Shopifyデータを取得するためのIntegrate.ioパイプラインを作成し、Google Studioを使用して上記の質問に答えるためにデータを可視化します。 

Shopifyストアについて

すでにストアを持っている場合は、次のステップでそのストアをIntegrate.ioと接続します。

もし、最初にシミュレートされたデータを使ってこれらのステップを完了したいのであれば、開発用のストアをセットアップして(今回はそれを利用します)、ShopifyのAdmin APIを使って実際のデータのようなデータをプッシュすることができます(そのためのコードについては、次のステップを参照してください)。

開発用のストアを設定するには、Shopifyの案内に従い設定を行います。 詳細を記入し、開発用のストア設定フォームでストアの目的を選択します。 

Shopify コネクションの設定

さて、ストアの準備ができたので、次のステップはIntegrate.ioとストアを接続することです。Integrate.ioのダッシュボードから、Shopifyのストアアドレスを入力して、Shopify接続を新規で作成する必要があります。

thumbnail image

thumbnail image

行き詰った場合は、Integrate.ioのヘルプ「Allowing Integrate.io access to my data on Shopify」でステップバイステップの手順を確認してください。

サンプルデータの収集

以下の手順を使用して、開発用のストアにいくつかのデータを入力することができます。もし実際のストアで試している場合(すでにいくつかの注文がある場合)は、次のセクションにスキップしてください。

プライベートアプリの設定

Shopifyのプライベートアプリでは、APIにアクセスすることができます。こちらの手順でプライベートアプリを設定することができます。 

thumbnail image

アプリには必ず以下の権限を与えてください。

  • Customers:読み取りと書き込み
  • Orders:読み取りと書き込み
  • Products:読み取りと書き込み

上記のパーミッションでアプリを作成すると、アプリ設定の管理者APIセクションに「Example URL」というフィールドが表示されます。このURLをコピーして、ブラウザで試してみてください。 

thumbnail image

ブラウザのウィンドウに以下のような出力が表示されます。

{
    "orders":[]
}

これはShopifyからJSON形式で返されるOrders APIの結果です。 

Shopify APIのURL構造を理解する

URLを見てみると、https://$api_key:$password@$store_url/admin/api/2020-07/orders.jsonという形式になっています。

  • api_key、$password、およびstore_urlは、それぞれAPIキー、アプリのパスワード、およびストアのURLです。
  • /admin/api/2020-07は、バージョン2020-07の管理者APIにアクセスすることを表しています。
  • orders.jsonは、JSON形式のOrdersリソースデータをリクエストしています。商品の場合はproducts.jsonを使用し、顧客の場合はcustomers.jsonを使用します。

注意:ライブストアでプライベートアプリを設定している場合は、このURLを公開しないでください。 

開発ストアにはまだ注文がないので、返されたJSON配列は空です。次はコードを使ってこのようなデータを生成します。

サンプルデータをShopifyストアにセットする

ここに用意したPythonスクリプトを使って、いくつかのデータを生成して遊ぶことができます。設定方法はGithubリポジトリのREADMEファイルに記載されています。実行には5分もかからないはずです。

Shopify API 構造の解説

Shopifyストアにデータが入ったので、実際にIntegrate.ioでパイプラインを作成しましょう。

この記事では、ShopifyのAdmin APIの3つの主要なAPIリソース、Customer、Product、Ordersに焦点を当てていきます。前述したように、Shopifyの一般的なAPI URLは以下のようになります。

https://$shop_name/admin/api/2020-07/customers.json?limit=250&updated_at_min=$last_updated

最後にいくつかのURLパラメータを追加しました。 

  • limit は、毎回のAPI コール (つまりページ) で取得するレコード数を指定します。
  • updated_at_minで古いレコードをフィルタリングするタイムスタンプのしきい値を指定します。

Shopify APIはカーソルベースのページネーションをサポートしており、次のページのURLはAPIレスポンスのLinkヘッダーを通して共有されます。ページネーションはIntegrate.ioのShopify接続で自動的に処理されるので、そのためのロジックを書く必要はありません。

注意すべき重要なことは、これらのAPIのレスポンスにはネストされたマップと配列が含まれているということです。例えば、ここに Products API のレスポンスがあります。

{
    "products": [
        {
            "id": 5605681594534,
            "title": "ADIDAS | CLASSIC BACKPACK",
            "body_html": "This women's backpack has a glam look, thanks to a 
faux-leather build with an allover fur print. The front zip pocket keeps 
small things within reach, while an interior divider reins in potential 
chaos.",
            "vendor": "ADIDAS",
            "product_type": "ACCESSORIES",
            "created_at": "2020-08-13T09:56:30-04:00",
            "handle": "adidas-classic-backpack",
            "updated_at": "2020-08-17T07:41:11-04:00",
            "published_at": "2020-08-13T09:56:30-04:00",
            "template_suffix": null,
            "published_scope": "web",
            "tags": "adidas, backpack, egnition-sample-data",
            "admin_graphql_api_id": "gid://shopify/Product/5605681594534",
            "variants": [
                {
                    "id": 35682265563302,
                    "product_id": 5605681594534,
                    "title": "OS / black",
                    "price": "70.00",
                    "sku": "AD-03-black-OS",
                    "position": 1,
                    "inventory_policy": "deny",
                    "compare_at_price": "0.00",
                    "fulfillment_service": "manual",
                    "inventory_management": "shopify",
                    "option1": "OS",
                    "option2": "black",
                    "option3": null,
                    "created_at": "2020-08-13T09:56:30-04:00",
                    "updated_at": "2020-08-13T09:57:37-04:00",
                    "taxable": true,
                    "barcode": null,
                    "grams": 0,
                    "image_id": null,
                    "weight": 0.0,
                    "weight_unit": "kg",
                    "inventory_item_id": 37588493500582,
                    "inventory_quantity": 8,
                    "old_inventory_quantity": 8,
                    "requires_shipping": true,
                    "admin_graphql_api_id": "gid://shopify/ProductVariant/
35682265563302"
                }
            ],
            "options": [
                {
                    "id": 7139663347878,
                    "product_id": 5605681594534,
                    "name": "Size",
                    "position": 1,
                    "values": [
                        "OS"
                    ]
                },
                {
                    "id": 7139663380646,
                    "product_id": 5605681594534,
                    "name": "Color",
                    "position": 2,
                    "values": [
                        "black"
                    ]
                }
            ],
            "images": [
                {
                    "id": 18699642831014,
                    "product_id": 5605681594534,
                    "position": 1,
                    "created_at": "2020-08-13T09:56:30-04:00",
                    "updated_at": "2020-08-13T09:56:30-04:00",
                    "alt": null,
                    "width": 635,
                    "height": 560,
                    "src": "https://cdn.shopify.com/s/files/1/0411/0516/2406/products/
85cc58608bf138a50036bcfe86a3a362.jpg?v=1597326990",
                    "variant_ids": [],
                    "admin_graphql_api_id": "gid://shopify/ProductImage/18699642831014"
                },
                {
                    "id": 18699642863782,
                    "product_id": 5605681594534,
                    "position": 2,
                    "created_at": "2020-08-13T09:56:30-04:00",
                    "updated_at": "2020-08-13T09:56:30-04:00",
                    "alt": null,
                    "width": 635,
                    "height": 560,
                    "src": "https://cdn.shopify.com/s/files/1/0411/0516/2406/products/
8a029d2035bfb80e473361dfc08449be.jpg?v=1597326990",
                    "variant_ids": [],
                    "admin_graphql_api_id": "gid://shopify/ProductImage/18699642863782"
                },
                {
                    "id": 18699642896550,
                    "product_id": 5605681594534,
                    "position": 3,
                    "created_at": "2020-08-13T09:56:30-04:00",
                    "updated_at": "2020-08-13T09:56:30-04:00",
                    "alt": null,
                    "width": 635,
                    "height": 560,
                    "src": "https://cdn.shopify.com/s/files/1/0411/0516/2406/products/
ad50775123e20f3d1af2bd07046b777d.jpg?v=1597326990",
                    "variant_ids": [],
                    "admin_graphql_api_id": "gid://shopify/ProductImage/18699642896550"
                }
            ],
            "image": {
                "id": 18699642831014,
                "product_id": 5605681594534,
                "position": 1,
                "created_at": "2020-08-13T09:56:30-04:00",
                "updated_at": "2020-08-13T09:56:30-04:00",
                "alt": null,
                "width": 635,
                "height": 560,
                "src": "https://cdn.shopify.com/s/files/1/0411/0516/2406/products/
85cc58608bf138a50036bcfe86a3a362.jpg?v=1597326990",
                "variant_ids": [],
                "admin_graphql_api_id": "gid://shopify/ProductImage/18699642831014"
            }
        }
    ]
}

これはトップレベルにproducts配列があり、各製品オブジェクトの中には、バリエーション、画像、オプションのための配列があります。リレーショナルデータベースにこのようなタイプのレスポンスを格納するには、テーブル(行と列)の形でモデル化する必要があります。

コアとなるShopify API リソース

ShopifyのAdmin APIのドキュメントをスクロールしてみると、レスポンスに圧倒的な数のフィールドを持つAPIリソースがたくさんあることがわかります。しかし、いくつかの本質的なAPIリソースとフィールドに焦点を当てることで、ほとんどの一般的なユースケースをカバーすることができます。これらのAPIリソースとフィールドに含まれる情報は以下の通りです。

  • Orders (Orders Resource レスポンスのトップレベルのフィールド)
  • Order Refunds (Orders Resource のレスポンス内でネスト化され保持)
  • Products(Products Resourceのレスポンスのトップレベルのフィールド)
  • Product Variants Products Resourceのレスポンス内でネスト化されて保持)
  • CustomersCustomers Resourceのレスポンスのトップレベルフィールド)
  • Customer Addresses (Customers Resource のレスポンス内でネスト化されて保持)

第2部で作成するパイプラインを使用して、これら6つの情報を独立したリレーショナルテーブルに配置します。

データ送信先のデータベースを用意する

私はShopifyのデータをPostgreSQLデータベースに抽出します。しかし、Integrate.ioは提供するものに汎用性があり、他にも多数のデータベースをサポートしています。パイプラインを好みのデータベースコンポーネントに接続し、ダッシュボードにデータベース接続を追加するだけです。

データ送信先のデータベースはありますか?

データベースを持っていない場合は、PostgreSQL、MySQL、またはその他のサポートされているデータベースをローカルコンピュータにインストールして、ngrokを使ってTCPトンネルを作成することができます(まさにこの記事のために私がやっていることです)。しかし、コンピュータをデータベースとして使用することは、テスト目的の場合にのみお勧めします。本番環境では、HerokuやAWSのようなクラウドプロバイダを使ってデータベースサーバを1台設定するかもしれません(Heroku PostgresAWS Redshiftを確認してください)。

データベースを使う理由とは?

Shopifyのデータを自分のデータベースに保存することには、いくつかのメリットがあります。

  • あなたのデータはあなたの管理下にあります。データを安全に保つために第三者を信頼する必要はなく、いつでもデータを検査することができます。
  • データを最新の状態に保ちたい場合は、Integrate.ioのもつインクリメンタルローディングやスケジュール機能を利用することができます。これらは後の記事で紹介するように、非常に便利な機能です。

データベースに接続する

Integrate.ioからデータベースへ接続するには、Integrate.ioのダッシュボードからデータベース接続を作成しなければなりません。ホストアドレス、ユーザー名、パスワードなどの典型的なデータベースの詳細を提供しなければなりません。詳しい説明は Using Components: Database Destinationで説明されています。ngrokでトンネリングした私のローカルPostgreSQLデータベースの詳細をシェアしておきます。 

thumbnail image

この記事では、Shopifyストアとデータデスティネーションの接続を設定しました。また、Shopify Admin APIの構造とその仕組みについても簡単に説明しましたが、この情報は次の記事の中でETLパイプラインを作成するのに役立ちます。パート2では、これらの接続を使用してデータを取得するIntegrate.ioパッケージを作成し、その後Google Data Studioの助けを借りてそれを可視化します。