0
Help us understand the problem. What are the problem?

posted at

API 経由で起動する Shopify Flow のトリガーを自作してみた

概要

Shopify Flowとは
Shopify のエンタープライズプラン「Shopify Plus」 を利用すると使えるようになるオートメーション機能。Shopify で構築した自身のストア上における顧客の行動をトリガーに様々なアクションを自動で行ってくれる。

Trigger → Condition → Action

  • Trigger(トリガー)
    • ワークフローを開始させるイベント
  • Condition(条件)
    • アクションを実行するかどうかの条件
  • Action(アクション)
    • 条件が満たされた時に行われる内容
ex.
・ ある商品の在庫数が◯個以下になった際に Slack 通知を飛ばす
・ ○円以上の買い物をした顧客に対して特別なタグを付与する
・ 顧客が新規登録されるたびにそのデータをスプレッドシートに記録する

スクリーンショット 2022-04-21 23.46.54.png
https://apps.shopify.com/flow

この Shopify Flow を回し始めるには「トリガー」と呼ばれるきっかけが必要になるのですが、Shopify が標準で用意しているトリガーは基本的にストア上の顧客行動が対象となっているため、それ以外の要因で引き金を引く事が難しくなっています。

もちろん、特に奇を衒った事をしようとしなければそれでも十分だと思いますが、個人的に「外部からちょこっと API を叩くだけで任意に起動できるトリガーを作れないかなぁ」みたいな要望があったため、色々調べてみました。

結果、なんとかなりそうな方法があったので紹介してみたいと思います。

API 経由でワークフローを回す事ができるようになれば、Shopify ストアとは別の自社アプリ内などに組み込んで色々と連携が捗ったり運用の幅が広がるかもしれません。

カスタムアプリを作成

スクリーンショット 2022-04-22 0.04.28_censored.jpg

Shopify Parnters のダッシュボードに入り、「アプリ管理」→「すべてのアプリ」へと進み、「アプリを作成する」ボタンをクリックします。

スクリーンショット 2022-04-22 0.08.14.png

  • カスタムアプリ
  • 公開アプリ

の2種類ありますが、今回は「カスタムアプリ」の方を選択してください。

スクリーンショット 2022-04-22 0.10.22.png

諸々入力したら、右上の「アプリを作成」ボタンをクリックしましょう。

トリガーを作成

スクリーンショット 2022-04-22 0.13.56_censored.jpg

カスタムアプリの作成に成功するとアプリ詳細画面に飛ぶはずなので、「拡張機能」という部分をクリックしてください。

スクリーンショット 2022-04-22 0.16.16.png

「作成+」をクリック。

スクリーンショット 2022-04-22 0.17.17.png

拡張機能タイプは「Flow/トリガー」を選択してください。

スクリーンショット 2022-04-22 0.19.41.png

適当な名前をつけて「Save」

スクリーンショット 2022-04-22 0.20.47.png

トリガーの設定を行うために「Working draft」をクリック。

スクリーンショット 2022-04-22 0.22.35_censored.jpg

  • トリガーのタイトル
    • 任意
  • トリガーの説明
    • 任意
  • プロパティ
    • お客様

プロパティについては、デフォルトの状態だと

  • お客様
  • 注文
  • 商品

といった3種類が用意されており、Trigger 起動時のリクエストに

  • customer_id
  • order_id
  • product_id

を含める事で Action 実行時に shopify 上のオブジェクトを参照する事ができます。

https://shopify.dev/apps/flow/triggers#shopify-properties

When you create a trigger, you add the properties that your trigger sends to Shopify Flow. You can add a custom property or a predefined Shopify property.
Shopify property lets you send the identifier of a Shopify resource to Shopify Flow. Merchants can then use the entire resource in their conditions and actions. You can add one of each Shopify property to a trigger:
For example, your trigger sends a customer ID to Shopify Flow. The merchant can create a condition that checks the customer's total spend amount. In their action, the merchant can include the template variables for customers (such as {{customer.email}}).

スクリーンショット 2022-04-22 0.34.51_censored.jpg

設定が済んだら右上の「Create version」をクリックし、「Minor version」を選択して「Create」

スクリーンショット 2022-04-22 0.36.48.png

作成が完了したら、「Publish」をクリックしましょう。

