2018/04/01 ブログのテーマをcocoonに変更しました。
スポンサーリンク

うわっ…私のはてブ数、低すぎ…?GASを使って、はてブ数を監視する方法!

スポンサーリンク

やった!はてブついた!!今夜はドン勝だ!!よしセルクマしよ

はてなブックマークが滅多につく事がない当ブログは、ブックマークされると大変嬉しいです。(PV数も伸びるし)

今回は僕が日々使ってるはてぶ監視プログラムを紹介したいと思います。

はてブ数の監視する方法

今までの監視方法(僕の場合)

IFTTTを使って記事に1つ目のはてブがついたらメールを受け取る方法
IFTTTというWebサービスを使って、ブログ記事に最初のはてなブックマークがついたらメールで受け取る方法をご紹介します。

こちらの記事を参考にして、初めてはてなブックマークをされたら、Slackに通知されるような仕組みを作っていました。

ですが、いろいろ欠点がありまして...具体的には

  • 最初のブックマークしかわからない
    • 2つ、3つブックマークされてもわからない
  • 通知が遅い
    • ブックマークされてから約10分で通知されます。

この2点から、自分で監視するプログラムを書こうと思いました。

今回、はてブ数を監視する方法(仕組み)

はてなブックマーク件数取得APIを使用します。

例えば、当ブログのLINE BOTの記事のはてブ数を取得する際

http://api.b.st-hatena.com/entry.counts?url=https://routecompass.net/line-bot/

のように http://api.b.st-hatena.com/entry.counts の API エンドポイントにクエリパラメータ url を付与し GET リクエストを送ります。

 

結果はこのようなJSON形式で返ってきます。(ご自身のブラウザでも確認する事ができます。)

 

この仕組みを利用し、1日に何度もはてブ数を取得します。(僕の場合、5分ごとに取得しています。)

 

前回取得したはてブ数と比較し、変化があった場合に通知するような仕組みを作っていきます。

GASとは?

GASとはGoogle Apps Scriptの略です。

Google様が提供している「Gmail」や「スプレッドシート」などのアプリをJavaScriptで操作し、組み合わせたり、単体でも動かす事が出来ます。

今回は主にスプレッドシートと組み合わせるので、ExcelのVBAと思っていただくと、想像しやすいかもしれません。

当ブログでも2回、GASの活用例を紹介させて頂きました。

[GAS]全米が泣いた親不孝 LINE Botを作ってみた
どーも最近反抗期のオーカワ(@okawa_compass)です。以前親に生存確認を送るBOTを作りました。 IFTTTとLINE Notiftを使い、毎朝8:00に元気ですと送信するBOTでした。 まぁ速攻でバレたんです...
【GAS】Google Apps Scriptで作るTwitter Bot(晩飯 Bot)
いつも当ブログを見ていただいてる読者様からこんなリクエストがありました!! 実際に作っていこうと思います!! 作る機能 Twitterからのリクエストなので、Twitterのbotを作っていきます。 ...

GASの優れている点は

  • サーバレスで開発が可能
  • 無料
  • 定期実行の設定が容易

勿論まだまだ優れている点は沢山ありますが、この辺で......

GASはとっても便利です。いろいろ制限もありますが……

【容量制限】これは困った。GAS(Google Apps Script)の落とし穴
最近GAS(Google Apps Script)にハマっているオーカワ(@okawa_compass)です。 当ブログでも既に2回出ていますね♪GASを使ったプログラムは今後も紹介する予定です。 とても便利なも...

事前準備(スプレッドシート編)

スプレッドシートを作成していきます。

Google Driveにアクセスをします。

もし、Googleのアカウントを持っていなかったら、この時点で作成します。

スプレッドシートの作成

スプレッドシートを作成する場所はどこでも大丈夫ですが、今回はGASというフォルダーを作り、その中にスプレッドシートを作成していきます。

  1. 右クリックから新しいフォルダをクリック
  2. フォルダを作り、フォルダの中で右クリック
  3. Google スプレッドシートを選択

ファイル名はなんでも大丈夫です。

シート名の変更

スプレッドシートの左下にシート1というのがあると思います。

そちらを「hatena」に変更します。シート名の上から右クリックで変更が出来ます。

こちらは絶対に忘れないでください(忘れると動きません)

データの入力

必要なデータを入力します。

上の画像のように、入力をお願いします。(同じセルに入力してください。)

通知設定

はてブの通知にはSlackとメールを用意しました。

Slackで通知を受け取りたい場合

Slack APIをセルF1に入力します。(xoxp-から始まる文字列です。)

