Figma 新機能「開発モード」の利用

最近デザインツールの「Figma」を使用する機会が増え、便利だなと思いながら日々活用しています。
Figma Config 2023 では、「開発モード - Developer Mode」という新機能が発表され、ベータ版で2023年まで無料で使用できるものとして公開されました。
実装側のエンジニアなどが、デザインデータからデザインの詳細やコードの確認をすることがより便利になった実装に特化したモードです。

Config 2023の最新情報: 開発モード、バリアブル、高度なプロトタイプ作成機能など

デザインからプロトタイプ作成、構築まで、チームの最高のアイデアを前進させる機能をご紹介します。

Figmaの新しいスペースである開発モードにより、開発作業がより容易になり、デザインから製品化までを迅速化できます。
現時点で開発モードはベータ版であり、2023年中はすべてのユーザーが無料で使用できます。

figma リリースノート - https://www.figma.com/ja/release-notes/

今回は以下の公式のチュートリアルを参照して機能を確認しています。
● 「Dev Mode playground」 - Figma
https://www.figma.com/community/file/1234941143610339388

セクションの準備完了状態

デザインモード(従来のモード)で作成したデザインをセクションに入れ込むと、セクション名の右横に「開発準備完了」のステータスを付けることができるようになりました。

実装できる状態となったデザインデータをこのステータスにすることで、開発モードでの左サイドバーに「開発準備完了」のセクションとした画面、つまり開発に必要な画面だけを参照できます。

共同作業が行えることによりデザインデータ上でデザインの変更などを検討していると、それが検討中なのか完成したものなのか実装側は分からないため、これまではラベルの自作等していましたが、この機能を使えば簡単に明確になります。

インスペクトパネル

開発モードでは、マウスオーバーだけでスペーシングを確認できます。これまでコンポーネントをクリックしたりキーを押しながらでないと確認できなかったので、この開発モードを使用することによってより簡単に確認ができるようになりました。
開発モードでの確認時はデザインデータを変更できないようになっているので、不意の操作で変更を加えてしてしまうということもありません。

右サイドバーではブラウザのデベロッパーツールのような形で、クリックされた要素についてCSSなどのコードでスタイルを参照できます。iOS、Android用のコードスニペットの生成も可能です。

また、コンポーネントのプレイグラウンドもあるので、設定されているプロパティの確認ができます。この変更はデザインに反映されないため、それぞれのバリアントについてトグルスイッチで自由に変更しながら、いろいろなパターンのデザインや動作の確認ができます。テキスト要素があれば、そのテキストを変更して確認も可能です。

画面単位での変更履歴

フレームを選択し、右サイドバーの「変更履歴」から、その変更内容を見ることができます。
デフォルトの「並べて表示」では、左の履歴一覧で選択したバージョンのものを左側に表示し、右側には最新バージョンが表示されるので、比較しながら変更点を確認できます。

また、下部には編集したレイヤー単位の変更内容が表示され、レイヤー名をクリックするとハイライトされるので、具体的にどこがどう変化したのかがすぐにわかります。

Visual Studio Code 連携

VS Codeに拡張機能「Figma for VS Code」をインストールすると、VS Code上でFigmaのデザインファイルの確認ができたり、コメントや変更履歴をリアルタイムで追跡できます。
画面を切り替える必要がないため、コーディング途中での変更やコメントにもすぐに気づけそうです。

動作は開発モードと同様で、マウスオーバーやクリックで要素の詳細を見ることができます。(VS Code上で開くことができるのは開発モードのみ)

おわりに

最近はもっぱらデザインデータを作る側の立場ですが、実際に開発モードの利用によって実装側のエンジニアとのコミュニケーションコストは下がっていると実感しています。
特に、デザインの変更点があったときに特別複雑なものでなければ、実装側は開発モードで変更履歴をチェックして知ることができるので、これまで何か別の形で変更点の共有や説明を行うといったやりとりも減り、リアルタイムで変更を確認、反映してもらえる点が非常に便利に感じています。

開発モード画面も従来同様ある程度直感的に操作できますし、デザイナー側も最終チェックのような形で開発モードでデータを見てみたりすると、従来のモードでは見落としていた修正点なども発見できるのではないかという印象です。