アクセストークンを取得 & ストアにインストール

諸々の準備が整ったので、自身のストアに先ほど作ったカスタムアプリをインストールしていきます。

と、その前に、カスタムアプリと通信を行うためのアクセストークンを取得しなければなりません。

アクセストークンの取得方法は色々ありますが、今回は

  • Ruby
  • Ruby on Rails
  • ngrok

を使って Web サーバーを準備し、そこで取得していきます。

各種ディレクトリ & ファイルを作成

$ mkdir shopify-access-token-getter && cd shopify-access-token-getter
$ touch Dockerfile docker-compose.yml entrypoint.sh Gemfile Gemfile.lock
./Dockerfile
FROM ruby:3.0

RUN curl https://deb.nodesource.com/setup_14.x | bash

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs yarn

ENV APP_PATH /myapp

RUN mkdir $APP_PATH
WORKDIR $APP_PATH

COPY Gemfile $APP_PATH/Gemfile
COPY Gemfile.lock $APP_PATH/Gemfile.lock
RUN bundle install

COPY . $APP_PATH

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
./docker-compose.yml
version: "3"
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
    volumes:
      - mysql-data:/var/lib/mysql
      - /tmp/dockerdir:/etc/mysql/conf.d/
    ports:
      - 4306:3306
  api:
    build:
      context: .
      dockerfile: Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
      - ./vendor/bundle:/myapp/vendor/bundle
    environment:
      TZ: Asia/Tokyo
      RAILS_ENV: development
    ports:
      - "3000:3000"
    depends_on:
      - db
volumes:
  mysql-data:
./entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
./Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "rails", "~> 6"
./Gemfile.lock
# 空欄でOK

rails new

APIモードで作成します。

$ docker-compose run api rails new . --force --no-deps -d mysql --api

database.ymlを編集

デフォルトの状態だとデータベースとの接続ができないので「database.yml」の一部を書き換えます。

./config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password # デフォルトだと空欄になっているはずなので変更
  host: db # デフォルトだとlocalhostになっているはずなので変更

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: <%= ENV["DATABASE_NAME"] %>
  username: <%= ENV["DATABASE_USERNAME"] %>
  password: <%= ENV["DATABASE_PASSWORD"] %>

コンテナを起動 & データベースを作成

$ docker-compose build
$ docker-compose up
$ docker-compose run api bundle exec rails db:create

localhost:3000 にアクセス

スクリーンショット 2021-07-24 0.30.48.png

localhost:3000 にアクセスしてウェルカムページが表示されればOKです。

ngrok を起動

./config/environments/development.rb
# 追記
config.hosts << ".ngrok.io"
$ ngrok http 3000

https:// を割り当てるために上記コマンドで起動します。

アクセストークン取得用の処理を記述

./Gemfile
gem "faraday"
$ docker-compose build

HTTP クライアントの「faraday」をインストールしてきましょう。

$ docker-compose run api bundle exec rails g controller api/shopify
./app/controllers/api/shopify_controller.rb
class Api::ShopifyController < ApplicationController
  def auth
    shop = params[:shop]
    client_id = "CUSTOM_APP_API_KEY" # カスタムアプリの API キー
    scope = "write_customers,read_customers"
    redirect_uri = "https://************.ngrok.io/api/shopify/token" # ngrok で起動したサーバーの URL
    state = SecureRandom.random_bytes(16)

    query = {
      client_id: client_id,
      scope: scope,
      redirect_uri: redirect_uri,
      state: state
    }.to_query

    url = "https://#{shop}/admin/oauth/authorize?#{query}"

    redirect_to url
  end

  def token
    shop = params[:shop]
    code = params[:code]

    client_id = "CUSTOM_APP_API_KEY"            # カスタムアプリの API キー
    client_secret = "CUSTOM_APP_API_SECRET_KEY" # カスタムアプリの API シークレットキー

    res = Faraday.post("https://#{shop}/admin/oauth/access_token",
      client_id: client_id,
      client_secret: client_secret,
      code: code
    )

    p res.body
  end
end

アクセストークン取得用の処理をコントローラーに書いていきます。

ルーティングを定義

./config/routes.rb
Rails.application.routes.draw do
  get "api/shopify/auth", to: "api/shopify#auth"
  get "api/shopify/token", to: "api/shopify#token"
