5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

nem / symbolAdvent Calendar 2022

Day 8

定期的に Blockchain Symbol のハーベスト通知を取得する

Posted at

こんにちは。 faunsu19000 です。
Blockchain の Symbol でハーベストの履歴を取得する Google Apps Script を作成しました。

自前でサーバーを用意する必要がない為、低コストに導入出来ます。

実行方法

  1. 以下のスクリプトを Google Apps Script へ貼り付けてください
  2. 関数 main の中の address 変数へ監視したいアドレスを入力して下さい
  3. main 関数を実行します

挙動

main 関数を実行すると自動的に30分毎に最新の履歴を取得しに行きます。
もし停止したい場合には stop 関数を実行していただければ止まります。

/**
 * Address を 48桁形式に変換する
 * @param {string} address plain 形式のアドレス
 * @param {string} node node の URL
 */
function getEncodeAddress(address, node) {
  const url = [node, "accounts", address].join("/");
  const res = UrlFetchApp.fetch(url);
  return JSON.parse(res.getContentText()).account.address
}

/**
 * amount を Uint 形式から Int 形式へ変換する。
 * Symbol メインネットの値をハードコートで本関数は作成
 * @param {string} amount
 * @returns {number}
 */
function getIntAmount(amount) {
  return Number(amount) / 1000000;
}

/**
 * トランザクション履歴よりハーベスト履歴のみ取得する。ページネーションは1ページ目のみとする
 * @param {string} address plain 形式のアドレス
 * @param {string} node node の URL
 */
function getHarvestHistory(address, node) {
  const HARVEST_FEE_ENUM = 8515;
  const url = [node, "statements", "transaction"].join("/");
  const encodedAddress = getEncodeAddress(address, node);
  const res = UrlFetchApp.fetch(`${url}?targetAddress=${address}&order=desc`);
  const data = JSON.parse(res.getContentText()).data;
  let harvestHistory = [];
  data.forEach((d => {
    d.statement.receipts.forEach((r => {
      if (r.type === HARVEST_FEE_ENUM && r.targetAddress === encodedAddress) {
        r.targetAddress = address;
        r.amount = getIntAmount(r.amount);
        harvestHistory.push({ height: d.statement.height, ...r });
      }
    }))
  }))
  return harvestHistory;
}

/**
 * Gmail にて自身に対して通知を行う
 */
function sendGmail(data) {
  GmailApp.sendEmail(Session.getActiveUser(), "[通知]ハーベストしました", JSON.stringify(data));
}


/**
 * 取得結果をデータベースへ格納し、新たなデータがあればユーザーへ通知する
 */
function writeDatabase(data) {
  const database = PropertiesService.getUserProperties();
  let oldData = database.getProperty("data");
  if (!oldData) {
    database.setProperty("data", JSON.stringify([]));
    oldData = [];
  } else {
    oldData = JSON.parse(oldData);
  }

  data.forEach(d => {
    if (oldData.every(o => o !== d.height)) {
      oldData.push(d.height);
      GmailApp.sendEmail(Session.getActiveUser(), "[通知]ハーベストしました", JSON.stringify(d, null, 4));
    }
  })

  database.setProperty("data", JSON.stringify(oldData))
}

/**
 * 定期実行をGASに対して設定する
 */
function setTrigger(){
  const database = PropertiesService.getUserProperties();
  const triggerStatus = database.getProperty("trigger");
  if(!triggerStatus){
    const id = ScriptApp.newTrigger("main").timeBased().everyMinutes(30).create();
    database.setProperty("trigger",id.getUniqueId());
  }
}

function stop(){
  const database = PropertiesService.getUserProperties();
  database.deleteProperty("trigger");
  ScriptApp.getScriptTriggers().forEach(e => ScriptApp.deleteTrigger(e));
}


function main() {

  const node = "https://symbolnode.blockchain-authn.app:3001";
  const address = "ここにアドレスを入力してください";

  setTrigger();
  writeDatabase(getHarvestHistory(address, node));

}
5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?