ただ、デザインデータのセクションやフレームのタイトルがそのまま開発モードに反映されたり、作成したものがコードとして書き出されやすくなったことで、デザイナー側がデザインファイルの要素やレイヤーの中身をしっかりと整理することがより重要になると思いました。コンポーネントの作成や、適切なネーミング、セクショニングを行うことが求められるようになるので、実装側にデータを渡す際は改めて気をつける必要があります。

開発モード以外の新機能として、variablesモードや高度なプロトタイプ作成機能も実装されているとのことで、有料化となる前にこれらの新機能も順次試してみたいと思います。

  

class-validatorをカスタムする

npmのclass-validatorでカスタムバリデータを作ったので備忘録として残しておきます。ここではclass-validatorの詳細については触れませんので公式を参照してください。

class-validatorの使用例

下記のようにクラスのメンバーに対してデコレータを記述するだけでバリデーションが適用されます。記述されたデコレータのルールはすべてが判定の対象です。

import {
  IsEmail,
  IsNotEmpty,
  IsString,
  MinLength,
} from 'class-validator'

export class AuthDto {
  @IsEmail()        // メールアドレスの形式になっているか
  @IsNotEmpty()     // 値が入っているか(!== '', !== null, !== undefined)
  email: string

  @IsString()       // 文字列か
  @IsNotEmpty()     // 値が入っているか(!== '', !== null, !== undefined)
  @MinLength(8)     // 8文字以上になっているか
  password: string
}

カスタムバリデータの作成

漢字やカタカナ、携帯番号が0で始まるかなど最初からライブラリに用意がないものについてはカスタムバリデータを作成できます。下記は全角スペースを許可しないバリデータと半角スペースを許可しないバリデータです。

import { ValidateBy, ValidationOptions } from "class-validator"

export const isNotIncludeSpace = (validationOptions?: ValidationOptions): PropertyDecorator => {
  return ValidateBy (
    {
      // バリデータの名称
      name: 'isNotIncludeSpace',
      // バリデーションの内容
      validator: {
        validate(value): boolean {
          // 半角スペースを含むか
          return !value.includes(' ')
        }
      }
    },
    validationOptions,
  )
}

export const isNotIncludeZenkakuSpace = (validationOptions?: ValidationOptions): PropertyDecorator => {
  return ValidateBy (
    {
      name: 'isNotIncludeZenkakuSpace',
      validator: {
        validate(value): boolean {
          // 全角スペースを含むか
          return !value.includes(' ')
        }
      }
    },
    validationOptions,
  )
}

カスタムバリデータの利用

import {
  IsEmail,
  IsNotEmpty,
  IsString,
  MinLength,
} from 'class-validator'

// 作成したカスタムバリデータをインポート
import {
  isNotIncludeSpace,
  isNotIncludeZenkakuSpace,
} from 'helpers/customValidator'

export class AuthDto {
  @IsEmail()
  @IsNotEmpty()
  email: string

  @IsString()
  @IsNotEmpty()
  @MinLength(8)
  password: string

  @IsString()
  @IsNotEmpty()
  // messageプロパティでエラーの際に表示するメッセージを指定
  @isNotIncludeSpace({ message: '半角スペースは含めることができません' })           // 半角スペースのチェック
  @isNotIncludeZenkakuSpace({ message: '全角スペースは含めることができません' })    // 全角スペースのチェック
  nickname: string
}

まとめ

今回試しに使っただけなので半角スペースを判定するバリデータと全角スペースを判定するバリデータを作成しましたが、実際には半角スペースと全角スペースの判定であれば最初から用意されている

@NotContains

というデコレータで対応できると思います。

下記のようにvalidatorの中身を変更すれば全角カナや半角カナのチェックもできます。

{
  name: 'isZenkakuKana',
  validator: {
    validate(value): boolean {
      // 全角カナか
      return !!value.match(/^[ァ-ヶー ]*$/)
    }
  }
},
{
  name: 'isHankakuKana',
  validator: {
    validate(value): boolean {
      // 半角カナか
      return !!value.match(/^[ヲ-゚]*$/)
    }
  }
},

参考リンク

https://www.npmjs.com/package/class-validator

