🌉

【Shopify.dev和訳】Apps/Dev tools/App Bridge/Actions①

2021/09/10に公開

この記事について

この記事は、Apps/Developer tools/App Bridge/Actionsの記事を和訳したものです。

記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。

Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

https://apps.shopify.com/shopify-application-314?locale=ja&from=daniel

Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。

https://apps.shopify.com/font-picker-1?locale=ja&from=daniel

アクション

Shopify App Bridge は、アクションという新しいコンセプトを導入しています。アクションは、アプリケーションやホストがペイロードを持つイベントをトリガーするための方法を提供します。

このセクションのコード例では、モジュール式の JavaScript パターンを使用していることを前提としています。もし、Shopify App Bridge の CDN ホスト版を使用している場合は、import をwindow['app-bridge']グローバルのオブジェクトに置き換えることで、同じ結果を得ることができます。

以下のコードの代わりに

import { TitleBar } from "@shopify/app-bridge/actions"

こちらのコードを使用してください

var AppBridge = window["app-bridge"]
var actions = AppBridge.actions
var TitleBar = actions.TitleBar

その他のサンプルコードは、そのままの状態で機能します。

シンプルなアクション

シンプルなアクションはホスト(例:Shopify admin や Shopify POS)とアプリの両方でディスパッチできます。ここでは、アプリ内のシンプルアクションの例を示します。

import createApp from "@shopify/app-bridge"
import { Toast } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

const toastOptions = {
  message: "Product saved",
  duration: 5000,
}

const toastNotice = Toast.create(app, toastOptions)
toastNotice.subscribe(Toast.Action.SHOW, (data) => {
  // showアクションで何かをする
})

toastNotice.subscribe(Toast.Action.CLEAR, (data) => {
  // clearアクションで何かをする
})

// 上記のtoastOptionsを使ってshow Toastアクションを実行します
toastNotice.dispatch(Toast.Action.SHOW)

アクションセット

アクションセットは、アプリが作成・使用するシンプルなアクションをグループ化したものです。アクションセットは一意の ID で生成され、アプリが直接サブスクライブできる追加機能を備えています。アクションセットは、いつでもディスパッチやサブスクライブが可能なアクションの永続的なセットと考えることができます。以下は、Toast アクションセットの例です。

import createApp from '@shopify/app-bridge';
import { Toast } from '@shopify/app-bridge/actions';

const app = createApp({
  apiKey: '12345',
  host: host,
});

const toastOptions = {
  message: 'Product saved',
  duration: 5000
};

const toastNotice = Toast.create(app, toastOptions);
toastNotice.subscribe(Toast.Action.SHOW, data => {)
  // showアクションで何かをする
});

toastNotice.subscribe(Toast.Action.CLEAR, data => { 何かアクションを起こしてください。
  // クリアアクションで何かをする
});

// 上記の toastOptions を使用して、show Toast アクションをディスパッチします。
toastNotice.dispatch(Toast.Action.SHOW);

Button

Buttonアクションセットは、TitleBarModalなどの他のアクションセットのボタンを構築するために使用されます。

セットアップ

アプリを作成し、@shopify/app-bridge/actionsからButtonモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照することに注意してください。

import createApp from "@shopify/app-bridge"
import { Button } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

ボタンの作成

Saveというラベルのついたプライマリボタンを作成します。

const myButton = Button.create(app, { label: "Save" })

クリックアクションのサブスクリプション

subscribeを呼び出すことで、ボタンアクションをサブスクリプションすることができます。この関数は、アクションのサブスクリプションを解除するために呼び出すことができる関数を返します。

const myButton = Button.create(app, { label: "Save" })
const clickUnsubscribe = myButton.subscribe(Button.Action.CLICK, (data) => {
  // クリックイベントで何かをする
})

// クリックアクションのサブスクリプションを解除する
clickUnsubscribe()

クリックアクションのディスパッチ

const myButton = Button.create(app, { label: "Save" })
myButton.dispatch(Button.Action.CLICK)

ペイロード付きクリックアクションのディスパッチ

const myButton = Button.create(app, { label: "Save" })
// ペイロードでアクションを起動
myButton.dispatch(Button.Action.CLICK, { message: "Saved" })

// アクションをサブスクライブし、ペイロードを読み取る
myButton.subscribe(Button.Action.CLICK, (data) => {
  // data = { payload: { message: 'Saved'}}
  console.log(`Received ${data.payload.message} message`)
})

モーダルにボタンを付ける

モーダルのような他のアクションにボタンを取り付けることができます。モーダルについて詳しくは、「モーダル」をご覧ください。

const okButton = Button.create(app, {label: 'Ok'});
const cancelButton = Button.create(app, {label: 'Cancel'});const modalOptions = {
  title: 'My Modal',
  message: 'Hello world!',
  footer: {primary: okButton, secondary: [cancelButton]},
};

const myModal = Modal.create(app, modalOptions);

ボタンのスタイル

style プロパティを渡すことで、ボタンのスタイルを変更することができます。ボタンは 1 つの代替スタイル、Danger スタイルをサポートしています。