SlackのAPIがわからない場合はこちらのリンクを参考にしてください。

Slack APIのTokenの取得・場所 - Qiita
# 追記部分 こちらの記事はレガシーなトークンを使っていますので、 (
メールで通知を受け取りたい場合

セルF2に通知を受けたいメールアドレスを入力してください。

例えばGoogle垢に紐づいてるメールアドレスが、unko@gmail.comの場合、unko@gmail.comから通知を受け取りたいメールアドレスに送信をします。

勿論、Google垢に紐づいてるメールアドレスでも大丈夫です。(自分から自分に送る事になります。)

メールアドレスの間違いだけは気をつけてください。

どちらも受け取りたい場合

上の設定を参考に、2つとも設定してください。

ようやくGAS(プログラム)の設定

ツールから、スクリプトエディタをクリックします。

クリックすると、このような画面になります。

コードの中に、function~~~など書いてありますが、全部消して真っ白にしてください。

ライブラリの追加

SlackをGASで扱う為にSlackAppのライブラリを追加します。いつもお世話になっております。

Slackで通知設定を受けない場合も、後々プログラムでエラーが起こるので、設定をお願いします。

 

リソース→ライブラリを選択します。(プロジェクト名を聞かれるので、そのままでもいいですし、名前を変えて頂いても構いません。)

ライブラリキーの場所に

M3W5Ut3Q39AaIwLquryEPMwV62A3znfOO

を入力し、追加を押します。

 

バージョンを指定し(僕の場合は22を選択しました)、保存を押します。

プログラムの貼り付け

以下のプログラムを貼り付けます。

function main () {//main関数
var hatena = new Hatena ();
var bookmark = hatena.get_bookmark ();
hatena.kaki(bookmark);
}
Hatena = function (){//コンストラクタ
this.bk = SpreadsheetApp.getActiveSpreadsheet();
this.sheet = this.bk.getSheetByName("hatena"); //hatenaというシートを取得
this.slack = this.sheet.getRange(1, 6).getValue();//slack_api取得
this.mail = this.sheet.getRange(2, 6).getValue();//メールアドレスを取得
this.last_row = this.sheet.getLastRow();  //最終行を検出
if (!this.slack && !this.mail) return;
}
Hatena.prototype.get_bookmark = function (){//bookmarkの取得
var url = [];
var url_50 = 0;
var url_count = 0;
var hatena_api_url = "http://api.b.st-hatena.com/entry.counts?url=";//複数のurl
for (var i = 3; i <= this.last_row; i++) {  //最終行までurlを取得
if (url_count >= 50){//一度に50個まで
url_count = 0;
url_50 += 1;
}
if (url_count == 0) url[url_50] = this.sheet.getRange(i,1).getValue();//最初だけは
else url[url_50] += '&url=' + this.sheet.getRange(i,1).getValue();//urlを足して行く
url_count += 1;
}
var url_json = {};
for (var i = 0; i <=url.length; i++) {
var api_url = hatena_api_url + url[i];
try {
var response = UrlFetchApp.fetch(api_url);//はてなapiに投げる(極まれにエラー出る)  
var json=JSON.parse(response.getContentText());//jsonを読み込む
for(key in json) url_json[key] = json[key];//結合
}
catch (e) {
return;
}
}
return url_json;
}
Hatena.prototype.kaki = function (url_json){//bookmarkとタイトルを上書きする
if (url_json) for (var i = 3; i <= this.last_row; i++) {
this.url = this.sheet.getRange(i,1).getValue();
this.old_bookmark = this.sheet.getRange(i, 3).getValue();
this.new_bookmark = url_json[this.url];
this.kp = this.new_bookmark - this.old_bookmark;//差分
if (this.old_bookmark){
this.title = this.sheet.getRange(i, 2).getValue();//タイトルをシートから取得
if (this.kp > 0) {
this.sheet.getRange(i, 3).setValue(this.new_bookmark);//ブックマークを上書き
if (this.slack) this.send_slack();
if (this.mail) this.send_mail();
}
else if (this.kp < 0){//ブックマークが減ったら
this.sheet.getRange(i, 3).setValue(this.new_bookmark);//ブックマークを上書き
if (this.slack) this.send_slack();
if (this.mail) this.send_mail();
}
}
else {//初めてのbookmark
if (this.new_bookmark != 0) {
this.title = this.get_title();
this.sheet.getRange(i, 2).setValue(this.title);//タイトルを挿入
this.sheet.getRange(i, 3).setValue(this.new_bookmark);//ブックマークを上書き
if (this.slack) this.send_slack();
if (this.mail) this.send_mail();
}
}
}
}
Hatena.prototype.get_title = function (){ //タイトルを取得する
try{
var api_url = "http://b.hatena.ne.jp/entry/jsonlite/?url=" + this.url;
var response = UrlFetchApp.fetch(api_url);//はてなapiに投げる(極まれにエラー出る)     
}
catch (e){//エラーだった場合
return;
}
if (response != "null"){//結果が帰ってくれば
var json=JSON.parse(response.getContentText());//jsonを読み込む
var title = json["title"];//タイトルを取得
}
return title;
}
Hatena.prototype.send_slack= function (){ //タイトルを取得する
var kp_mes;
if (this.kp > 0) kp_mes = "増えました。";
else {
kp_mes = "減りました。";
this.kp = -this.kp;//減った時は"-"をかける
}
var slack_title = "*<" + this.url + "|" + this.title + ">*"//タイトルをリンクにする
var mes = slack_title + "\n" + ">はてブ数が" + " `" + this.kp + "` " + kp_mes +"現在" + this.new_bookmark + "はてブ。";
this.postSlackMessage(mes);//送れ
}
Hatena.prototype.postSlackMessage = function(mes) {//slackに投稿する関数
var slackApp = SlackApp.create(this.slack); //SlackApp インスタンスの取得
var options = {
channelId: "#general", //チャンネル名
userName: "bot", //投稿するbotの名前
message: mes //投稿するメッセージ
};
slackApp.postMessage(options.channelId, options.message, {username: options.userName});//送信
}
Hatena.prototype.send_mail = function (){//メールを送る
var kp_mes;
if (this.kp > 0) kp_mes = "増えました。";
else {
kp_mes = "減りました。";
this.kp = -this.kp;//減った時は"-"をかける
}
var mail_title = this.new_bookmark + "はてブ---" + this.title;
var mes = this.title + "\n" + "はてブ数が" + this.kp + kp_mes +"現在" + this.new_bookmark + "はてブ。";
MailApp.sendEmail(this.mail, mail_title, mes);
}