20周年記念クルージング

5月26日に当社グリニッジ株式会社は20周年を迎えました。
今回は20周年を記念して、先月開催したクルージングディナーの様子をお伝えします。

ちなみに15周年の時もクルージングディナーでした。
そちらの様子は下記よりご確認ください。

新橋駅で待ち合わせし、みんなでゆりかもめに乗り、日の出ふ頭へ。
大きな船を見るとワクワクしてしまうのは、なぜですかね?

まずはみんなでデッキに出て、シャンパンで乾杯!
天気にも恵まれて、まぶしかったです。

日の出桟橋を出航後、美味しい料理に心を弾ませながら、始めは恒例の席順クイズ。
何の規則性で並んでいるのか?
これまでの社内イベントでは、血液型や誕生日、入社順などがありました。

難易度を上げたのですが、気づく人は気づきますね。
今回は名前の総画数順で席順を決めました。最小が18画、最大が48画。
こんなにも差があることに驚きました!

食事の中盤からは、トランプをくじ引きの代わりにプレゼント交換タイム♪
もらう側はその場でプレゼントを開けて一言、送る側はなぜこのプレゼントにしたのか?を発表。
それぞれ思い思いのプレゼントで楽しい時間となりました!

最後は美味しいケーキを頬張りつつ、風船を膨らまして、集合写真撮影。
社員考案の『グリニッジポーズ』で撮影しました。
(グリニッジのロゴマークをイメージしたそうです。わかりますか笑)

全社員が揃って、楽しんだ1日。
20周年も、とても記憶に残るクルージングとなりました!

もちろん、二次会も大いに盛り上がりました!
オンラインではなく、久しぶりの対面は話が弾みます!

伝え方に工夫を!

私事ですが、グリニッジに中途入社して6年目に突入しました。
EC業界の知識や経験がない未経験からのスタートだったのですが、6年目にもなると業務の量と幅が増え、今では人事担当として、新卒・中途採用プロジェクトのリーダーという責任のあるポジションを任せてもらえるようになりました。

責任のあるポジションを任せてもらえるのは勉強にもなり、自分の経験や自信にもなりますが、時には自分よりも年上の方に指示したり、だいぶ歳の離れた年下の後輩に指導することもあり、

「どうすれば相手にこちらの意図がしっかり伝わるのか?」
「指導する側とされる側、どちらも気持ちよく仕事をするにはどうしたら良いのか?」
と指導方法や伝え方に悩むことがあります。

最近では、「これってパワハラ・セクハラになるのではないか…?」と指導方法や部下との接し方に悩む上司が増えていると耳にします。
また、テレワークする機会が増えたことによって、社内のコミュニケーションをうまく取ることができていないという悩みもあると思います。

そこで今回は、同僚や部下にどのような声掛けをすると良いのか、下記の参考書籍を読んで、そこから学んで自分でも気をつけるようにしていることをお伝えしたいと思います。
(こちらの書籍はリーダー向けの内容となっていますが、リーダーだけではなく、社内のコミュニケーションとしても参考になります!)

効果的なフィードバックの仕方

ポジティブ編
さらなるステップアップのために、能力ではなくプロセスを褒めましょう!

能力を褒めることは部下の承認欲求を満たすからいいと思うかもしれません。しかし能力を褒めるのは危険です。理由は2つあります。1点目はせっかく能力を認めてもらっているのだからと、部下が悪い報告を怠る可能性が出てくること。2点目は部下の成長を止めてしまうこと。

共感されるリーダーの声掛け 言い換え図鑑 吉田幸弘著

例えば「Aさんは能力が高いから期待しているよ。」ではなく、
「企画書いつも細かい分析まで載せてくれていて、本当助かるよ。」というように、
先天的能力よりも、努力やプロセスを褒めて、そのうえでさらにステップアップしてもらうために改善点も伝えるのがポイントです。

自分の努力を認めてもらえるだけではなく、どこが良かったのか具体的に言ってもらえると、「この人はちゃんと自分のことを見てくれているんだな。」と感じ、一緒に働くことに安心できますよね。
また、改善点などアドバイスをもらうことで次回に活かせますし、部下のスキルアップにもつながります。