const myButton = Button.create(app, { label: "Delete", style: Button.Style.Danger })

オプションの更新

部分的なボタンのオプションを指定して set メソッドを呼び出し、既存のボタンのオプションを更新することができます。これにより、ボタンのupdateアクションが自動的に開始され、新しく指定されたオプションが既存のオプションに統合されます。

const myButton = Button.create(app, { label: "Save" })
myButton.set({ disabled: true })

解除

ボタンの現在のサブスクリプションをすべて削除するために unsubscribe を呼び出します。

const myButton = Button.create(app, {label: 'Save'});
myButton.subscribe(Button.Action.CLICK, data => {)
  // クリックイベントで何かをする
});

myButton.unsubscribe();

ButtonGroup

ButtonGroupアクションセットは、Buttonアクションセットのインスタンスをグループ化するために使用されます。ButtonGroupアクションセットは、アプリのTitleBarアクションセットに渡すことができます。

設定方法

アプリを作成し、ButtonButtonGroupモジュールを@shopify/app-bridge/actionsからインポートします。以下の例では、このサンプルアプリケーションを参照することに注意してください。

import createApp from "@shopify/app-bridge"
import { Button, ButtonGroup } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

ボタングループの作成

More actionsというラベルのプライマリボタンと、SettingsHelpというラベルの 2 つのボタンを生成します。

const button1 = Button.create(app, { label: "Settings" })
const button2 = Button.create(app, { label: "Help" })
const myGroupButton = ButtonGroup.crelate(app, {
  label: "More actions",
  buttons: [button1, button2],
})

更新を登録する

subscribeを呼び出すと、ボタングループの更新アクションをサブスクリプションできます。この関数は、アクションのサブスクリプションを解除するために呼び出すことができる関数を返します。

// 上記と同じボタングループを使用
const updateUnsubscribe = myGroupButton.subscribe(ButtonGroup.Action.UPDATE, (data) => {
  // ボタングループが更新されたら何かをする
  // データは以下のような形になっています。{id: string, label: string, buttons: [{id: string, label: string, disabled: boolean,} ...]}
})

// 登録解除
updateUnsubscribe()

登録解除

unsubscribeを呼び出すと、ボタングループとその子のサブスクリプションをすべて削除します。

const button1 = Button.create(app, {label: 'Settings'});
const button2 = Button.create(app, {label: 'Help'});const myGroupButton = ButtonGroup.create(app, {label: 'More actions', buttons: [button1, button2]});
// 上と同じボタングループを使う
myGroupButton.subscribe(ButtonGroup.Action.UPDATE, data => {
  // ボタングループが更新されたら何かをする
  // データは次のような形式になっています。{id: string, label: string, buttons: [{id: string, label: string, disabled: boolean} ...]}
});

button1.subscribe(Button.Action.CLICK, () => {
  //クリックアクションで何かをする
});

button2.subscribe(Button.Action.CLICK, () => {
  //クリックアクションで何かをする
});

// ボタングループの更新アクションを解除する
// button1とbutton2のクリックアクションからUnsubscribeする
myGroupButton.unsubscribe();

ボタングループのアクションからのみ登録解除する

unsubscribefalse をつけて呼び出すと、子のサブスクリプションはそのままにして、ボタングループのサブスクリプションだけを削除することができます。例えば、ボタングループのサブスクリプションを解除したいが、ボタンリスナーは残しておき、ボタンを別のアクション(モーダルなど)で再利用できるようにしたい場合などです。

const button1 = Button.create(app, { label: "Settings" })
const button2 = Button.create(app, { label: "Help" })
const myGroupButton = ButtonGroup.create(app, {
  label: "More actions",
  buttons: [button1, button2],
})
// 上と同じボタングループを使う
myGroupButton.subscribe(ButtonGroup.Action.UPDATE, (data) => {
  // ボタングループが更新されたら何かをする
  // データは次のような形式になっています。{id: string, label: string, buttons: [{id: string, label: string, disabled: boolean} ...]}
})

button1.subscribe(Button.Action.CLICK, () => {
  //クリックアクションで何かをする
})

button2.subscribe(Button.Action.CLICK, () => {
  //クリックアクションで何かをする
})

// ボタングループの更新アクションのみをサブスクリプション解除する
myGroupButton.unsubscribe(false)

// モーダルでボタン1とボタン2を再利用する
const modalOptions = {
  title: "私のモーダル",
  message: "Hello world!",
  footer: { secondary: [button1, button2] },
}

const myModal = Modal.create(app, modalOptions)

オプションの更新

既存のボタングループのオプションを更新するために、部分的なボタングループのオプションで set メソッドを呼び出すことができます。これは、自動的にボタングループのupdateアクションを起こし、新しく与えられたオプションを既存のオプションに統合します。

const button1 = Button.create(app, { label: "Settings" })
const button2 = Button.create(app, { label: "Help" })
const myGroupButton = ButtonGroup.create(app, {
  label: "More actions",
  buttons: [button1, button2],
})
myGroupButton.set({ disabled: true })

