💳

【Shopify.dev和訳】Apps/Checkout/Shipping methods/ExampleScripts

2021/09/12に公開約11,600字

この記事について

この記事は、Apps/Checkout/Shipping methods/Example scriptsの記事を和訳したものです。

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

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

配送方法のサンプルスクリプト | Shipping methods example scripts

このガイドでは、shipping methods APIを実装した一連のスクリプト例を紹介します。


コンフィグレーションに基づいて配送方法をフィルタリング | Filter shipping methods based on configuration

このスクリプトは、以下の両方の条件が満たされたときに配送方法をフィルタリングします。

  • 配送方法の名前が設定の shippingMethodName フィールドと一致する、またはフィールドがコンフィグレーションに設定されていない場合は Unknown です。

  • チェックアウト(購入提案)の合計金額がコンフィグレーションからの閾値フィールドよりも大きい(CAD)、またはフィールドがコンフィグレーションに設定されていない場合は 100.00CAD ドルである。

src/script.ts
import {
  ShippingMethods,
  CheckoutDomain as Domain,
  Configuration,
  Console,
  Currencies,
  Money,
  safeParseInt,
} from '@shopify/scripts-checkout-apis';

export function shippingMethodsHandler(
  input: ShippingMethods.Input,
  configuration: Configuration,
): ShippingMethods.Result {
  // スクリプトの出力を表示するには、`Console.log`を使います。
  Console.log('Hello! This is a log from your script!');

  const filterResponse = filter(input.purchaseProposal, input.shippingMethods, configuration);

  // レスポンス配列に何も返さなければ、チェックアウトに影響はありません。
  return new ShippingMethods.Result(
    new ShippingMethods.SortResponse([]),
    filterResponse,
    new ShippingMethods.RenameResponse([]),
  );
}

function filter(
  purchaseProposal: Domain.PurchaseProposal,
  shippingMethods: Domain.ShippingMethod[],
  configuration: Configuration,
): ShippingMethods.FilterResponse {
  var hiddenMethods = new Array<Domain.ShippingMethod>();

  for (let i = 0; i < shippingMethods.length; i++) {
    const shippingMethod = shippingMethods[i];

    if (shouldHide(purchaseProposal, shippingMethod, configuration)) {
      hiddenMethods.push(shippingMethod);
    }
  }

  return new ShippingMethods.FilterResponse(hiddenMethods);
}

function shouldHide(
  purchaseProposal: Domain.PurchaseProposal,
  shippingMethod: Domain.ShippingMethod,
  configuration: Configuration,
): bool {
  const nameMatches = nameConfiguration(configuration) == shippingMethod.title;
  const aboveThreshold = purchaseProposal.totalPrice() > thresholdConfiguration(configuration);

  return nameMatches && aboveThreshold;
}

function nameConfiguration(configuration: Configuration): string {
  const defaultNameFilter = 'Unknown';
  return configuration.exists('shippingMethodName') ? configuration.get('shippingMethodName')! : defaultNameFilter;
}

function thresholdConfiguration(configuration: Configuration): Money {
  const defaultThreshold = (100).toString();
  const threshold = <f64>(
    safeParseInt(configuration.exists('threshold') ? configuration.get('threshold')! : defaultThreshold)
  );

  return Money.fromAmount(threshold, Currencies.CAD);
}

最初の配送方法の名称変更 | Rename first shipping method

このスクリプトは、1 つ以上の配送方法がある場合、最初の配送方法の名前を Rename Shipping Method!に変更します。

src/script.ts
import {CheckoutDomain as Domain, ShippingMethods, Configuration, Console} from '@shopify/scripts-checkout-apis';

export function shippingMethodsHandler(
  input: ShippingMethods.Input,
  // eslint-disable-next-line @shopify/assemblyscript/no-unused-vars
  _configuration: Configuration,
): ShippingMethods.Result {
  // スクリプトの出力を表示するには、`Console.log`を使います。
  Console.log('Hello! This is a log from your script!');

  const renameResponse = renameFirstShippingMethod(input.shippingMethods);

  // レスポンス配列に何も返さなければ、チェックアウトに影響はありません。
  return new ShippingMethods.Result(
    new ShippingMethods.SortResponse([]),
    new ShippingMethods.FilterResponse([]),
    renameResponse,
  );
}

