【macOS】右クリックから短縮したAmazonリンクをコピーする

## まとめ

- Amazonってリンクが無駄に長い
- そういうサイト[^短縮サイト]もあるが、macの右クリックからコピーしたい
- Automatorを使って作った

https://github.com/taikis/myJXA

## Amazonのリンクは長い

検索から飛ぶと、こんなに長くなってしまう
https://www.amazon.co.jp/%E3%83%A2%E3%83%AD%E3%83%83%E3%82%B3-%E3%83%95%E3%83%AB%E3%83%BC%E3%83%84%E3%83%A8%E3%83%BC%E3%82%B0%E3%83%AB%E3%83%88-60%E5%80%8B%E5%85%A5%E3%82%8A1BOX/dp/B007CEWVRW/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3DI1RMHPRJFY3&keywords=%E3%83%A2%E3%83%AD%E3%83%83%E3%82%B3%E3%83%A8%E3%83%BC%E3%82%B0%E3%83%AB&qid=1656953958&sprefix=%E3%83%A2%E3%83%AD%E3%83%83%E3%82%B3%E3%83%A8%E3%83%BC%E3%82%B0%E3%83%AB%2Caps%2C181&sr=8-4

また、検索バーに入れていた値も引き継がれるため、どうやって検索したのかがわかってしまいます。  
他人に共有するときなどは適していません。

## Amazonリンクの仕組み

### 短縮方法
必要なのは`dp/B007CEWVRW`のような10桁の文字列です。  
ASINと呼ばれ、Amazonが商品につける固有のIDとなっています。[^公式リンク]

これを使うだけで、こんなに短縮することができます。
https://amazon.co.jp/dp/B007CEWVRW

### URLの種類

しかし、アフィリエイトリンクなどではまれに`db/`から始まる番号がない場合があるらしい。[^URLの例外]
そのため、URLのパターンを網羅する必要があります。

http://urbanqee.com/html/amazon/amazon-url-shortened.html

上記サイトによれば、四つのパターンがあるようです。

| Amazonリンク |
|:-:|
| dp/){ASIN}/ |
| gp/product/{ASIN}/ |
| exec/obidos/asin/{ASIN}/ |
| o/ASIN/{ASIN}/|

## 設計

要件がわかってきたところで、今回作るものの概要を考えます。

1. macで右クリックから呼び出したい
1. 入力されたURLを正規表現でパーズし、ASINを取り出す
1. 最小のURLを再構成してクリップボードにコピー

今回はこれを目指すことにします。

## 要素技術

### Automator

今回はURLを選択→右クリックのメニューからコピーや、クリップボードの操作を行いたかったので、OSと親和性の高いAutomatorを用いました。

と言っても、AppleはAutomatorにJavaScriptを対応させており、JavaScriptで完結することができます。
他にもAppleScriptなるものがあるようですが、このために勉強するのは~~だるい~~コストが高いのでやめました。

### JavaScript

JavaScriptでクリップボードの操作など、OSに関わる操作をする場合、`StandardAdditions`パッケージを用いる。

このパッケージはWeb上に公式のリファレンスが存在しない。(多分)
macのローカルに保存されているので、下記手順に従ってリファレンスを参照しましょう。[^Appleの辞書の開き方解説]

1. スクリプトエディタ
1. ファイル
1. 用語説明を開く
1. 右上のAppleScriptをJavaScriptに変更
1. `StandardAdditions.osax`を開く
1. それっぽい機能をクリック

例えばクリップボードへのコピーだと、`Clipboard Commands`→`setTheClipboardTo`に、

> Clipboard Commands
> setTheClipboardTo method : Place data on an application’s clipboard. Use inside a ‘tell’ block and activate the application first  
> setTheClipboardTo any : the data to place on the clipboard

とあり、`setTheClipboardTo(any)`を使えばいいことがわかります。

## 実装

さて、やることとやり方がわかったので実装をします。

### 正規表現

今回はamazon.comでもamazon.co.jpでも動かしたかったので、正規表現は下記のようにしました。[^Amazon正規表現]

```js
var regList = [];
regList.push(/(?:https?:\/\/)?([^\/]*\/).*dp\/([0-9A-Z]{10})(?:[^0-9A-Z]|$)/i);
regList.push(/(?:https?:\/\/)?([^\/]*\/).*product\/([0-9A-Z]{10})(?:[^0-9A-Z]|$)/i);
regList.push(/(?:https?:\/\/)?([^\/]*\/).*asin\/([0-9A-Z]{10})(?:[^0-9A-Z]|$)/i);
```

これで四つのパターンが網羅され、ドメインとASINがキャプチャされます。

### URLが取れたらクリップボードにコピー

クリップボードにコピーするには、下記のように書きます。

```js
var app = Application.currentApplication();
app.includeStandardAdditions = true;
app.setTheClipboardTo(url);
```

最初の二行はおまじないと思っています。
includeStandardAdditionsを入れないと、その時開いているソフトの機能しか呼び出せないようです。

### URLが取れなかったら警告を吐く

用語説明を漁って、OKボタンのみのダイアログがあることがわかりました。

```js
var dialogText = "Amazonリンクが正しく入力されませんでした。";
app.displayAlert(dialogText, {
    buttons: "終了",
});
```

### 完成

成功した時は邪魔にならないように通知を入れたりして、完成したのが下記になります。

```js
function getAsin(target) {
	var regList = [];
	regList.push(/(?:https?:\/\/)?([^\/]*\/).*dp\/([^\/|\?]*)/i);
	regList.push(/(?:https?:\/\/)?([^\/]*\/).*product\/([^\/|\?]*)/i);
	regList.push(/(?:https?:\/\/)?([^\/]*\/).*asin\/([^\/|\?]*)/i);
	for (let reg of regList) {
		var m = reg.exec(target);
		if (m) {
			return [m[1], m[2]];
		}
	}

}

function run(input, parameters) {
    var app = Application.currentApplication();
    app.includeStandardAdditions = true;

	var domain, asin;
	urlInfo = getAsin(input);
	if (urlInfo) {
		[domain, asin] = urlInfo;
		url = "https://" + domain + "dp/" + asin;
		app.setTheClipboardTo(url);
        app.displayNotification("URLをコピーしました",{
            withTitle: "成功",
        })
	}else{
        var dialogText = "Amazonリンクが正しく入力されませんでした。";
        app.displayAlert(dialogText, {
            buttons: "終了",
        });
    }
}
```

GitHubにも載せてあります。

https://github.com/taikis/myJXA/tree/main/amazon-url-formatter


## Automatorに載せる

これをAutomatorに載せて、右クリックから使えるようにします。  

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623593/d36cbccc-c1a7-27c2-ef14-22a912ff229d.png" width="100%">

基本は画像の通り設定すればOKです。
URLが選択されているときに、右クリックメニューに表示されます。

## 終わりに

Javascript for Automationって衰退しているのか？ってくらい文献がないですね。  
もっといい共有方法を知っている方がいたら教えてください。

[^短縮サイト]:めっちゃ便利なツール: https://howtobuyfromjapan.com/amazon_url_shortener.htm
[^公式リンク]:参考 Amazon: https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=201446530
[^URLの例外]:参考 ITMedia: https://www.itmedia.co.jp/bizid/articles/0805/13/news065.html
[^Appleの辞書の開き方解説]:参考 Apple公式: https://developer.apple.com/library/archive/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/OpenaScriptingDictionary.html
[^Amazon正規表現]:参考 AmazonのURLからASINコードを抜き出すための正規表現コード
https://penpen-dev.com/blog/ama-asin-nukidasu/