プログラムの承認

プログラムを貼り付けたら、保存ボタンを押します。

そして実行(再生)ボタンを押します。

 

そしたらこのようなウインドが出てくると思います。

「許可を確認」を押し、次の画面でも許可をしてください。

これが終われば設定は終了です。

お疲れ様でした。

この時点ではプログラムを実行しても、何も起こらないのが正解です。

監視したいURLを追加してもう一度実行してみよう

一番左のURLの欄に、はてブの監視をしたいURLを追加していきましょう。(赤色の罫線は見やすくする為で、特に意味はありません。)

例えばこんな感じ。

URLを追加したらもう一度実行をします。

一番下のurlにはてブ数もタイトルも表示されないのは、まだ一度もはてブがされていないからです。

通知の設定も出来ていれば、通知が来るはずです。

  • Slackの場合

  • メールの場合

定期的にプログラムを実行するように設定しよう!

今のままだと、プログラムの実行ボタンを押さないと、実行(はてブを監視)する事が出来ないので、定期的にプログラムを実行出来るようにします。

GASにはトリガー機能がありますので、それを使っていきます。

トリガーボタンを押します。

今は何もトリガーが設定されていないので、追加をします。

プログラムが自動起動するように設定します。

今回の場合は5分ごとにプログラムが自動実行するような仕組みですね。

自動実行する間隔はご自身でご自由に設定してください。

保存をして完了です。ね、簡単でしょ?

 

あとは勝手にプログラムがはてブ数を監視してくれます。

はてブ数が変われば、通知をしてくれます。やったねたえちゃん

自動で監視するURLを追加する方法

ブログに記事を投稿してから、URL追加するのダルいんだけど💢


オーカワ
よーし、記事を投稿したから、URL追加しよっと

オーカワ
ってダルいわ!!自動化するぞ

ってな訳で、自動化してみました~。

自動でURLを追加する仕組み

はてなブックマークで自分のブログのドメインを検索し、すべてを見ると、はてなブックマークされている記事の一覧が表示できます。