ボタンの更新

ボタングループに取り付けられたボタンを更新することができます。ボタングループの子ボタンが更新されると、自動的にボタングループのupdateアクションが発生します。

const button1 = Button.create(app, { label: "Settings" })
const button2 = Button.create(app, { label: "Help" })
const myGroupButton = ButtonGroup.create(app, {
  label: "More actions",
  buttons: [button1, button2],
})
button1.set({ disabled: true })

Cart

必要なもの

これらのアクションを実行するには、以下のアプリのバージョンが必要です。

  • Point of Sale iOS v5.11.0またはそれ以上
  • Point of Sale Android v3.3.2またはそれ以上

設定方法

アプリを作成し、@shopify/app-bridge/actionsからCartモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照することに注意してください。

import createApp from "@shopify/app-bridge"
import { Cart } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

カートの作成

カートを作成し、カートの更新情報をサブスクライブします。

var cart = Cart.create(app)
cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] cart update", payload)
})

エラー処理

app.error(function (data: Error.ErrorAction) {
  console.info("[client] Error received: ", data)
})

機能の検出

カートアクションは Shopify Point of Sale アプリでのみ利用可能なので、アクションを呼び出す前にそのアクションが利用可能かどうかをチェックすると良いでしょう。これにより、機能が利用可能かどうかを適切な UI で表示することができます。機能検出の詳細については、「機能」を参照してください。

次の例では、Cart.Action.FETCHが利用可能かどうかを要求し、その結果を使って UI を変更することで、カートアクションで機能検出を使用する方法を示しています。

まず、カートグループが利用可能かどうかを確認します。

app.featuresAvailable([Group.Cart]).then(function (state) {...});

プロミス ブロックは、カート アクションのステータスを含む state オブジェクトに解決します。Cart.Action.FETCHをクエリして、そのオブジェクト内でDispatchします。trueの場合は、以下のFetch cartの手順に従います。falseの場合、このコンテキストではカートアクションは使用できません。この方法を使えば、カートが空の場合と、カートが利用できないコンテキストを区別することができます。

app.featuresAvailable(Group.Cart).then(function (state) {
  var _ref = state.Cart && state.Cart[Cart.Action.FETCH],
    Dispatch = _ref.Dispatch

  if (Dispatch) {
    cart.dispatch(Cart.Action.FETCH)
  } else {
    var toastOptions = {
      message: "カートは利用できません",
      duration: 5000,
      isError: ture,
    }
    var toastError = Toast.create(app, toastOptions)
    toastError.dispatch(Toast.Action.SHOW)
  }
})

カートの更新

グループ Cart
アクション UPDATE
アクションタイプ APP::CART::UPDATE
説明 Shopify POS から、現在アクティブなカートの最新状態を取得します。

このアクションをサブスクライブすると、カートの更新情報が提供されます。

var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] fetchCart", payload)
  unsubscriber()
})
// ...
// 他の Cart アクションを呼び出す

NoteAttribute ペイロード

キー タイプ 説明
name String 属性の名前です。
value String 属性の値です。

レスポンス

キー タイプ 説明
subtotal String 割引を含む、税・送料前の現在のカートの合計金額です。値段は、ショップの既存の通貨設定に基づいています。
taxTotal String 現在のカートの税金の合計です。値段は、ショップの既存の通貨設定に基づいています。
grandTotal String 現在のカートの税金と割引を適用した後の合計金額です。値段は、ショップの既存の通貨設定に基づいています。
customer Customer? 現在のカートに関連付けられている顧客です。
lineItems Array[LineItem] lineItem オブジェクトのリストです。
noteAttributes Array[NoteAttribute]? カートのプロパティを含むオブジェクトのリストです。
cartDiscount Discount? カート全体に適用される現在の割引額。
note String? カートに関連するノート。

フェッチカート

グループ Cart
アクション FETCH
アクションタイプ APP::CART::FETCH
説明 Shopify POS から現在アクティブなカートを要求します。

カートは、Cart.Action.UPDATEでデータを受け取る前に FETCH を呼び出す必要があります。

var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] fetchCart", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.FETCH)

お客様の設定

グループ Cart
アクション SET_CUSTOMER
アクションの種類 APP::CART::SET_CUSTOMER
説明 現在のカートにカスタマーを設定します。

これは、カートとその後の注文に添付される顧客です。既存の顧客 ID を持つ顧客を設定することも、新しい顧客を作成することもできます。

ID を持つ既存のカスタマー

var customerPayload = {
  id: 123,
}

新しいお客様です。

var customerPayload = {
  email: "voisin@gmail.com",
  firstName: "Sandrine",
  lastName: "Voisin",
  note: "2019年の最初のお客様",
}
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] setCustomer", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.SET_CUSTOMER, {
  data: cutomerPayload,
})

リクエスト

キー タイプ 説明
data Customer お客様のデータです。

カスタマーペイロード

キー タイプ 説明
id Number? 既存の顧客の ID です。
email String? 新規顧客の電子メールです。
firstName String? 新しい顧客のファーストネームです。
lastName String? 新規顧客の姓名
note String? 新規顧客のメモです。

