しょうがないので Amazon アフィリエイト・リンク作成ツールを作ったですよ

no extension

昨年「Amazon アフィリエイトリンク作成サービスを Amakuri へ移行」したと書いたのだが Amazon の締めつけが厳しくて閉鎖するらしい。

何してくれやがるですか Amazon さん orz

しょうがないので,自前で Amazon アフィリエイト・リンク作成ツールを作ったですよ。 ただし CLI (Command-Line Interface) ツール。 下手にサービスなんか作って BAN されるの嫌だし,なにより Web サービスは管理・運用が面倒臭い。

ツールのインストール

まだテストもしていない出来たてホヤホヤ(笑) まぁ,でも,ひと通りは動く。

バイナリを用意していないので,インストールには Go 言語 1.11 以降のビルド環境(git を含む)が必要。 適当なフォルダで以下のコマンドを実行すれば $GOPATH/bin フォルダにインストールされる。

$ export GO111MODULE=on
$ go mod init tools
$ go get github.com/spiegel-im-spiegel/amazon-item@latest

一応,動作確認。

$ amazon-item -h
Searching Amazon Items, Powered by Product Advertising API

Usage:
  amazon-item [flags]
  amazon-item [command]

Available Commands:
  help        Help about any command
  lookup      Lookup Amazon Item
  search      Search Amazon Items
  version     Print the version number

Flags:
      --access-key string      Access Key ID
      --associate-tag string   Associate Tag
      --config string          config file (default $HOME/.paapi.yaml)
  -h, --help                   help for amazon-item
      --marketplace string     Marketplace (default "webservices.amazon.co.jp")
      --secret-key string      Secret Access Key

Use "amazon-item [command] --help" for more information about a command.

【追記 2019-01-27】 バイナリを含む v0.2.1 をリリースした

v0.2.1 をリリースした。

各種プラットフォーム向けのバイナリも併せてリリースしているので,自前でビルドしなくてもよくなった。 改めてよろしく。

使用準備

amazon-item を使うには Amazon Associate ID を持っていて Amazon Product Advertising API の Access Key および Secret Key まで取得済みであることが前提となる。 取得できたら $HOME ディレクトリに .paapi.yaml ファイルを作って値を格納しておく(ファイル・アクセス管理に注意)。

たとえばこんな感じ。

associate-tag: mytag-20
access-key: AKIAIOSFODNN7EXAMPLE
secret-key: 1234567890

なお associate-tag とは Amazon Associate ID のことである。

これで準備 OK

商品の検索

商品の検索には amazon-item search コマンドを使う。

$ amazon-item search -h
Search Amazon Items by ItemSearch Method

Usage:
  amazon-item search [flags] keyword

Flags:
  -h, --help                    help for search
  -g, --response-group string   ResponseGroup (default "ItemAttributes,Small")
  -s, --search-index string     SearchIndex (default "All")
  -t, --template string         Template file

Global Flags:
      --access-key string      Access Key ID
      --associate-tag string   Associate Tag
      --config string          config file (default $HOME/.paapi.yaml)
      --marketplace string     Marketplace (default "webservices.amazon.co.jp")
      --secret-key string      Secret Access Key

たとえば結城浩さんの『数学ガール/フェルマーの最終定理』の Kindle 版を探すなら

amazon-item search 数学ガール+フェルマーの最終定理+kindle

などとすればよい。 検索結果は JSON 形式で標準出力に出力される。 jq コマンドなどで整形すれば見やすくなるだろう。

amazon-item search 数学ガール+フェルマーの最終定理+kindle | jq .

テンプレート・ファイルを用意すれば出力を任意に整形できる。 たとえば

$ cat template/item-list.md
| ASIN | Title | Author | Binding | EAN | Publisher | PublicationDate | URL |
| ---- | ----- | ------ | ------- | --- | --------- | --------------- | --- |
{{ range .Items }}| {{ .ASIN }} | {{ .ItemAttributes.Title }} | {{ .ItemAttributes.Author }} | {{ .ItemAttributes.Binding }} | {{ .ItemAttributes.EAN }} | {{ .ItemAttributes.Publisher }} | {{ .ItemAttributes.ReleaseDate }} | {{ .URL }} |
{{ end }}

のようなテンプレートを用意して以下のように使う。

