
『プログラミング』noteの抽出ツールを作ってみたいのじゃ(2)
良いこと思いついた!
あ! 以下記事の続きです。
前回の記事では、現状いい方法がわからないという感じでしたが、ある方法を思いつきました。
「note」に登録する際には必ずメールアドレスを設定しますよね。私はGmailで登録しているのですが、このメールに届く通知が使えるんじゃないかと思ったんです。
■説明するロジックが使える条件
・Gmailでnoteに登録していること
・通知を受け取る設定にしていること
通知設定は「アカウント設定」のここです。
noteAPIとPythonで作ろうと考えていたのですが、別の方法を取ることになります。目的は「抽出ツールを作る」ことなので、手段は変更してもよいと思います。ちなみにこのロジックのメリットは以下です。
■メリット
・note上でプログラムを稼働しないため
規約に違反することがない
・他人のデータを参照できないため
方法を公開しても悪用の心配がない
🌸作った機能
・特定記事に「スキ」をしたユーザーの
「名前」と「ユーザーページURL」を抽出
・それをスプレッドシートに書き込み
応用すれば、「コメント」「埋め込み紹介」「サポート」などをしてくれたユーザーを自動で抽出可能になります。コメントを多くくれている人ランキングなんかもすぐ作れるようになります。
🌸実行イメージ
まずはイメージを紹介する。
詳細説明は後ほど。
▼スプレッドシートに以下を指定
1 : 記事IDを指定
2 : 記事タイトル指定
実行すると……
「スキ」を付けたユーザーがスプレッドシートに書き込まれます。
こんな感じ。「対象1記事のスキを全件」取得できます。
🌸コード公開
Google Apps Scriptを使います。
使用方法は後ほど説明。
function sukiFunction() {
//アクティブなスプレッドシートを取得
ss = SpreadsheetApp.getActiveSpreadsheet();
//シート名「値を指定」を選択
sheet = ss.getSheetByName('値を指定');
//シート名「値を指定」のA2にある値を取得(記事ID)
id = sheet.getRange('A2').getValue();
//シート名「値を指定」のB2にある値を取得(記事title)
title = sheet.getRange('B2').getValue();
//シート名「test」をアクティブにする
sheet_test = ss.getSheetByName("test");
sheet_test.activate();
Logger.log('id:' + id);
Logger.log('title:' + title);
// 検索条件に該当するスレッド一覧を取得
var threads = GmailApp.search('subject:スキのおしらせ -label:処理済み ' + title);
// スレッドを一つずつ取り出す
threads.forEach(function(thread) {
// スレッド内のメール一覧を取得
var messages = thread.getMessages();
// メールを一つずつ取り出す
messages.forEach(function(message) {
// メール本文を取得
var plainBody = message.getPlainBody();
// メール件名を取得
subject = message.getSubject();
var from = message.getFrom();
//送信元のアドレスが「noreply@note.mu」のみを対象とする。
if(!from.match("noreply@note.mu")){
return;
}
//指定した記事IDが含まれているものだけを対象
if(!plainBody.match(id)){
return;
}
//コメントへのスキは除外
if(subject.match("コメントへのスキのおしらせ")){
return;
}
//メール本文を改行ごとに区切る
var arr_n = plainBody.split('\n');
////////スキしたユーザーのURLを取り出し////////
//?nt=が始まる文字位置を検索
var str_index = arr_n[3].indexOf("?nt=");
//userのurlを取り出し。
var user_url = arr_n[3].slice(1,str_index);
////////スキしたユーザーの名前を取り出し////////
//<httpsが始まる文字位置を検索
var str_index = arr_n[5].indexOf("<https");
//userネームを取り出し。
var user_name = arr_n[5].slice(0,str_index-1);
////////スプレッドシートに書き出し////////
// 最終行を取得
var lastRow = sheet_test.getLastRow() + 1;
// セルを取得して値を転記
sheet_test.getRange(lastRow, 1).setValue(user_name);
sheet_test.getRange(lastRow, 2).setValue(user_url);
});
// スレッドに処理済みラベルを付ける
var label = GmailApp.getUserLabelByName('処理済み');
thread.addLabel(label);
});
// 最終行を取得
var lastRow = sheet_test.getLastRow();
//重複削除用に範囲を指定
var range = ss.getRange("A:B");
//重複行を削除する
range.removeDuplicates([2]);
}
🌸ラベル準備
noteに登録しているGmailを開く
⇩
左側にある「もっとみる」
⇩
新しいラベルを作成
⇩
新しいラベル名を入力に
「処理済み」を入力
⇩
作成
🌸使用方法
■説明するロジックが使える条件
・Gmailでnoteに登録していること
・通知を受け取る設定にしていること
■1
noteに登録しているGmailのアカウントでログインし、ドライブを開く。
■2
左側「新規」クリック
■3
「スプレッドシート」をクリック
■4
「ツール」から「スクリプトエディタ」をクリック
■5
以下画像になっていたらOK
エラーの人は以下を行ってください
■エラー画面になる人
・グーグルドライブ画面で
右上のアカウントアイコンをクリック
・「すべてのアカウントからログアウトする」クリック
・noteに登録しているグーグルアカウントでログイン
・スクリプトエディタが開けるようになると思います
エラーは複数アカウントでログインしている場合に発生します。スクリプトエディタはデフォルトアカウントで開こうとしているのに、別のアカウントでログインしているときに発生するようです。
■6
以下を削除。
function myFunction() {
}
■7
以下コードを全部コピーして
「スクリプトエディタ」に貼り付けてください。
function sukiFunction() {
//アクティブなスプレッドシートを取得
ss = SpreadsheetApp.getActiveSpreadsheet();
//シート名「値を指定」を選択
sheet = ss.getSheetByName('値を指定');
//シート名「値を指定」のA2にある値を取得(記事ID)
id = sheet.getRange('A2').getValue();
//シート名「値を指定」のB2にある値を取得(記事title)
title = sheet.getRange('B2').getValue();
//シート名「test」をアクティブにする
sheet_test = ss.getSheetByName("test");
sheet_test.activate();
Logger.log('id:' + id);
Logger.log('title:' + title);
// 検索条件に該当するスレッド一覧を取得
var threads = GmailApp.search('subject:スキのおしらせ -label:処理済み ' + title);
// スレッドを一つずつ取り出す
threads.forEach(function(thread) {
// スレッド内のメール一覧を取得
var messages = thread.getMessages();
// メールを一つずつ取り出す
messages.forEach(function(message) {
// メール本文を取得
var plainBody = message.getPlainBody();
// メール件名を取得
subject = message.getSubject();
var from = message.getFrom();
//送信元のアドレスが「noreply@note.mu」のみを対象とする。
if(!from.match("noreply@note.mu")){
return;
}
//指定した記事IDが含まれているものだけを対象
if(!plainBody.match(id)){
return;
}
//コメントへのスキは除外
if(subject.match("コメントへのスキのおしらせ")){
return;
}
//メール本文を改行ごとに区切る
var arr_n = plainBody.split('\n');
////////スキしたユーザーのURLを取り出し////////
//?nt=が始まる文字位置を検索
var str_index = arr_n[3].indexOf("?nt=");
//userのurlを取り出し。
var user_url = arr_n[3].slice(1,str_index);
////////スキしたユーザーの名前を取り出し////////
//<httpsが始まる文字位置を検索
var str_index = arr_n[5].indexOf("<https");
//userネームを取り出し。
var user_name = arr_n[5].slice(0,str_index-1);
////////スプレッドシートに書き出し////////
// 最終行を取得
var lastRow = sheet_test.getLastRow() + 1;
// セルを取得して値を転記
sheet_test.getRange(lastRow, 1).setValue(user_name);
sheet_test.getRange(lastRow, 2).setValue(user_url);
});
// スレッドに処理済みラベルを付ける
var label = GmailApp.getUserLabelByName('処理済み');
thread.addLabel(label);
});
// 最終行を取得
var lastRow = sheet_test.getLastRow();
//重複削除用に範囲を指定
var range = ss.getRange("A:B");
//重複行を削除する
range.removeDuplicates([2]);
}
コードの準備ができました!
次はスプレッドシートの準備!!
■8
入力受け取り用のシートを作ります。
シート名 : 値を指定
セルA1 : 対象記事ID
セルB1 : 対象記事タイトル
色とか枠線はお好みで。
■9
結果書き出し用のシートを作ります。
・左下の「+」でシート追加
・シート名「test」
・セルA1「画像参照」
・セルB1「画像参照」
色とか枠線はお好みで。
■10
ついに実行してみる!!!
▼シート「値を指定」で以下を記載
A2 : 記事ID
B2 : 記事タイトル
■記事のIDって何?
記事URLの一番右側の文字列
https://note.com/syakai_hutekigou/n/ここ
※マガジンから開いたりするとURLが変わります。
こんな感じになっていたらOK。
実行ボタンを押すと……
「承認が必要です」が出てきたら「権限を確認」
⇩ ⇩
アカウントの選択 で 自分のアカウント選択
⇩ ⇩
詳細クリック
安全ではないページに移動クリック
プログラムの実行権限を
与えるだけなので安心してください。
⇩ ⇩
右下の「許可」をクリック
Gmailとスプレッドシートを使ってもいいよと許可しています。
これで実行できます!
実行ボタンを押すと……
どんどん書き込んでくれます✨✨
今回のコードは複雑にならないように最低限の機能しかあえて付けていないです。他に追加しようかな~と考えている機能は
▼追加検討中機能
■再実行考慮
現状では、一度処理したものは次回処理しないコードになってます。「追加更新」を目的としているからです。ただ、最初からもういっかい実行してほしいこともあると思います。そこを追加したい。
■書き込み場所
現状「test」シートに出力しておりますが、記事によって自動でシートを作成し出力するようにする。
■複数記事
複数記事について実行できるようにする
■他の反応
サポートやコメント、記事紹介などを抽出
■エラー処理
記事IDなどの未入力チェック。他の考えられるエラーに対する処理。
■デメリットどうするか
記事タイトルを途中で編集することもあると思います。現状、タイトルに編集があった場合は正しい数を取得できなくなっている。
考え始めたらもっとあります。ここで、なぜコードを作成し始めたか思い出してください。以下機能を作りたかったからです。
・記事に「スキ」等を付けたユーザーを抽出
・抽出したデータからリストを作成
・一定時間ごとにプログラムを実行して更新
「スキ」だけですが、2つ目まではできてますね。一定時間ごとも実は可能です。トリガーの設定が可能なので、そこで「15分毎」「1時間毎」など設定できます。
ただ、実行回数には制限があるため気をつけなければいけません。「Gmailは1日何万件まで取得可能」みたいなのがあります。うまくいかないときは制限がかかっていなかも確認してみてください。
作りたかった機能を作るという目的は達成できた気がしますが、どうでしょう(笑)。まぁ「PythonとnoteAPI」で作ったパターンも用意するつもりです。まだどうやるかはわかってないけど、わかり次第更新します。絶対できるはずなので頑張ってみます。
さて、
詳細を知りたい方もいるかもですね。
ここからは各コードの解説です。
……と思いましたが、長くなるので次回に!!!
■更新履歴
■2021年1月3日 10:41更新
新しいラベル作成の説明が抜けていたため、「ラベル準備」を追加した。