end

これで

  • https://************.ngrok.io/api/shopify/auth
  • https://************.ngrok.io/api/shopify/token

にアクセスした際に先ほど定義した処理が走るようになりました。

アプリ URL & リダイレクト URL を変更

https://localhost/」 で暫定的に埋めていた

  • アプリ URL
  • リダイレクト URL

を先ほど立ち上げた Web サーバーのものに置き換えます。

スクリーンショット 2022-04-22 1.20.32_censored.jpg

  • アプリ URL
    • https://**************.ngrok.io/api/shopify/auth
  • リダイレクト URL
    • https://**************.ngrok.io/api/shopify/token

インストールリンクを作成

スクリーンショット 2022-04-22 1.08.56_censored.jpg

諸々の準備ができたので、いよいよカスタムアプリをストアにインストールしていきます。

スクリーンショット 2022-04-22 1.10.55_censored.jpg

インストール先のストアドメインを入力し、「リンクを生成する」をクリックしてください。

スクリーンショット 2022-04-22 1.23.34_censored (2).jpg

あとは生成されたリンクをコピーし、アドレスバーにペーストしてアクセスしてみましょう。

スクリーンショット 2022-04-22 1.57.52_censored.jpg

上手くいけばこんな感じのインストール画面が出てくるので、右上の「アプリをインストール」をクリック。

スクリーンショット 2022-04-22 2.01.15_censored (1).jpg

インストールが完了したら、アプリケーションのログを見てみましょう。

"{\"access_token\":\"shpca_********************\",\"scope\":\"write_customers\"}"

shpca_が接頭辞として付いている文字列がアクセストークンなので、メモに控えておいてください。

ワークフローを作成

スクリーンショット 2022-04-22 6.24.14_censored.jpg

ストアにカスタムアプリをインストールできたら、ワークフローを作成します。

スクリーンショット 2022-04-22 6.26.40_censored.jpg

ワークフロー作成画面が開いたら、トリガーとして先ほど作成したカスタムアプリから「Test Trigger」を選択してください。

スクリーンショット 2022-04-23 2.37.10.png

次に、アクションとして「Add customer tags」を開き

  • test-trigger

適当な文字列を入力。

スクリーンショット 2022-04-23 2.37.49.png

トリガーとアクションの設定が終わったら、右上の「Turn on workflow」からワークフローを稼働させ始めます。(条件(Condition)は今回割愛しました)

動作確認

curl -X POST "https://*******.myshopify.com/admin/api/2022-04/graphql.json" \
-H "Content-Type: application/graphql" \
-H "X-Shopify-Access-Token: shpca_******************************" \
-d '
mutation {
  flowTriggerReceive(body: "{
    \"trigger_id\": \"**********-****-****-****-**********\",
    \"properties\": {
      \"customer_id\": *****************
    }
  }") {
    userErrors {
      field,
      message
    }
  }
}'
  • *******.myshopify.com
    • 自身のストアドメイン
  • X-Shopify-Access-Token
    • 事前に取得したアクセストークン
  • trigger_id
    • トリガーID
  • customer_id
    • 対象の顧客ID

スクリーンショット 2022-04-23 2.43.15_censored.jpg

トリガーIDについては、「カスタムアプリ」→「拡張機能」→「Test Trigger」→「Edit draft」を開き、ペイロードのプレビュー という部分を確認してください。

上記 Curl コマンドを実行し、

{
	"data": {
		"flowTriggerReceive": {
			"userErrors": []
		}
	},
	"extensions": {
		"cost": {
			"requestedQueryCost": 1,
			"actualQueryCost": 1,
			"throttleStatus": {
				"maximumAvailable": 2000,
				"currentlyAvailable": 1999,
				"restoreRate": 100
			}
		}
	}
}

こんな感じのレスポンスが返って来ればOKです。

スクリーンショット 2022-04-23 2.50.21_censored.jpg

customer_id で指定した顧客情報も確認してみてください。「test-trigger」というタグが付与されているはず。

これで API 経由で Shopify Flow を起動させる事に成功しました。

あとがき

以上、Shopify Flow のトリガーを自作してみました。

API 経由で起動できる事から、Shopify ストア以外の場所でも何かしらのアクションを起こせるようになり、活用の幅が広がりそうな気がします。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?