ネガティブ編
部下のモチベーションを落とさずに指摘したい場合は、“叱ってから褒める”の順番にしましょう!

「大口顧客A社との契約も締結して素晴らしいね。ただ、ミスが増えてきているから注意して。」
「最近ミスが増えているから注意して。大口顧客A社との契約も締結して素晴らしいのだから。」
このように、褒められてから叱られると「ミスを注意して」という内容が頭の中に残ります。形式上褒めておいた感が強くなります。一方で、叱られてから褒められるとどうでしょうか。ミスを指摘されたけど、大口顧客受注を褒めてもらったという印象の方が強く残りませんか。

共感されるリーダーの声掛け 言い換え図鑑 吉田幸弘著

これは親近効果といって、最後の言葉の印象は強く残りやすいのだそうです。
リーダーや先輩として部下を叱ったり、注意することも重要な仕事のひとつですが、叱り方を間違えてしまうと、部下のやる気が低下したり、気持ちが落ち込んでしまったりして、お互いに気分が良くないですよね。

「そんなこと、とっくに知ってるよ!」という方がほとんどだと思いますが、伝える順番を変えるだけで相手の捉え方が大きく変わるので、“叱ってから褒める”の順番を頭の片隅にでも置いておいてください。

さいごに

以前の記事でもお伝えしましたが、ほんの少し伝え方を変えるだけで、相手の捉え方は大きく変わります。
相手のことを考えた声掛けをすることでお互いが気持ちよく業務をこなし、その結果、プロジェクトをうまく進めることができたら、一石二鳥ですね。
リーダーや先輩として後輩に適切な指導ができるように、いろいろと伝え方に工夫していかないといけませんね!

画面いっぱいの高さまで要素を広げるCSSを解説

画面いっぱいまで広がるヒーローイメージ(アイキャッチイメージ)をよく見かけませんか?

キャンペーンサイトやコーポレートサイトで使われることが多いですね。

どのデバイスで見ても対応できるように、ヒーローイメージの外枠はheight: 100vh;を設定すると丸く収まると思っていましたが、昨今それでは対応できなくなりました。

今回は、レスポンシブデザインにおいて画面いっぱいまで要素を広げるCSSをご紹介します。

ヒーローイメージにはsvhを使おう

ページにアクセスしたときにコンテンツが画面いっぱいに広がり、スクロールすると後続コンテンツが見えてくる。

このようなデザインを実装したいときは外枠の要素にheight: 100svh;を設定しましょう。
CSSは下記のとおりです。

.hero-image {
  height: 100svh;
}

デモはこちらからご確認ください。

なぜvhじゃなくてsvhなのか?

iOS Safariなどでは、ビューポートのサイズが可変になります。
ファーストビュー(ページアクセス)時とスクロール時でブラウザの表示領域(高さ)が変わります。
iOS Safariではブラウザコントロールバーが非表示になり、URL欄も小さくなるため、そのビューポートが広がります。

svhはビューポートの高さが最小のとき、つまりファーストビューの高さを示します。

ビューポートの高さの最大値を示すのがlvhです。

vhはそれぞれのユーザーエージェントによる、デフォルトのビューポートサイズが採用され、デフォルトのビューポートは大抵ラージビューポートと同じサイズになるので100vh = 100lvhとなり、ファーストビューからはみ出してしまいます。

vhとsvhの違いは何か、下図を見るとわかりやすいかと思います。

ブラウザ対応状況

svh(lvh、dvh含む)は2022年11月末にGoogle Chrome(ver.108)が対応したことで、主要ブラウザ(Chrome、Edge、Safari、Firefox)では問題なく使えるようになりました。

まとめ

ヒーローイメージなどファーストビューの画面いっぱいに広げるコンテンツにはvhではなくsvhを使いましょう。

svhの他にはdvhなどもありますが、それはまた別の機会に説明します。

バス釣りは仕事と似ている。

私の趣味であるバス釣りですが、小学生の時にブームが来て、少しかじるも全く釣ることができず辞めておりました。
25歳くらいのときに何かいい趣味はないかと思い、バス釣りを久々にやってみたらどハマりしました。
そこから10年以上続いております。

バス釣りとは