顧客の住所を追加する

グループ Cart
アクション ADD_CUSTOMER_ADDRESS
アクションの種類 APP::CART::ADD_CUSTOMER_ADDRESS
説明 現在のカートに関連付けられている顧客に新しい住所を追加します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] addCustomerAddress", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.ADD_CUSTOMER_ADDRESS, {
  data: {
    address1: "528 Old Weston Road",
    address2: "Apartment 201",
    city: "Toronto",
    company: "Eliteweb Inc",
    country: "Canada",
    countryCode: "CA",
    firstName: "Sandrine",
    lastName: "Voisin",
    name: "Sandrine Voisin",
    phone: "416 684 1787",
    province: "Ontario",
    provinceCode: "ON",
    zip: "M6N 3B1",
  },
})

リクエスト

キー タイプ 説明
data Address 新規にアドレスを作成するためのデータです。

アドレス ペイロード

キー タイプ 説明
address1 String? 顧客のプライマリアドレス。
address2 String? 住所に関連する追加情報(アパート番号、スイート番号、ユニット番号など)
city String? 顧客の都市名
company String? 住所に関連する会社名
firstName String? 顧客のファーストネームです。
lastName String? 顧客の姓名
phone String? 顧客の電話番号を入力してください。
province String? 住所の都道府県です。
country String? 住所の国名を指定します。
zip String? 住所の郵便番号を指定します。
name String? 住所の名前を指定します。
provinceCode String? 都道府県名の頭文字をとったものです。
countryCode String? ISO 3166-1 (alpha-2)形式の国コードです。

お客様の住所を更新する

グループ Cart
アクション UPDATE_CUSTOMER_ADDRESS
アクションの種類 APP::CART::UPDATE_CUSTOMER_ADDRESS
説明 現在のカートに関連付けられている顧客の新しい住所を更新します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] updateCustomerAddress", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.UPDATE_CUSTOMER_ADDRESS, {
  index: 0,
  data: {
    address1: "528 Old Weston Road",
    address2: "Apartment 201",
    city: "Toronto",
    company: "Eliteweb Inc",
    country: "Canada",
    countryCode: "CA",
    firstName: "Sandrine",
    lastName: "Voisin",
    name: "Sandrine Voisin",
    phone: "416 684 1787",
    province: "Ontario",
    provinceCode: "ON",
    zip: "M6N 3B1",
  },
})

リクエスト

キー タイプ 説明
index Number 更新するアドレスのインデックスです。
data Address 更新するアドレスのフィールドです。

お客様の削除

グループ Cart
アクション REMOVE_CUSTOMER
アクションの種類 APP::CART::REMOVE_CUSTOMER
説明 現在のカートから顧客を削除します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] removeCustomer", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.REMOVE_CUSTOMER)

割引設定

グループ Cart
アクション SET_DISCOUNT
アクションの種類 APP::CART::SET_DISCOUNT
説明 現在のカートに割引を設定します。

カート全体に割引を適用すると、すべてのラインアイテムに影響します。割引にはいくつかの種類があります。それぞれのタイプの例については、以下を参照してください。

定額割引:

var discountPayload = {
  amount: 1,
  discountDescription: "1ドルオフの割引"type: 'flat',
}

割引の割合:

var discountPayload = {
  amount: 0.5,
  discountDescription: "50%オフの割引 ",
  type: "percent",
}

割引コード discount:

var discountPayload = {
  discountDescription: "Holiday Sale",
  discountCode: "holidaysale50",
}
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] setDiscount", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.SET_DISCOUNT, {
  data: discountPayload,
})

割引額ペイロード

キー タイプ 説明
amount Number カートの小計に適用される割引額を、フラット値または合計パーセンテージ割引として指定します。フラット割引額は 0 より大きくなければなりません。カートの小計より大きい割引は、小計の金額まで減額されます。パーセンテージ割引額は 0.0 から 1.0 の間でなければなりません。
discountDescription String? 適用される割引の説明です。指定されていない場合は、デフォルトで Discount となります。
type String? 割引のタイプ。オプションはフラットまたはパーセンテージです。入力されていない場合は、flat がデフォルトです。

割引コードのペイロード

キー タイプ 説明
discountCode String 現在のカートに適用される割引コードです。

リクエスト

キー タイプ 説明
data DiscountAmount | DiscountCode 現在のカートに適用する割引のタイプ。

割引の解除

グループ Cart
アクション REMOVE_DISCOUNT
アクションの種類 APP::CART::REMOVE_DISCOUNT
説明 現在のカートから割引を削除します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] removeDiscount", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.REMOVE_DISCOUNT)

カートのプロパティを設定する

グループ Cart
アクション SET_PROPERTIES
アクションの種類 APP::CART::SET_PROPERTIES
説明 現在のカートに追加のプロパティを追加します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] setProperties", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.SET_PROPERTIES, {
  data: {
    referral: "Shopify",
    userID: "1234",
  },
})

リクエスト

