Worldcoinの価格変動を監視し、iPhoneに通知するシステムを作る

## はじめに
最近、**Worldcoin（WLD）** の価格が日々大きく変動しています。そんな中、購入のベストタイミングを逃したくない、または保有している通貨の価格が急に下がった時にすぐに対応したいと考える方も多いと思います。

そこで今回は、**Worldcoinの価格変動を監視し、設定した価格を超えた瞬間に自分のiPhoneに通知するシステム**を作ってみたので紹介します。

# 使うツール
・GoogleAppScriptのみ
## ステップ1: Worldcoinの価格を取得

まずは、[CoinMarketCap](https://coinmarketcap.com/)というサイトのAPIを使用してWorldcoinの価格を日本円で取得するプログラムを作ります。
GoogleAppScriptを新規作成し、以下のコードを記述します。
※APIを利用するには、アカウントを作成しAPIキーを取得する必要があります。

```javascript
function getWorldcoinPriceJPY() {
  // CoinMarketCapのAPIエンドポイント
  var url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=WLD&convert=JPY";
  var apiKey = '**********';// 自分のAPIキー
  
  // APIリクエストのオプション設定
  var options = {
    "method" : "get",
    "headers" : {
      "X-CMC_PRO_API_KEY": apiKey,
      "Accept": "application/json"
    }
  };
  
  // APIリクエストを送信し、レスポンスを取得
  var response = UrlFetchApp.fetch(url, options);
  var json = response.getContentText();
  var data = JSON.parse(json);
  
  // Worldcoinの価格を日本円で取得
  var priceJPY = data.data.WLD.quote.JPY.price;
  
  // 取得した価格をログに出力（または他の処理）
  Logger.log("Worldcoinの現在の価格は ¥" + priceJPY.toFixed(2) + " です。");
  
  // Worldcoinの価格を返す
  return priceJPY
}
```

実行すると、現在のWorldcoinの価格を取得することができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2192833/e025f35e-b732-ec1d-5a84-fc66ed656d98.png)

## ステップ2: メール通知の送信

次に、取得した価格が設定値を超えた場合にメール通知を送信するプログラムを作ります。HTML形式のメール本文で、価格の数字を強調表示して少し見やすくしました。
引数には、「送信先メールアドレス」、「メールに記載したい情報」を設定しています。

```javascript
function sendEmail(email, maxPrice, minPrice, price) {
  var to = email; // 送信先のメールアドレス
  var subject; // メールの件名
  var body; // メールの本文（HTML形式）

  if (price >= maxPrice) {
    subject = "Worldcoinの価格が ￥" + maxPrice + " を超えました";
    body = "<p>" + subject + "</p><p>現在の価格: WLD <strong>￥" + price.toFixed(2) + "</strong></p>";
  } else if(price <= minPrice){
    subject = "Worldcoinの価格が ￥" + minPrice + " を下回りました";
    body = "<p>" + subject + "</p><p>現在の価格: WLD <strong>￥" + price.toFixed(2) + "</strong></p>";
  } else {
    return;
  }
  // メールを送信（HTML形式の本文を使用）
  MailApp.sendEmail({
    to: to,
    subject: "【WLD】" + subject,
    htmlBody: body
  });
  
  // オプションとして、送信後にログを出力することもできます
  Logger.log("メールを送信しました: 宛先=" + to);
}
```
プログラムを実行すると、無事iphoneへメールが届いていることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2192833/d53955d1-e6d8-ee5b-4371-a354318cbd58.png)

## ステップ3: 価格変動の監視と通知

最後に、**Worldcoinの価格が設定した基準値を超えたかどうか**をチェックし、超えた場合にだけ**メールで通知する**プログラムを設定します。

価格が基準値を超えている期間ずっとメールを送り続けることがないように、**isExceed**というフラグを用意し、**価格が超えた瞬間のみメールを送る**よう少し工夫しています。

※**MAX_PRICE**と**MIN_PRICE**の値を変更することで好きな基準値を設定できます！

```javascript
//通知を送る基準値
MAX_PRICE = 1500
MIN_PRICE = 1000

function monitorWorldcoinPriceJPY() {
  //isExceed:価格が超えている間、無限に通知を送るのを防ぐために、「現在の価格が超えているかの状態(isExceed)」を保存する
  //isExceedがfalse->trueになったときに通知することで、超えた瞬間に1回だけ通知を送るようにする。
  var isExceeded = getPriceExceeded();

  // worldcoinの価格を取得
  var priceJPY = getWorldcoinPriceJPY();

  // 価格が基準値を超えているか判定
  if (priceJPY >= MAX_PRICE && isExceeded == "false") {
    Logger.log("Worldcoinの現在の価格は ¥" + MAX_PRICE + "を超えています。");
    sendEmail("riku2004@gmail.com", MAX_PRICE, MIN_PRICE, priceJPY);
    setPriceExceeded(true);
    return true;
  }
  else if (priceJPY <= MIN_PRICE && isExceeded == "false") {
    Logger.log("Worldcoinの現在の価格は ¥" + MIN_PRICE + "を下回っています。");
    sendEmail("riku2004@gmail.com", MAX_PRICE, MIN_PRICE, priceJPY);
    setPriceExceeded(true);
    return true;
  }
  else if (isExceeded == "true"){
    setPriceExceeded(false);
  }
  return false;
}

function getPriceExceeded() {
  var scriptProperties = PropertiesService.getScriptProperties();
  var value = scriptProperties.getProperty('isExceeded');
  return value;
}

function setPriceExceeded(isExceeded){
  var scriptProperties = PropertiesService.getScriptProperties();
  scriptProperties.setProperty('isExceeded', isExceeded);
}


```

