Amazon の商品リンクを短縮するブックマークレット

Amazon で良い商品を見つけて紹介するときに困るのが、あの**滅茶苦茶長いアドレス**！！

しかも Slack などで貼り付ると途切れてしまって、「リンク切れて見れない」とか二度手間になったり。。。Excel とかで商品リストを作るときにも困りもの。。。

そんなMyお悩み解決をしたかったので Google Chrome で動くブックマークレットを作ってみました。

# ブックマークレットとは？

ブラウザーのお気に入り機能を利用してブックマークしたサイトリンクの代わりに、ちょっぴり便利なツールを実行する仕組みです。実際にはワンライナー JavaScript プログラムです。

歴史や詳しい解説は [wikipedia](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88) で：


> **ブックマークレット (Bookmarklet)** とは、ユーザーがウェブブラウザのブックマークなどから起動し、なんらかの処理を行う簡易的なプログラムのことである[注釈 1]。携帯電話のウェブブラウザで足りない機能を補ったり、ウェブアプリケーションの処理を起動する為に使われることが多い。

# 登録する

1. Chrome の設定からブックマークマネージャーを開きます。
  Windows なら Ctrl + Shift + O でも起動します。
1. 右上のメニューから「新しいブックマークを追加」を選びます。
1. 名前は任意ですが、ここでは「Amazon リンク短縮」とします。
1. URL に以下の内容を丸ごと貼り付けて保存します。

```javascript:bookmarklet
javascript:(function(){['www.amazon.co.jp','www.amazon.com'].includes(location.host)&&(m=location.pathname.match(/\/(dp|gp\/product)\/\w+/))?location.href=location.origin+m[0]:alert(%27Amazon\u306e\u5546\u54c1\u30da\u30fc\u30b8\u3092\u8868\u793a\u3057\u3066\u304f\u3060\u3055\u3044%27)})()
```

こんな感じ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934/9cf8554e-83b2-1531-a18e-b2a3d1a6c6be.png)

ドロップダウンで表示してスッキリさせたいので、フォルダを作ってその中にいれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934/5673de1a-290b-3679-141c-dcf14f0c3ad8.png)

# 使ってみる

アマゾンで商品を探したら、作成したブックマークレット「Amazon リンク短縮」をクリック！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934/a1a6857e-5530-0640-e8d8-71a6e9ddaf9b.png)

すると、、アドレスをシンプルにできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934/fa1ba9af-156d-002f-3739-8100d4a60756.png)

これでおねだりする商品アドレスが途切れることなく伝えることができますね！やった！！

あっ、画面ショットの商品は素で欲しい半田ごてですｗ　~~スケスケはロマン~~

# コード説明

ここからはプログラマー向けの説明です。使うだけならここまでで終わりです。

# 概要

アドレス中の `/dp/*****/` や `/gp/product/*****/` 部分を抜き出し、それ以外は捨てる事で短縮しています。
うっかり対策として Amazon のサイトに対してのみ機能するようにホスト名で制限してます。
UK など別サイトでは試してませんので、必要に応じて改造してもらえればと思います。

## 分解

```javascript
javascript:(function(){
  ['www.amazon.co.jp','www.amazon.com'].includes(location.host)
  && (m=location.pathname.match(/\/(dp|gp\/product)\/\w+/))
    ? location.href = location.origin+m[0]
    : alert('Amazonの商品ページで実行してください')
})()
```

## 構造

建付けとしては三項演算子を中心として『「サイト判定＆商品ID探索」？「両方ともOKならURL整形してリダイレクト」：「失敗メッセージ」』です。

## ポイントになるところ

### 即時関数にして実行している

使える構文・処理構造のバリエーションを増やすために `(` `)` で括りつつ即時関数としてラッピングしています。

### 参考演算子

大多数は、代入式・値変換として利用される参考演算子ですが、短縮のために if ブロックのように実行するコードの分岐として利用しています。

```javascript
if (x && y) { /* 成立時の処理 */ } else { /* 不成立時 */ }

(x && y) ? { /* 成立時の処理 */ } : { /* 不成立時 */ }

x && y ? /* 成立時の処理 */ : /* 不成立時 */
```

成立時・不成立時の処理は1命令だけであればブロックを省略できるのを利用するとコード圧縮できます。

### 戻り値を判定に流用する

[match()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/match) で商品IDらしき部分だけを抜き出しをしていますが、同時に代入結果を参考演算子の評価式に与える事で抜き出せたかの判定にも流用しています。

```javascript
if (m = str.match(/商品IDらしき部分を抜き出す正規表現/)) {
  // 見つかったら m はオブジェクト
} else {
  // 見つからなかったら m は null
}
```


## javascript: とは？

普段は `https://～` になっている URL 部分が、あまり馴染みが無い `javascript` から始まっています。この部分をスキームと言い、スキームごとに挙動が設定されていてます。

- `https:` なら、暗号通信が有効にして続くホスト名の Web サイトをブラウザーで開く
- `mailto:` なら、メーラーを起動して続く文字列を宛先メールアドレス
- `tel:` なら、電話アプリを起動して続く番号にコールする
- `javascript:` なら、続く文字列を JavaScript として実行する

のような感じです。
※厳密には `:` はスキームには含まれません。

興味があるなら「[RFC 3986](https://tex2e.github.io/rfc-translater/html/rfc3986.html)」あたりが参考になります。

# おわりに

「いかに短い JavaScript コードを仕上げるか」という一種のゲーム感覚で作り始めたのが切っ掛けでした。ブックマークレットが所謂ワンライナー、1行コードでかつ、使えない起動がある縛りがある中でいかに成し遂げるかというテーマは奥深く面白いのではとおもいます。

最後に、失敗メッセージは日本語にしたかったので以下のサイトを活用しました。感謝です。

- Unicodeエスケープシーケンス変換ツール
  https://tech-unlimited.com/escape-unicode.html

完全に自分用に作ったブックマークレットですが、最初に書いた通り案外と出番が多くて重宝してます。

何かのお役に立てれば。