キー タイプ 説明
data Object 現在のカートに追加するプロパティのキーと値のペアです。

カートのプロパティを削除する

グループ カート
アクション REMOVE_PROPERTIES
アクションの種類 APP::CART::REMOVE_PROPERTIES
説明 現在のカートから 1 つ以上のプロパティを削除します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] removeProperties", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.REMOVE_PROPERTIES, {
  data: ["referral", "userID"],
})

リクエスト

キー タイプ 説明
data Array[String] 現在のカートから削除するプロパティのリストです。

ラインアイテムの追加

グループ カート
アクション ADD_LINE_ITEM
アクションの種類 APP::CART::ADD_LINE_ITEM
説明 新しいラインアイテムを現在のカートに追加します。

ラインアイテムは 2 つの異なる方法でカートに追加することができます:商品のバリエーションとして、またはクイックセールアイテムとして(通常、バリエーションでバックアップされていない商品の単発販売に使用されます)。

クイックセールのラインアイテム:

var lineItemPayload = {
  price: 20,
  quantity: 1,
  title: "Bab Low - Blue Jay // White Soles",
  taxable: true,
}

バリエーションラインアイテム:

var lineItemPayload = {
  variantId: 1234,
  quantity: 1,
}
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] addLineItem", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.ADD_LINE_ITEM, {
  data: lineItemPayload,
})

ラインアイテムのペイロード

キー タイプ 説明
price Number? ラインアイテムの価格です。variantIdが提供されていない場合は必須です。0以上の値でなければなりません。
Quantity Number 追加するアイテムの量です。入力されていない場合、デフォルトは1です。0以上の値でなければなりません。
title String? 商品名。指定がない場合は "Quick sale"がデフォルトとなります。
variantId Number? 追加されるバリアントのユニークな ID です。入力されていない場合、商品はカスタムセールとみなされます。
discount DiscountAmount? ラインアイテムに適用する割引額。
taxable Boolean? ラインアイテムがカートの税金を変更するかどうかを示すフラグです。指定されていない場合、デフォルトはtrueです。カスタムセールアイテムにのみ設定可能です。

リクエスト

キー タイプ 説明
data LineItem 現在のカートに新しいラインアイテムを作成するためのデータです。

ラインアイテムの更新

グループ カート
アクション UPDATE_LINE_ITEM
アクションタイプ APP::CART::UPDATE_LINE_ITEM
説明 カート内の既存のラインアイテムの数量を更新します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] updateLineItem", paylkoad)
  unsubscriber()
})
cart.dispatch(Cart.Action.UPDATE_LINE_ITEM, {
  index: 0,
  data: {
    quantity: 100,
  },
})

ラインアイテム更新のペイロード

キー タイプ 説明
quantity Number 追加するアイテムの量。0より大きい値でなければなりません。

リクエスト

キー タイプ 説明
index Number 更新するラインアイテムのインデックス
data Line Item Update 指定されたインデックスのラインアイテムを更新するためのデータです。

ラインアイテムの削除

グループ カート
アクション REMOVE_LINE_ITEM
アクションの種類 APP::CART::REMOVE_LINE_ITEM
説明 既存のラインアイテムをカートから削除します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] removeLineItem", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.REMOVE_LINE_ITEM, {
  index: 0,
})

リクエスト

キー タイプ 説明
index Number 削除するラインアイテムのインデックスです。

ラインアイテムの割引設定

グループ カート
アクション SET_LINE_ITEM_DISCOUNT
アクションの種類 APP::CART::SET_LINE_ITEM_DISCOUNT
説明 現在のカート内のラインアイテムの割引を設定します。

カートの割引とは異なり、ラインアイテムの割引には割引コードを使用できません。一律割引とパーセント割引のみサポートしています。

一律値引き:

var discountPayload = {
  amount: 1,
  discountDescription: "1ドルオフの割引",
  type: "flat",
}

割引の割合:

var discountPayload = {
  amount: 0.5,
  discountDescription: "50%オフの割引 ",
  type: "percent",
}
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] setLineItemDiscount", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.SET_LINE_ITEM_DISCOUNT, {
  index: 0,
  data: discountPayload,
})

リクエスト

キー タイプ 説明
index Number 割引を適用するラインアイテムのインデックス。
data DiscountAmount ラインアイテムに適用する割引額。

ラインアイテム割引の削除

グループ Cart
アクション REMOVE_LINE_ITEM_DISCOUNT
アクションの種類 APP::CART::REMOVE_LINE_ITEM_DISCOUNT
説明 現在のカート内のラインアイテムの割引を削除します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] removeLineItemDiscount", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.REMOVE_LINE_ITEM_DISCOUNT, {
  index: 0,
})

リクエスト

キー タイプ 説明
index Number 割引を適用しないラインアイテムのインデックスです。

ラインアイテムのプロパティの設定

グループ カート
アクション SET_LINE_ITEM_PROPERTIES
アクションの種類 APP::CART::SET_LINE_ITEM_PROPERTIES
説明 現在のカート内の指定されたラインアイテムに、プロパティを追加します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] setLineItemProperties", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.SET_LINE_ITEM_PROPERTIES, {
  index: 0,
  data: {
    referral: "Shopify",
    userID: "1234",
  },
})