$ amazon-item search -t template/item-list.md 数学ガール+フェルマーの最終定理+kindle
| ASIN | Title | Author | Binding | EAN | Publisher | PublicationDate | URL |
| ---- | ----- | ------ | ------- | --- | --------- | --------------- | --- |
| B00AXUD4EQ | 数学ガール フェルマーの最終定理 1 (MFコミックス フラッパーシリーズ) |  春日旬 | Kindle版 |  | KADOKAWA / メディアファクトリー | 2012-12-19 | https://www.amazon.co.jp/exec/obidos/ASIN/B00AXUD4EQ/mytag-20 |
| B00I8AT1CM | 数学ガール/フェルマーの最終定理 |  結城 浩 | Kindle版 |  | SBクリエイティブ | 2014-03-12 | https://www.amazon.co.jp/exec/obidos/ASIN/B00I8AT1CM/mytag-20 |
| B00DONBQAI | 数学ガール フェルマーの最終定理 3 (MFコミックス フラッパーシリーズ) |  春日 旬 | Kindle版 |  | KADOKAWA / メディアファクトリー | 2013-06-27 | https://www.amazon.co.jp/exec/obidos/ASIN/B00DONBQAI/mytag-20 |
| B00AXUD4F0 | 数学ガール フェルマーの最終定理 2 (MFコミックス フラッパーシリーズ) |  春日旬 | Kindle版 |  | KADOKAWA / メディアファクトリー | 2012-12-19 | https://www.amazon.co.jp/exec/obidos/ASIN/B00AXUD4F0/mytag-20 |
| B0756XMQBN | 数学ガール フェルマーの最終定理 |  春日旬 春日 旬 | Kindle版 |  |  |  | https://www.amazon.co.jp/exec/obidos/ASIN/B0756XMQBN/mytag-20 |
| B00ZEIEY1E | [まとめ買い] 数学ガール フェルマーの最終定理(コミックフラッパー) |  春日旬 春日 旬 | Kindle版 |  |  |  | https://www.amazon.co.jp/exec/obidos/ASIN/B00ZEIEY1E/mytag-20 |

これで出力結果を markdown の表形式に整形できた。

Amazon アフィリエイト・リンクを作成する

ある商品に対して Amazon アフィリエイト・リンクを作成するには amazon-item lookup コマンドを使う。

$ amazon-item lookup -h
Lookup Amazon Item by ItemLookup Method

Usage:
  amazon-item lookup [flags]

Flags:
  -h, --help                    help for lookup
  -p, --id-type string          IdType (default "ASIN")
  -d, --item-id string          ItemId
  -g, --response-group string   ResponseGroup (default "Images,ItemAttributes,Small")
  -t, --template string         Template file
  -x, --xml                     Output with XML format

Global Flags:
      --access-key string      Access Key ID
      --associate-tag string   Associate Tag
      --config string          config file (default $HOME/.paapi.yaml)
      --marketplace string     Marketplace (default "webservices.amazon.co.jp")
      --secret-key string      Secret Access Key

商品を指定するには ASIN コードを使う。

$ amazon-item lookup -d B00I8AT1CM

特に指定しなければ JSON 形式で標準出力に出力される。 また -x オプションをつければ XML 形式で(というか PA-API の返す結果がそのまま)出力される。

amazon-item lookup コマンドもテンプレート・ファイルで出力を整形できる。 たとえば

$ cat template/lookup.md
{{ range .Items }}<div class="hreview">
  <div class="photo"><a class="item url" href="{{ .URL }}"><img src="{{ .MediumImage.URL }}" width="{{ .MediumImage.Width }}" alt="photo"></a></div>
  <dl class="fn">
    <dt><a href="{{ .URL }}">{{ .ItemAttributes.Title }}</a></dt>
    {{ with .ItemAttributes.Author }}<dd>{{ . }}</dd>{{ end }}
    <dd>{{ .ItemAttributes.Publisher }}{{ with .ItemAttributes.PublicationDate }} {{ . }}{{ end }}{{ with .ItemAttributes.ReleaseDate }} (Release {{ . }}){{ end }}</dd>
    <dd>{{ .ItemAttributes.ProductGroup }} {{ .ItemAttributes.Binding }}</dd>
    <dd>ASIN: {{ .ASIN }}{{ with .ItemAttributes.EAN }}, EAN: {{ . }}{{ end }}</dd>
  </dl>
  <p class="powered-by" >reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="{{ $.Today }}">{{ $.Today }}</abbr> (powered by <a href="{{ $.AppURL }}" >{{ $.AppName }}</a> {{ $.AppVersion }})</p>
</div>{{ end }}

といった感じにテンプレートファイルを作って

$ amazon-item lookup -d B00I8AT1CM -t template/lookup.html
<div class="hreview">
  <div class="photo"><a class="item url" href="https://www.amazon.co.jp/exec/obidos/ASIN/B00I8AT1CM/mytag-20"><img src="https://images-fe.ssl-images-amazon.com/images/I/41vT2D6sERL._SL160_.jpg" width="113" alt="photo"></a></div>
  <dl class="fn">
    <dt><a href="https://www.amazon.co.jp/exec/obidos/ASIN/B00I8AT1CM/mytag-20">数学ガール/フェルマーの最終定理</a></dt>
    <dd>結城 浩</dd>
    <dd>SBクリエイティブ 2008-07-29 (Release 2014-03-12)</dd>
    <dd>eBooks Kindle版</dd>
    <dd>ASIN: B00I8AT1CM</dd>
  </dl>
  <p class="powered-by" >reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2019-01-13">2019-01-13</abbr> (powered by <a href="https://github.com/spiegel-im-spiegel/amazon-item" >amazon-item</a> v0.1.0)</p>