バス釣りについてですが、一般的な方が「釣り」と聞いて想像するものとは全く異なると思います。
水辺に座って餌を巻いて浮が動くまでずっと待つというものを想像するのではないでしょうか。

バス釣りはその真逆となり、座るなんてことはあり得ません。
多種多様なルアーを駆使して、1つの場所で釣れなければ、次の場所に移動する。
天候、状況、反応などさまざまな要素で考え、試して移動を繰り返します。

バス釣りをするのに重要な要素はおおまかに天候、場所の状況、ルアーの選択だと思います。
さらに細かい要素を加えると、その日の天気の変化、ルアーの色、動かし方など、
細かい要素を考え始めるとキリがないのですが…
その日のパターンを見つける釣りだと思います。
昨日は釣れていたのに同じことをやっても今日は釣れないなんてことは当たり前にあります。

バス釣りを行う際の流れ

バス釣りは上記の要素が複雑に入り組んでその日その日に合ったパターンを見つけていきます。
流れで言いますと、調査、実践、修正、評価になるのかと思います。

調査は釣行日前の天気やSNSでの釣果情報を確認してその日にどのような釣りをするか考えます。
(楽しい想像が膨らみすぎて準備が一番楽しいなんて時もあります)

釣りをしてみて調査通りの状況であるか実践して確認します。
(大体は調査が甘くてここを外すことが多いですが…)

当日の水位や水の色、天気など状況に合わせて修正を行っていきます。
これは今までの経験則や釣り場のデータをどれほど持っているかで
判断が大きく変わる部分だと思いますが、これを繰り返して魚の居場所を探っていきます。

最後に今日の状況を振り返り、経験やデータを蓄積して次に生かします。
これを繰り返すことで釣行を重ねるほど釣果は上がるはず…です。

仕事との共通点

これは仕事でも同じことが言えるのではないかと思っております。
上記、調査、実践、修正、評価を繰り返して成果につなげる。
仕事では対象が魚から人になって、釣果から成果になる。
私は仕事と趣味の共通点を見つけることで、より面白みを感じて働けるようになりました。

仕事を趣味に近い感覚で、より面白味を持って取り組む要素として、この共通点は意外と大切なのではないかと感じております。
釣りだけではなく、他の趣味などでも仕事との共通点があるのではないでしょうか。
皆様も共通点を見つけると趣味に近い感覚で仕事ができるかもしれません。

振り返り手法

こんにちは。

現在、スクラムでの開発を本格的に始めようとしています。
スクラムでは、チームが継続的に振り返りを行います。

一度、別件でFun/Done/Learnでの振り返りを行いました。

感情に基づいている部分もあり、はじめての振り返り手法としては入りやすかったです。
しかし、何がDoneで何がLearnなのか、Fun/Done/Learnの分け方が難しく感じました。

もちろん、DoneでありLearnでもあると重なっているのもOKなのですが、分け方が曖昧でわかりづらいです。
実際、Fun/Done/Learnは次への生かし方が難しい手法のようです。

振り返り手法は他にもたくさんあるので調べてみました!
今後、やってみたい面白そうな振り返り手法を紹介いたします。

KPT法

Keep、Problem、Tryの頭文字でKPT法です。



Keep
うまくいったことや今後も継続すること
Problem
うまくいかなかったことや今後はやめた方がいいこと
Try
今後実施していくべき行動策

Fun/Done/Learnと違う点として、Keep、Problem、Tryが明確に分かれている点がいいと思いました、

物事をはっきり分けられる分、問題もはっきりわかっていくのは魅力的です。
そこですぐに問題解決に移りたくなってしまいますが、あくまで振り返りの場のため、趣旨がずれないように気をつけなくてはいけません。

象、死んだ魚、嘔吐

物騒な名前の通り、うまくいっていないこと・ネガティブなことを発信する振り返り手法です。


見て見ぬふりをしてきた問題。触れてはいけないとされてきたこと。いわゆる暗黙の了解。
部屋の中に象がいるのに誰もそれを口にしないthe elephant in the roomという慣用句から。

死んだ魚
放置しておくとまずい問題

嘔吐
今まで話せていなかったこと。いわゆるぶっちゃけ