リクエスト

キー タイプ 説明
data Object 指定されたラインアイテムに追加するプロパティのキーと値のペアです。

ラインアイテムのプロパティの削除

グループ Cart
アクション REMOVE_LINE_ITEM_PROPERTIES
アクションの種類 APP::CART::REMOVE_LINE_ITEM_PROPERTIES
説明 現在のカート内の指定されたラインアイテムからプロパティを削除します。

プロパティを削除する際には、プロパティのキーを参照します。上記のカートに設定されたプロパティのキーは、referraluserIDでした。これらの値のいずれかを渡すことで、プロパティを削除することができます。

var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] removeLineItemProperties", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.REMOVE_LINE_ITEM_PROPERTIES, {
  index: 0,
  data: ["referral", "userID"],
})

リクエスト

キー タイプ 説明
index Number プロパティを削除する行アイテムのインデックス。
data Array[String] 指定されたラインアイテムから削除するプロパティのリストです。

カートのクリア

グループ カート
アクション CLEAR
アクションタイプ APP::CART::CLEAR
説明 現在のカートからすべてのラインアイテムを削除します。
var unsubscriber = cart.subscribe(Cart.Action.UPDATE, function (payload) {
  console.log("[Client] clear", payload)
  unsubscriber()
})
cart.dispatch(Cart.Action.Clear)

Contextual Save Bar

コンテクストセーブバーは、マーチャントがページ上のフォームに変更を加えた際に、そのオプションを伝えるものです。このコンポーネントは、商品や顧客などの新しいオブジェクトを作成する際にも表示されます。マーチャントはこのコンポーネントを使用して、作業を保存または破棄することができます。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからContextualSaveBarモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照することに注意してください。

import createApp from "@shopify/app-bridge"
import { ContextualSaveBar } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

作成と表示

コンテキストの保存バーを生成し、表示させます。

const options = {
  saveAction: {
    disabled: false,
    loading: false,
  },
  discardAction: {
    disabled: false,
    loading: false,
    discardConfirmationModal: true,
  },
}
const contextualSaveBar = ContextualSaveBar.create(app, options)

contextualSaveBar.dispatch(ContextualSaveBar.Action.SHOW)

オプションの更新

オプションはいつでも変更できます。コンテクストセーブバーが表示されている場合は、すぐに UI が更新されます。

contextualSaveBar.set({ discardAction: { discardConfirmation: false } })

Hide

コンテクストセーブバーを非表示にしたいときに、非表示アクションをディスパッチします。

contextualSaveBar.dispatch(ContextualSaveBar.Action.HIDE)

破棄と保存をサブスクライブする

コンテクストセーブバーのアクション(ContextualSaveBar.Action.DISCARDContextualSaveBar.Action.SAVE)は、subscribeを呼び出すことでサブスクライブできます。subscribe メソッドは、アクションの登録を解除するために呼び出すことができるメソッドを返します。

コンテクストセーブバーを非表示にするには、subscribe コールバックでContextualSaveBar.Action.HIDEアクションをディスパッチします。

const discardUnsubscribe = contextualSaveBar.subscribe(
  ContextualSaveBar.Action.DISCARD,
  function () {
    // コンテクストセーブバーを隠す
    contextualSaveBar.dispatch(ContextualSaveBar.Action.HIDE)
    // 廃棄アクションで何かをする
  }
)

const saveUnsubscribe = contextualSaveBar.subscribe(ContextualSaveBar.Action.SAVE, function () {
  // オプションで、保存アクションが進行中の間、ローディングスピナーを表示する
  contextualSaveBar.set({ saveAction: { loading: true } })
  await doSaveAction()

  // コンテクストセーブバーを隠す
  contextualSaveBar.dispatch(ContextualSaveBar.Action.HIDE)
})

// 登録解除
discardUnsubscribe()
saveUnsubscribe()

Unsbscribe

コンテクストの保存バーで現在のサブスクライブをすべて削除するには、unsubscribe を呼び出します。

contextualSaveBar.subscribe(ContextualSaveBar.Action.DISCARD, function () {
  // discard アクションで何かをする
  // コンテクストセーブバーを隠す
  contextualSaveBar.dispatch(ContextualSaveBar.Action.HIDE)
})

contextualSaveBar.subscribe(ContextualSaveBar.Action.SAVE, function () {
  // 保存アクションで何かを行う
  // コンテクストセーブバーを隠す
  contextualSaveBar.dispatch(ContextualSaveBar.Action.HIDE)
})

// 登録解除
contextualSaveBar.unsubscribe()

Error

他のアクションタイプと同様に、ランタイムエラーをサブスクライブすることができます。エラーアクションは、アクションがディスパッチされた後に非同期的に発生する可能性があるため、アプリのエラーをサブスクライブすることをお勧めします。エラーハンドラが定義されていない場合、エラーはコンソールにスローされます。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからErrorモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照していることに注意してください。