</div>

などと整形することができる。

これで PA-API の利用を Amazon から拒絶されなければ自前で何とかいけそうかな。 でも売上実績がないと PA-API が使えなくなるんだよなぁ。 ホンマに勘弁してよ Amazon さん orz

【追記】 go-amazon-product-api パッケージの置き換え

amazon-item では DDRBoxman/go-amazon-product-api パッケージを使っているのだが ItemAttributesAuthor および Creator 項目の取り扱いに難があって複数の AuthorCreator を上手く取り込めない。 これを改良したものを spiegel-im-spiegel/go-amazon-product-api で公開している。

パッケージを置き換えるには,最初のインストールのときにできる go.mod ファイルに以下の行を追記する。

replace github.com/DDRBoxman/go-amazon-product-api v0.0.0-20190113062856-6736abd38089 => github.com/spiegel-im-spiegel/go-amazon-product-api v0.0.0-20190113075218-1369f41b1e57

この状態で再度

$ go get github.com/spiegel-im-spiegel/amazon-item@latest

とすれば spiegel-im-spiegel/go-amazon-product-api に置き換えてくれる。 やぁ 1.11 のモジュール・モードは本当に便利だなや。

これで

{{ range .Items }}<div class="hreview">
  <div class="photo"><a class="item url" href="{{ .URL }}"><img src="{{ .MediumImage.URL }}" width="{{ .MediumImage.Width }}" alt="photo"></a></div>
  <dl class="fn">
    <dt><a href="{{ .URL }}">{{ .ItemAttributes.Title }}</a></dt>
    {{ if .ItemAttributes.Author }}<dd>{{ range $i, $v := .ItemAttributes.Author }}{{ if ne $i 0 }}, {{ end }}{{ $v }}{{ end }}</dd>{{ end }}
    {{ if .ItemAttributes.Creator }}<dd>{{ range $i, $v := .ItemAttributes.Creator }}{{ if ne $i 0 }}, {{ end }}{{ $v.Value }}{{ with $v.Role }} ({{ . }}){{ end }}{{ end }}</dd>{{ end }}
    <dd>{{ .ItemAttributes.Publisher }}{{ with .ItemAttributes.PublicationDate }} {{ . }}{{ end }}{{ with .ItemAttributes.ReleaseDate }} (Release {{ . }}){{ end }}</dd>
    <dd>{{ .ItemAttributes.ProductGroup }} {{ .ItemAttributes.Binding }}</dd>
    <dd>ASIN: {{ .ASIN }}{{ with .ItemAttributes.EAN }}, EAN: {{ . }}{{ end }}</dd>
  </dl>
  <p class="powered-by" >reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="{{ $.Today }}">{{ $.Today }}</abbr> (powered by <a href="{{ $.AppURL }}" >{{ $.AppName }}</a> {{ $.AppVersion }})</p>
</div>{{ end }}

のようにテンプレートを記述すれば

$ amazon-item lookup -d B01IGW5IIW -t template/lookup.html
<div class="hreview">
  <div class="photo"><a class="item url" href="https://www.amazon.co.jp/exec/obidos/ASIN/B01IGW5IIW/mytag-20"><img src="https://images-fe.ssl-images-amazon.com/images/I/51gC8Tmq1kL._SL160_.jpg" width="113" alt="photo"></a></div>
  <dl class="fn">
    <dt><a href="https://www.amazon.co.jp/exec/obidos/ASIN/B01IGW5IIW/mytag-20">リーン開発の現場 カンバンによる大規模プロジェクトの
運営</a></dt>
    <dd>HenrikKniberg, 角谷信太郎</dd>
    <dd>市谷聡啓 (翻訳), 藤原大 (翻訳)</dd>
    <dd>オーム社 2013-10-25 (Release 2017-07-15)</dd>
    <dd>eBooks Kindle版</dd>
    <dd>ASIN: B01IGW5IIW</dd>
  </dl>
  <p class="powered-by" >reviewed by <a href='#maker' class='reviewer'>Spiegel</a> on <abbr class="dtreviewed" title="2019-01-13">2019-01-13</abbr> (powered by <a href="https://github.com/spiegel-im-spiegel/amazon-item" >amazon-item</a> v0.1.0)</p>
</div>

のように整形される。

DDRBoxman/go-amazon-product-api に pull request を送るか悩み中。 割と破壊的変更なんだよね。 もう少し考えてから判断しよう。

ブックマーク