## ステップ４: 定期的に監視するためのトリガーの設定

このプログラムを5分ごとに実行するようGoogle Apps Scriptのトリガーを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2192833/258a6200-d233-0ca5-cd81-c558a5fe7795.png)

以上で、完成です。

このAPIは月に1万回までという制限があるのですが、
5分に１回のペースの場合、12[回/時間]x24[時間]x30[日/月]=**8640**[回/月]となるので、制限内で安心して価格の監視を行うことができます。


## まとめ

Worldcoinの価格を監視し、特定の価格を超えた際に自分のiPhoneにメールで通知するシステムを作りました。この方法はWorldcoinに限らず、他の仮想通貨や株価などにも応用可能です。ぜひ自分なりにアレンジして、便利に使ってみてください！

# 追記
### 100の位の数字が変わったら通知するバージョンの方が使い勝手が良かったです。
1399 -> 1400
のように100の位の数字が変わったときに通知するシステムも作ってみました。
このシステムはいちいち閾値を設定する必要がないのでこちらの方が使い勝手が良かったです。

```javascript
function getWorldPriceJPY(){
  //省略...
}
function monitorWorldcoinPriceJPY() {
  //price = 1456 -> priceThreshold = 14
  //100の位以上を保存する。この値が変動した時にユーザーに通知
  var priceThreshold = int(getPriceThreshold());
  // worldcoinの価格を取得
  var priceJPY = getWorldcoinPriceJPY();
  var sub_priceJPY = int(priceJPY / 100);
  Logger.log("sub_priceJPY:" + sub_priceJPY);
  Logger.log("priceThreshold:" + priceThreshold);
  // 価格が基準値を超えているか判定
  if (sub_priceJPY != priceThreshold) {
    const _isUp = sub_priceJPY > priceThreshold;
    if(_isUp){
      Logger.log("Worldcoinの現在の価格は ¥" + ((priceThreshold+1) * 100) + "を超えています。");
    }else{
      Logger.log("Worldcoinの現在の価格は ¥" + (priceThreshold * 100) + "を下回りました");
    }
    sendEmail("riku2004@gmail.com", priceJPY, _isUp);
    setPriceThreshold(sub_priceJPY);
    return true;
  }
  return false;
}

function getPriceThreshold() {
  var scriptProperties = PropertiesService.getScriptProperties();
  var value = scriptProperties.getProperty('priceThreshold');
  return value;
}

function setPriceThreshold(priceThreshold){
  var scriptProperties = PropertiesService.getScriptProperties();
  scriptProperties.setProperty('priceThreshold', priceThreshold);
}

function int(number){
  return parseInt(number, 10);
}


function sendEmail(email, price, isUp) {
  var to = email; // 送信先のメールアドレス
  var subject; // メールの件名
  var body; // メールの本文（HTML形式）
  var sub_price = int(price / 100) * 100;
  if (isUp) {
    subject = "Worldcoinの価格が ￥" + sub_price + " を超えました";
    body = "<p>" + subject + "</p><p>現在の価格: WLD <strong>￥" + price.toFixed(2) + "</strong></p>";
  } else {
    subject = "Worldcoinの価格が ￥" + (sub_price + 100) + " を下回りました";
    body = "<p>" + subject + "</p><p>現在の価格: WLD <strong>￥" + price.toFixed(2) + "</strong></p>";
  }
  // メールを送信（HTML形式の本文を使用）
  MailApp.sendEmail({
    to: to,
    subject: "【WLD】" + subject,
    htmlBody: body
  });
  
  // オプションとして、送信後にログを出力することもできます
  Logger.log("メールを送信しました: 宛先=" + to);
}

```
## おまけ
### メールが届いたらWorldAppが自動で開くようにする
iPhoneのショートカットのオートメーションを使うと、メールが届いた時にアプリを開くというようなこともできます！
![IMG_4613.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2192833/32aa78c6-3051-53f1-1c97-375335d517d1.jpeg)
![IMG_4614.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2192833/741e9f1a-60f1-6c42-ba4e-fbb3a74da561.png)