雰囲気が重く発言しにくいチームや、関係性がまだできていないチームで有効な振り返りです。

さいごに

すこし調べただけで、たくさんの振り返り手法が出てきます。
いろいろ試行錯誤して、その状況でベストなものを見つけたいです!

PHPによる、Amazon、SP-APIのアクセストークン認証実装

Amazon、SP-APIの認証について、難しいと言ってきましたが自前で実装は可能です。

今回PHPでアクセストークンを利用し認証ヘッダを生成からの注文取得を作成したので、参考にしていただければ幸いです。 PHP5系でも動作します。  

ライブラリを利用せずに、Amazon、SP-APIを利用するにはスクラッチで認証処理を実装する必要があります。

Amazonのマニュアルに認証の仕様の説明がありますが、同じように作ったのに「認証されないなぜだ!」ということがやっぱりあります。アマゾンあるあるの情報が足りていないんですが、たとえば今回の認証の部分で嵌りやすいのが認証用のパラメータを合体させてヘッダの認証パラメータに変換してあげる部分が辞書順じゃないとだめ、とかあります。どこにこの説明載ってんのよこれみたいなのが時々あります。こういうのが経験値と勘と運だけで解決するしかないというところがAmazonのAPIを使う時の難しさ、自分が読めてないだけかもだですが(泣

1.前提条件

この記事を進めるうえでの前提条件としてはAmazon、SP-APIの基礎的な知識があること、PHPの知識があることが前提です。

2.PHPでアクセストークンから認証ヘッダ情報を生成し注文情報を取得してみる

今回もソースコード載せますのでコピーして、各値をご自身の環境の物に変更し、さくっとお試しください。 値が分からないという方は、以前書いた記事「Amazonの新しいAPI、SP-APIをとにかく動かしてみる」をご確認ください。

<?php

class Signature
{
    public static function calculateSignatureForService(
        $host,
        $method,
        $uri,
        $queryString,
        $data,
        $service,
        $accessKey,
        $secretKey,
        $region,
        $accessToken,
        $securityToken,
        $userAgent,
        $amzdate
    ) {
        $terminationString = 'aws4_request';
        $algorithm = 'AWS4-HMAC-SHA256';
        $date = substr($amzdate, 0, 8);

        if (is_array($data)) {
            $param = json_encode($data);
            if ('[]' == $param) {
                $requestPayload = '';
            } else {
                $requestPayload = $param;
            }
        } else {
            $requestPayload = $data;
        }

        $hashedPayload = hash('sha256', $requestPayload);

        $canonicalHeaders = [
            'host' => $host,
            'user-agent' => $userAgent,
        ];

        if (!is_null($accessToken)) {
            $canonicalHeaders['x-amz-access-token'] = $accessToken;
        }
        $canonicalHeaders['x-amz-date'] = $amzdate;

        if (!is_null($securityToken)) {
            $canonicalHeaders['x-amz-security-token'] = $securityToken;
        }

        $canonicalHeadersStr = '';
        foreach ($canonicalHeaders as $h => $v) {
            $canonicalHeadersStr .= $h.':'.$v."\n";
        }
        $signedHeadersStr = join(';', array_keys($canonicalHeaders));

        $credentialScope = $date.'/'.$region.'/'.$service.'/'.$terminationString;

        // パラメータは辞書順に並べ替える必要がある
        if (!empty($queryString)) {
            $queryArray = explode("&", $queryString);
            sort($queryArray);
            $queryString = implode("&", $queryArray);
        }

        $canonicalRequest = $method."\n".$uri."\n".$queryString."\n".$canonicalHeadersStr."\n".$signedHeadersStr."\n".$hashedPayload;

        $stringToSign = $algorithm."\n".$amzdate."\n".$credentialScope."\n".hash('sha256', $canonicalRequest);

        $kSecret = 'AWS4'.$secretKey;
        $kDate = hash_hmac('sha256', $date, $kSecret, true);
        $kRegion = hash_hmac('sha256', $region, $kDate, true);
        $kService = hash_hmac('sha256', $service, $kRegion, true);
        $kSigning = hash_hmac('sha256', $terminationString, $kService, true);

        $signature = trim(hash_hmac('sha256', $stringToSign, $kSigning));

        $authorizationHeader = $algorithm." Credential={$accessKey}/{$credentialScope}, SignedHeaders={$signedHeadersStr}, Signature={$signature}";
        return $authorizationHeader;
    }
}


$host = 'sellingpartnerapi-fe.amazon.com'; // 日本だとこの値
$service = 'execute-api';
$region = 'us-west-2'; // 日本だとこの値

$accessKey = "AKIA6***************"; // アクセスキーID: Amazonの新しいAPI、SP-APIをとにかく動かしてみる 1-6. アクセスキーIDの値
$secretKey = 'Zuh069DUjSU/****************************'; // シークレットアクセスキー: Amazonの新しいAPI、SP-APIをとにかく動かしてみる 1-6. シークレットアクセスキーの値
$accessToken = 'Atza|IwEBILzfIgHC3WPLptj_lyiwv-uPKg6xKPTPhwqqKZwjsK0GnlHR9zRnI0FfnESDZKDe4S************************************************************************************************************************************************************************************************************************************************************************************************************'; // アクセストークン: Amazonの新しいAPI、SP-APIをとにかく動かしてみる 4-7. のアクセストークンの値
                                                                                           
$marketplaceId = 'A1VC38T7YXB528'; // 日本だとこの値

$requestUrl = 'https://sellingpartnerapi-fe.amazon.com/orders/v0/orders?MarketplaceIds=' . $marketplaceId . '&CreatedAfter=2023-01-01';
$httpRequestMethod = 'GET';
$canonicalURI = '/orders/v0/orders';
$canonicalQueryString  = 'MarketplaceIds=' + $marketplaceId + '&CreatedAfter=2023-01-01'; // パラメータはSiguniture生成時に辞書順に変更する必要があるので注意

$userAgent = 'cs-php-sp-api-client/2.1';

$currentDateTime = new DateTime('UTC');
$amzdate = $currentDateTime->format('Ymd\THis\Z');

$signature = new Signature();
$authorizationHeader = $signature->calculateSignatureForService($host, $httpRequestMethod, $canonicalURI, $canonicalQueryString, '', $service, $accessKey, $secretKey, $region, $accessToken, null, $userAgent, $amzdate);

// Request headers
$headers = array();
$headers[] = 'Accept: application/json';
$headers[] = 'Content-Type: application/json';
$headers[] = 'host: ' . $host;
$headers[] = 'user-agent: ' . $userAgent;
$headers[] = 'x-amz-access-token: ' . $accessToken;
$headers[] = 'x-amz-date: ' . $amzdate;
$headers[] = 'Authorization:'. $authorizationHeader;


$curl = curl_init();
curl_setopt_array($curl, array(
    CURLOPT_URL => $requestUrl,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_POST => false,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => $httpRequestMethod,
    CURLOPT_VERBOSE => 0,
    CURLOPT_SSL_VERIFYHOST => 0,
    CURLOPT_SSL_VERIFYPEER => 0,
    CURLOPT_HEADER => false,
    CURLINFO_HEADER_OUT=>true,
    CURLOPT_HTTPHEADER => $headers,
));

$response = curl_exec($curl);

var_dump($response);

$err = curl_error($curl);
$responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);