function renameFirstShippingMethod(shippingMethods: Domain.ShippingMethod[]): ShippingMethods.RenameResponse {
  var renameProposals = new Array<ShippingMethods.RenameProposal>();

  if (shippingMethods.length > 0) {
    const renameProposal = ShippingMethods.RenameProposal.rename(shippingMethods[0], 'Renamed Shipping Method!');
    renameProposals.push(renameProposal);
  }

  return new ShippingMethods.RenameResponse(renameProposals);
}

配送方法のソート | Sort shipping methods

このスクリプトは、配送方法を名前でソートします。

  • 何のコンフィグレーションも提供されていない場合は、配送方法は昇順でソートされます。

  • コンフィグレーションで sortDirection フィールドが ascending に設定されている場合、配送方法は昇順にソートされます。

  • コンフィグレーションで sortDirection フィールドが descending に設定されている場合、配送方法は降順でソートされます。

  • コンフィグレーションで sortDirection フィールドがそれ以外に設定されている場合、スクリプトはエラーを発生させます。

src/script.ts
import {ShippingMethods, CheckoutDomain as Domain, Configuration, Console} from '@shopify/scripts-checkout-apis';

// 定数をファイルの先頭に抽出しておくと、参照や書き出しに便利です。
const ASC = 'ascending';
const DESC = 'descending';
const DEFAULT = ASC;

export function shippingMethodsHandler(
  input: ShippingMethods.Input,
  configuration: Configuration,
): ShippingMethods.Result {
  // スクリプトの出力を表示するには、`Console.log`を使います。
  Console.log('Hello! This is a log from your script!');

  const sortResponse = sort(input.purchaseProposal, input.shippingMethods, configuration);

  // レスポンス配列に何も返さなければ、チェックアウトに影響はありません。
  return new ShippingMethods.Result(
    sortResponse,
    new ShippingMethods.FilterResponse([]),
    new ShippingMethods.RenameResponse([]),
  );
}

function sort(
  purchaseProposal: Domain.PurchaseProposal,
  shippingMethods: Domain.ShippingMethod[],
  configuration: Configuration,
): ShippingMethods.SortResponse {
  return new ShippingMethods.ContextualQuickSort(purchaseProposal, shippingMethods, configuration).sort(
    (context: ShippingMethods.ShippingMethodContext, lhs: Domain.ShippingMethod, rhs: Domain.ShippingMethod) => {
      const sortDir = configuredSortDirection(context.configuration);
      const left = sortDir == ASC ? lhs : rhs;
      const right = sortDir == ASC ? rhs : lhs;

      return compareShippingMethods(context, left, right);
    },
  );
}

function compareShippingMethods(
  context: ShippingMethods.ShippingMethodContext,
  lhs: Domain.ShippingMethod,
  rhs: Domain.ShippingMethod,
): ShippingMethods.Comparator {
  return lhs.title.localeCompare(<string>rhs.title);
}

function configuredSortDirection(configuration: Configuration): string {
  // Configurationオブジェクトから期待される値を検証するのは良いアイデアです。
  // 値が提供されていない場合にはデフォルト値を提供し、
  // 値がない場合や予期しないタイプの場合にはエラーを発生させるようにすることができます。
  if (configuration.exists('sortDirection')) {
    // "!"は、この値がnullではないことをコンパイラに伝えるものです。
    const sortDirection = configuration.get('sortDirection')!;
    if (sortDirection == ASC || sortDirection == DESC) {
      return sortDirection;
    } else {
      throw 'sortDirection must be either ascending or descending!';
    }
  } else {
    return DEFAULT;
  }
}

メッセージの追加 | Add a message

これは、複雑で高度なスクリプトです。コンフィグレーションリストを使用し、マーチャントがスクリプトをカスタマイズできるようになっています。設定リストの各項目には、以下のフィールドが含まれています。

  • provinceCodes: 2 桁の州コードのコンマ区切りリスト。

  • provinceCodeMatchType: 有効な値: AllIncludeExcludeのいずれか。

  • countryCode: 2 桁の国コード。

  • message: 文字列。