import createApp from "@shopify/app-bridge"
import { Error } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

アプリですべてのエラーを subscribe する

app.errorメソッドを呼び出すと、アクションによって発生したエラーを含むすべてのエラーを subscribe できます。app.errorをコールすると、すべてのエラーの subscribe を解除するためのメソッドが返されます。

const unsubscribe = app.error((data) => {
  // type にはエラーの種類が入ります
  // action には、元のアクションとその ID が入ります。
  // message は、エラーを修正するための追加のヒントを含みます
  const {type, action, message} = data;
  // すべてのエラーをここで処理します
  switch(type) {
     case Error.Action.INVALID_PAYLOAD:
     //このエラーに対して何かを行う
     break;
  }
 }
});

// すべてのエラーから配信を停止する
unsubscribe();

特定のエラーを subscribe する

特定のエラータイプを指定して app.subscribe を呼び出すと、そのエラータイプだけをサブスクライブすることができます。

const unsubscribe = app.subscribe(Error.Action.INVALID_ACTION, (data) => {
  // そのエラーに対して何かを行います
})

// エラーのサブスクライブを解除する
unsubscribe()

あるアクションセットのすべてのエラーを subscribe する

任意のアクションセットの error メソッドを呼び出し、そのアクションセットに関連するすべてのエラーをサブスクライブします。

import {Modal} from '@shopify/app-bridge/actions';

const modalOptions = {
  message: 'Hello World',
};
const modal = Modal.create(app, modalOptions);

const unsubscribe = modal.error((data) => {
  // type にはエラータイプが入ります。
  // action には、元のアクションとその ID が入ります。
  // message は、エラーを修正するための追加のヒントを含みます。
  const {type, action, message} = data;
  // すべてのエラーをここで処理します
  switch(type) {
     case Error.Action.UNEXPECTED_ACTION:
     //エラーに対して何かを行う
     break;
  }
 }
});
// 開かれていないモーダルを更新することで、UNEXPECTED_ACTIONエラーを発生させる
modal.set({title: 'Greeting'});

// このフラッシュに関連するすべてのエラーの配信を停止する
unsubscribe();

アクションセットの特定のエラーをサブスクライブする

import {Modal} from '@shopify/app-bridge/actions';

const modalOptions = {
  message: 'Hello World',
};
const modal = Modal.create(app, modalOptions);

const unsubscribe = modal.subscribe(Error.Action.UNEXPECTED_ACTION, (data) => {
  // type にはエラータイプが入ります
  // action には、元のアクションとその ID が入ります。
  // message は、エラーを修正するための追加のヒントを含みます。
  const {type, action, message} = data;
  // ここでエラーを処理します
 }
});

// 開かれていないモーダルを更新することで、UNEXPECTED_ACTIONエラーを発生させる
modal.set({title: 'Greeting'});

// このフラッシュに関連するUNEXPECTED_ACTIONエラーの配信を停止する
unsubscribe();

Features

Featuresアクションセットでは、現在のアプリのコンテキストで利用可能な機能を確認したり、現在利用できない機能をリクエストすることができます。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからFeaturesモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照していることに注意してください。

import createApp from "@shopify/app-bridge"
import { Features, Group, Scanner } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

Features のアップデートを subscribe する

app.subscribe(Features.Action.UPDATE, function () {
  // このコールバックは、ある機能の可用性が変更されたことを通知します。
  // 変更されたことを通知します。
  // 利用可能な機能をすべて取得するには、`app.featuresAvailable()`を呼び出してください。
})
App.featuresAvailable()

App.featuresAvailable()

app.featuresAvailable()を呼び出すと、アプリで利用可能な機能の全セットに対して評価されるプロミスが返されます。機能セットは、グループ、各グループ内のアクション、各アクションのパーミッション(DispatchSubscribe)を含むオブジェクトとして表されます。

Dispatchtrueの場合、アプリ内でそのタイプのアクションを送信することが可能になります。同様に、Subscribetrueであれば、そのタイプのアクションのディスパッチをサブスクライブできます。

状態にグループが存在しない場合は、そのグループに含まれるすべてのアクションも利用できないと考えられます。

app.featuresAvailable().then(function (state) {
  /* すべてのアクションは、stateオブジェクトの中にあります。
  {
    Cart: {...},
    Button: {...},
    Modal: {...},
    ...
    Scanner: {...},
    Share: {...}
  } */
})

結果として得られる状態をグループのサブセットに限定したい場合は、グループ・パラメータを渡します。

app.featuresAvailable(Group.Cart).then(function (state) {
  // 状態にはCartのアクションのみが含まれます
  /*
  {
    Cart: {
      FETCH: {
        Dispatch: false
        Subscribe: false
      },
      remove_line_item_properties: {
        Dispatch: false
        Subscribe: false
      }
      ...
    }
  } */
})

...restパラメータを使うことで、複数のグループフィルタにも対応しています。

app.featuresAvailable(Group.Cart, Group.Button, Group.Modal).then(function (state) {
  // stateには、Cart、Button、Modalのアクションのみが含まれます。
  /*
  {
    Cart: {...},
    Button: {...},
    Modal: {...}.
  } */
})