curl_close($curl);

if ($err) {
    echo "<h5>Error:" . $responseCode . "</h5>";
    echo "<pre>";
    echo $err;
    echo "</pre>";
} else {
    echo "<h5>Response:" . $responseCode . "</h5>";
    echo "<pre>";
    echo $response;
    echo "</pre>";
}

PHPによるAmazon、SP-API実装 

特にご要望が多いPHPのSP-API実装について執筆したいと思います。

今回はさくっと行きます。

1.前提条件

この記事を進めるうえでの前提条件としてはAmazon、SP-APIの基礎的な知識があること、PHPの知識がありライブラリを読み込ませて実行が行えることが前提です。

2.clousaleが提供するamazon-sp-api-phpライブラリを利用する

以前の記事でも書きましたが、SP-APIを利用する場合、認証のためのアクセストークンからの認証用ヘッダの生成の難易度がとても高いです。

そこを自動で行ってくれるライブラリを利用すれば認証をほとんど意識することなくPHPでアマゾンのSP-APIを簡単に利用することができます。

世の中には無料でソースを提供してくれる素晴らしい方たちがいます。

https://github.com/clousale/amazon-sp-api-php

こちらをインストールして利用しましょう、インストールはURLのgithubページのInstallationに記載されているようにcomposerで行えます。