スクリプトは、すべてのコンフィグレーションリストのアイテムを繰り返し検索し、countryCode が購入提案書の国コードと一致し、購入提案書の都道府県コードが provincialCodeMatchType に基づく provincialCode と一致するものを探します。一致するものが見つかった場合、すべての配送オプションの名前の最後にメッセージが追加され、セパレーターとしてダッシュ(-)が付けられます。

src/script.ts
import {ShippingMethods, Configuration, ConfigurationList} from '@shopify/scripts-checkout-apis';

function renameShippingMethods(
  input: ShippingMethods.Input,
  configuration: Configuration,
): ShippingMethods.RenameResponse {
  const renameProposals = new Array<ShippingMethods.RenameProposal>();

  const configurationList = new ConfigurationList(configuration);

  const address = input.purchaseProposal.deliveryLines[0].destination;

  // 配送方法名に付加されるメッセージが初期値ではnull
  let message: string | null = null;

  // コンフィグレーションリストの全項目を参照して、マッチする項目があるかどうかを確認
  for (let i = 0; i < configurationList.length; i++) {
    const configurationListItem = configurationList[i];

    const provinceCodesRaw: string | null = configurationListItem.get('provinceCodes');
    const provinceCodes: Array<string> =
      provinceCodesRaw !== null && provinceCodesRaw.length > 0
        ? provinceCodesRaw.split(',').map<string>((pc: string) => pc.trim())
        : [];
    const countryCode: string | null = configurationListItem.get('countryCode');
    const provinceCodeMatchType: string | null = configurationListItem.get('provinceCodeMatchType');

    // 一致した場合、メッセージを更新してループから抜ける
    if (
      address.countryCode == countryCode &&
      (provinceCodeMatchType == 'All' ||
        (provinceCodeMatchType == 'Include' && provinceCodes.includes(address.provinceCode)) ||
        (provinceCodeMatchType == 'Exclude' && !provinceCodes.includes(address.provinceCode)))
    ) {
      const messageFromConfig: string | null = configurationListItem.get('message');
      // メッセージがNULLまたは空の文字列でないことを確認
      if (messageFromConfig !== null && messageFromConfig.length > 0) {
        message = configurationListItem.get('message')!;
        break;
      }
    }
  }

  const shippingMethods = input.shippingMethods;

  // メッセージが設定されていた場合、すべての配送方法の名前を変更し、メッセージを追加
  if (message !== null) {
    for (let i = 0; i < shippingMethods.length; i++) {
      const renameTo = shippingMethods[i].title + ' - ' + message;
      const renameProposal = ShippingMethods.RenameProposal.rename(shippingMethods[i], renameTo);
      renameProposals.push(renameProposal);
    }
  }

  return new ShippingMethods.RenameResponse(renameProposals);
}

export function shippingMethodsHandler(
  input: ShippingMethods.Input,
  configuration: Configuration,
): ShippingMethods.Result {
  const sortResponse = new ShippingMethods.SortResponse(input.shippingMethods);
  const filterResponse = new ShippingMethods.FilterResponse([]);
  const renameResponse = renameShippingMethods(input, configuration);

  return new ShippingMethods.Result(sortResponse, filterResponse, renameResponse);
}

設定例

国コード CA、州コード ON の注文があり、コンフィグレーションには以下の項目が含まれています:

{
  "provinceCodes": "SK", "MB"
  "provinceCodeMatchType": "Exclude",
  "countryCode": "CA",
  "message": "Not destined for the prairies"
}

各配送方法の名前には、" - Not destined for the prairies"が付加されます。

同様に、国コードが US、州コードが NY の注文があり、コンフィグレーションには以下の項目が含まれています:

{
  "provinceCodes": "",
  "provinceCodeMatchType": "All",
  "countryCode": "US",
  "message": "Destined for the USA"
}

各配送方法の名称には、"- Destined for the USA" が付加されています。


次のステップ | Next steps

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

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