カート

Point of Sale の Cart アクションにアクセスしようとすると、機能利用可能エラーが発生する場合は、そのコードをFeatures.Action.UPDATEのサブスクリプションでラップしてみてください。

// 機能更新アクションをできるだけ早くsubscribeする
const unsubscribe = app.subscribe(Features.Action.UPDATE, function () {
  app.featuresAvailable(Group.Cart).then((features) => {
    const hasFetchCart = features.Cart[Cart.Action.FETCH]
    if (hasFetchCart) {
      unsubscribe()
      // 何かをする
    }
  })
})

Features Update アクション

グループ 機能
アクション UPDATE
アクションタイプ APP::FEATURES::UPDATE
説明 機能の利用可能な状態が変化したときにディスパッチします。

レスポンス

キー タイプ 説明
Main Object メインコンテキストにおける機能の利用可能状態です。
Modal Object モーダルコンテキスト内の機能の利用可能状態です。

Features Request アクション

グループ 機能
アクション REQUEST
アクションタイプ APP::FEATURES::REQUEST
説明 機能の有効化を要求します。ディスパッチされるプラットフォームによっては、認証ダイアログが表示されることがあります。

app.featuresAvailable()を呼び出したときにアクションが利用できない場合、APP::FEATURES::REQUESTアクションを使用して、アクションのグループまたはグループ内の単一のアクションを有効にするよう要求することができます。これは、アプリがモバイルデバイス上で実行されていて、ユーザーの承認が必要なスキャナなどのハードウェア機能を要求する場合に特に便利です。

機能を有効にするためのワークフローには、APP::FEATURES::REQUEST::UPDATEのサブスクライブとAPP::FEATURES::REQUESTのディスパッチという 2 つの部分があります。APP::FEATURES::REQUESTは入力で、APP::FEATURES::REQUEST::UPDATEは出力です。

カメラスキャナのアクションを要求する:

var features = Features.create(app)
features.subscribe(Features.Action.REQUEST_UPDATE, function (payload) {
  if (payload.feature[Scanner.Action.OPEN_CAMERA]) {
    var Dispatch = payload.feature[Scanner.Action.OPEN_CAMERA].Dispatch
    console.log("Camera Scanner has been ".concat(Dispatch ? "enabled" : "disabled"))
  }
})
features.dispatch(Features.Action.REQUEST, {
  feature: Group.Scanner,
  action: Scanner.Action.OPEN_CAMERA,
})

リクエスト

キー タイプ 説明
feature String 有効にしたい機能グループです。
action String? 有効にするグループ内の任意のアクション。アクションが指定されていない場合は、グループ内のすべてのアクションが有効になります。

Features Request Update アクション

グループ 機能
アクション UPDATE
アクションタイプ APP::FEATURES::UPDATE
説明 機能要求アクションの結果を処理します。

レスポンス

キー タイプ 説明
feature Object 要求された機能の新しい状態です。

アプリケーションのコンテキスト

Shopify App Bridge のアプリケーションは様々な場所で開くことができます。それぞれの場所をコンテキストと呼んでいます。各コンテキストは、アプリケーションが利用できる機能のセットを提供します。異なるコンテキストは異なる機能セットを提供できます。

例えば、Modalコンテキストは、Mainコンテキストとは異なる機能セットを利用できます。

アプリケーションがどのコンテキストにあるかを確認するには、app.getState()を使用します。app.getState についてもっと読む。

app.getState("context").then(function (context) {
  console.log("Context is: ", context) // Context is: Main
})

Loading

ローディングアクションセットは、マーチャントにページの読み込み中やアップロードの処理中を示すために使用されます。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからLoadingモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照することに注意してください。

import createApp from "@shopify/app-bridge"
import { Loading } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

const loading = Loading.create(app)

ローディングの開始

新しいページをロードするときや、数秒以上かかる可能性のある非同期リクエストを完了するときに、START loading アクションを呼び出します。

loading.dispatch(Loading.Action.START)

読み込み停止

読み込みアクションが完了したら、STOP読み込みアクションをディスパッチします。

loading.dispatch(Loading.Action.STOP)

アクションのサブスクライブ

ローディングアクションセットを通じてディスパッチされたアクションをサブスクライブできます。

loading.subscribe(Loading.Action.START, () => {
  // ローディングが始まったら何かをする
})

loading.subscribe(Loading.Action.STOP, () => {
  // 読み込みが止まったら何かする
})

すべてのアクションのサブスクライブ

どのアクションセットがアクションを引き起こすかに関わらず、すべてのローディングアクションをサブスクライブすることができます。

app.subscribe(Loading.Action.START, () => {
  // 読み込みが始まったら何かする
})

app.subscribe(Loading.Action.STOP, () => {
  // 読み込み停止時に何かをする
})

Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

https://apps.shopify.com/shopify-application-314?locale=ja&from=daniel

Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。

https://apps.shopify.com/font-picker-1?locale=ja&from=daniel

Discussion

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