PHP7.3以上と若干制限があります。

3.PHPからclousale、SP-APIライブラリを使用して注文情報を取得してみる

ソースコード載せますのでコピーしてoptionsの値を自身の環境の物に変更し、さくっとお試しください。

optionsの値が分からないという方は、以前書いた記事「Amazonの新しいAPI、SP-APIをとにかく動かしてみる」をご確認ください。

<?php

require_once './vendor/autoload.php';

$options = [
    'refresh_token' => 'AtzrAtzr|IwEBIABHaXRPj86Ei3xPolpsRT*************************************************************************************************************************************************************************************************************************************************************************************************************', // リフレッシュトークン: Amazonの新しいAPI、SP-APIをとにかく動かしてみる 3-5. のリフレッシュトークンの値
    'client_id' => 'amzn1.application-oa2-client.********************************', // クライアントID: Amazonの新しいAPI、SP-APIをとにかく動かしてみる 3-7. のクライアントIDの値
    'client_secret' => 'amzn1.oa2-cs.v1.*****************************************************************:', // クライアント機密情報: Amazonの新しいAPI、SP-APIをとにかく動かしてみる 3-5. のクライアント機密情報の値
    'region' => \ClouSale\AmazonSellingPartnerAPI\SellingPartnerRegion::$FAR_EAST,  // 日本だとこの値
    'access_key' => 'AKIA6***************', // アクセスキーID: Amazonの新しいAPI、SP-APIをとにかく動かしてみる 1-6. アクセスキーIDの値
    'secret_key' => 'Zuh069DUjSU/****************************', // シークレットアクセスキー: Amazonの新しいAPI、SP-APIをとにかく動かしてみる 1-6. シークレットアクセスキーの値
    'endpoint' => \ClouSale\AmazonSellingPartnerAPI\SellingPartnerEndpoint::$FAR_EAST, // 日本だとこの値
];


// アクセストークン取得処理
$accessToken = \ClouSale\AmazonSellingPartnerAPI\SellingPartnerOAuth::getAccessTokenFromRefreshToken(
    $options['refresh_token'],
    $options['client_id'],
    $options['client_secret']
);


$config = \ClouSale\AmazonSellingPartnerAPI\Configuration::getDefaultConfiguration();
$config->setHost($options['endpoint']);
$config->setAccessToken($accessToken);
$config->setAccessKey($options['access_key']);
$config->setSecretKey($options['secret_key']);
$config->setRegion($options['region']);

$marketplaceId = 'A1VC38T7YXB528'; // 日本だとこの値

// 受注情報取得
$apiInstance = new \ClouSale\AmazonSellingPartnerAPI\Api\OrdersApi($config);
$result = $apiInstance->getOrders($marketplaceId, '2023-01-01');
var_dump($result);

店舗・EC DXPO東京‘23に出展いたします。

前回の楽天新春カンファレスでのブース出展に続いて、店舗・EC DXPOに出展させていただくことになりました。DXPOは、DXを推進する約500社が出展する国内最大級の展示会となります。

店舗・EC EXPOとは?

DXを推進する最新サービスが一斉に体験できる展示会となっており、業界大手からスタートアップ企業が参加しております。自社の課題を解決するソリューションが期待できる場となっております。開催日時は以下の通りです。

EC売上拡大・開業支援展にて展示

ECコーナーにて楽天向けレビュー対策ツール【らくらくーぽん】や昨年リリースしたYahoo!ショッピング向けレビュー対策ツール【らくらくフォロー】を中心に、サービスの紹介や実例などをご紹介いたします。その他のEC支援ツールの展示も予定しております。

オンライン展示会も同時に出展中:https://dxpo.jp/u/fox/webooth/detail?webooth_slot=810

DXPO会場にお越しいただいた際は、是非、弊社ブースにお立ち寄りください。