当ブログ(https://routecompass.net)の場合、こんな感じですね。

今回はこちらのRSSフィードを使用します。

RSSフィードは

http://b.hatena.ne.jp/entrylist?url= + "自分のブログのドメイン" +&mode=rss&sort=eid

で取得します。

 

当ブログだとこんなURLです。

http://b.hatena.ne.jp/entrylist?url=https://routecompass.net&mode=rss&sort=eid

取得できるRSSフィードを解析して、URLのみを取得します。(画像は全体の一部です。)

作成したプログラム

2行目のドメインを変更した後、先ほどコピペしたプログラムの下にコピペしてください。

function add_url (){//urlを自動で追加
var url = "https://routecompass.net";//ここに自分のドメイン
var atom = XmlService.getNamespace('http://purl.org/rss/1.0/');
var feed_url = "http://b.hatena.ne.jp/entrylist?url=" + url + "&mode=rss&sort=eid";
try {
var document = XmlService.parse(UrlFetchApp.fetch(feed_url).getContentText());
}
catch (e) {
return;
}
var items = document.getRootElement().getChildren('item', atom);
var hatebu_url = [];
for(var i = 0; i < items.length; i++) {
hatebu_url.push(items[i].getChildText("link", atom));//urlを取得
}
var bk = SpreadsheetApp.getActiveSpreadsheet();
var sheet = bk.getSheetByName("hatena"); //hatenaというシートを取得
var last_row = sheet.getLastRow();  //最終行を検出
var sheet_url = [];
for (var i = 3; i <= last_row; i++) sheet_url.push(sheet.getRange(i,1).getValue());
for (var i = 0; i < hatebu_url.length; i++) {
if (sheet_url.indexOf(hatebu_url[i]) == -1) {
sheet.getRange(sheet.getLastRow() + 1, 1).setValue(hatebu_url[i]);//シートにurlがなかったら追加する
} 
}
}

使い方

コピペが終わりましたら、保存して、add_urlを実行します。

URLを入力していなくても、勝手に追加されます。(既にあるURLは追加されません)

これも定期的にプログラムを実行するように設定しよう!

初めてはてブされたら、URLを追加する仕組みなので、監視する必要があります。

記事を投稿したら、URLを追加する仕組みではありませんので。

 

これも5分ごとに実行するようにしました。

トリガーの設定から、

このように設定をしました。

最終的なコード

一応載せときます。

function main () {//main関数
var hatena = new Hatena ();
var bookmark = hatena.get_bookmark ();
hatena.kaki(bookmark);
}
Hatena = function (){//コンストラクタ
this.bk = SpreadsheetApp.getActiveSpreadsheet();
this.sheet = this.bk.getSheetByName("hatena"); //hatenaというシートを取得
this.slack = this.sheet.getRange(1, 6).getValue();//slack_api取得
this.mail = this.sheet.getRange(2, 6).getValue();//メールアドレスを取得
this.last_row = this.sheet.getLastRow();  //最終行を検出
if (!this.slack && !this.mail) return;
}
Hatena.prototype.get_bookmark = function (){//bookmarkの取得
var url = [];
var url_50 = 0;
var url_count = 0;
var hatena_api_url = "http://api.b.st-hatena.com/entry.counts?url=";//複数のurl
for (var i = 3; i <= this.last_row; i++) {  //最終行までurlを取得
if (url_count >= 50){//一度に50個まで
url_count = 0;
url_50 += 1;
}
if (url_count == 0) url[url_50] = this.sheet.getRange(i,1).getValue();//最初だけは
else url[url_50] += '&url=' + this.sheet.getRange(i,1).getValue();//urlを足して行く
url_count += 1;
}
var url_json = {};
for (var i = 0; i <=url.length; i++) {
var api_url = hatena_api_url + url[i];
try {
var response = UrlFetchApp.fetch(api_url);//はてなapiに投げる(極まれにエラー出る)  
var json=JSON.parse(response.getContentText());//jsonを読み込む
for(key in json) url_json[key] = json[key];//結合
}
catch (e) {
return;
}
}
return url_json;
}
Hatena.prototype.kaki = function (url_json){//bookmarkとタイトルを上書きする
if (url_json) for (var i = 3; i <= this.last_row; i++) {
this.url = this.sheet.getRange(i,1).getValue();
this.old_bookmark = this.sheet.getRange(i, 3).getValue();
this.new_bookmark = url_json[this.url];
this.kp = this.new_bookmark - this.old_bookmark;//差分
if (this.old_bookmark){
this.title = this.sheet.getRange(i, 2).getValue();//タイトルをシートから取得
if (this.kp > 0) {
this.sheet.getRange(i, 3).setValue(this.new_bookmark);//ブックマークを上書き
if (this.slack) this.send_slack();
if (this.mail) this.send_mail();
}
else if (this.kp < 0){//ブックマークが減ったら
this.sheet.getRange(i, 3).setValue(this.new_bookmark);//ブックマークを上書き
if (this.slack) this.send_slack();
if (this.mail) this.send_mail();
}
}
else {//初めてのbookmark
if (this.new_bookmark != 0) {
this.title = this.get_title();
this.sheet.getRange(i, 2).setValue(this.title);//タイトルを挿入
this.sheet.getRange(i, 3).setValue(this.new_bookmark);//ブックマークを上書き
if (this.slack) this.send_slack();
if (this.mail) this.send_mail();
}
}
}
}
Hatena.prototype.get_title = function (){ //タイトルを取得する
try{
var api_url = "http://b.hatena.ne.jp/entry/jsonlite/?url=" + this.url;
var response = UrlFetchApp.fetch(api_url);//はてなapiに投げる(極まれにエラー出る)     
}
catch (e){//エラーだった場合
return;
}
if (response != "null"){//結果が帰ってくれば
var json=JSON.parse(response.getContentText());//jsonを読み込む
var title = json["title"];//タイトルを取得
}
return title;
}
Hatena.prototype.send_slack= function (){ //タイトルを取得する
var kp_mes;
if (this.kp > 0) kp_mes = "増えました。";
else {
kp_mes = "減りました。";
this.kp = -this.kp;//減った時は"-"をかける
}
var slack_title = "*<" + this.url + "|" + this.title + ">*"//タイトルをリンクにする
var mes = slack_title + "\n" + ">はてブ数が" + " `" + this.kp + "` " + kp_mes +"現在" + this.new_bookmark + "はてブ。";
this.postSlackMessage(mes);//送れ
}
Hatena.prototype.postSlackMessage = function(mes) {//slackに投稿する関数
var slackApp = SlackApp.create(this.slack); //SlackApp インスタンスの取得
var options = {
channelId: "#general", //チャンネル名
userName: "bot", //投稿するbotの名前
message: mes //投稿するメッセージ
};
slackApp.postMessage(options.channelId, options.message, {username: options.userName});//送信
}
Hatena.prototype.send_mail = function (){//メールを送る
var kp_mes;
if (this.kp > 0) kp_mes = "増えました。";
else {
kp_mes = "減りました。";
this.kp = -this.kp;//減った時は"-"をかける
}
var mail_title = this.new_bookmark + "はてブ---" + this.title;
var mes = this.title + "\n" + "はてブ数が" + this.kp + kp_mes +"現在" + this.new_bookmark + "はてブ。";
MailApp.sendEmail(this.mail, mail_title, mes);
}
function add_url (){//urlを自動で追加
var url = "https://routecompass.net";//ここに自分のドメイン
var atom = XmlService.getNamespace('http://purl.org/rss/1.0/');
var feed_url = "http://b.hatena.ne.jp/entrylist?url=" + url + "&mode=rss&sort=eid";
try {
var document = XmlService.parse(UrlFetchApp.fetch(feed_url).getContentText());
}
catch (e) {
return;
}
var items = document.getRootElement().getChildren('item', atom);
var hatebu_url = [];
for(var i = 0; i < items.length; i++) {
hatebu_url.push(items[i].getChildText("link", atom));//urlを取得
}
var bk = SpreadsheetApp.getActiveSpreadsheet();
var sheet = bk.getSheetByName("hatena"); //hatenaというシートを取得
var last_row = sheet.getLastRow();  //最終行を検出
var sheet_url = [];
for (var i = 3; i <= last_row; i++) sheet_url.push(sheet.getRange(i,1).getValue());
for (var i = 0; i < hatebu_url.length; i++) {
if (sheet_url.indexOf(hatebu_url[i]) == -1) {
sheet.getRange(sheet.getLastRow() + 1, 1).setValue(hatebu_url[i]);//シートにurlがなかったら追加する
} 
}
}

 

感想

GASは本当に便利です。是非皆様も使ってみてください!!

本当は初めてブックマークしてもらったら、自動でセルクマしたかったんですが、はてなの利用規則に引っかかるので、出来ませんでした。プログラムだと1行追加するだけで実現可能な手軽さなのに。

 

僕は5分ごとにプログラムを実行していますが、もっと精度が欲しい場合は1分ごとに実行なんてのも出来ます。ただGASには容量制限があるので気をつけてください。

【容量制限】これは困った。GAS(Google Apps Script)の落とし穴
最近GAS(Google Apps Script)にハマっているオーカワ(@okawa_compass)です。 当ブログでも既に2回出ていますね♪GASを使ったプログラムは今後も紹介する予定です。 とても便利なも...

 

おまけ

表を最初に作っといて、プログラムを実行すると”それっぽい”

The following two tabs change content below.

オーカワ

GCPばっか触ってるにゃーんエンジニア こちらのブログでも活躍中

コメント