#なんで作ったの?
この記事を見て、自分もQiita Organizationランキングをチェックできるものが欲しい・・
と思いたったので、自前のSlackBotにスクレイピングを利用して投稿するようにしてみた。
#何を使用したの?
・Google App Script
※SlackへMSGを送る部分は、右記ライブラリ使用→SlackApp
・Slack
#ソースコードは?
以下のソースコードより、Organizationランキング(週間、月間)の取得を行なっております。
GoogleAppScriptの時刻起動トリガーを指定してすれば、定刻起動も可能です。
※トリガーの設定方法は本記事では省略してます。(ぽちぽち簡単に設定できます。)
ソースコード
//メイン
function main(){
var msg = qiitaOrgGet()
sendSlack(msg)
}
//qiita organizationのスクレイピングと文字列の整形を行う。
function qiitaOrgGet(){
//スクレイピングURL
var url = ['https://qiita.com/organizations?sort=default' //週間
,'https://qiita.com/organizations?sort=activity_stats_total'] //月間
//organizationURL連結用
var orgurl = 'https://qiita.com/organizations/'
//organization名取得用パース文字
var from1 = '<strong class="ol-Item_name" itemprop="name"><a href='
var to1 = '</a></strong><p class="ol-Item_description" itemprop="description">'
//投稿数取得用パース文字
var from2 = '<div class="ol-Item_postNum mr-1of2">'
var to2 = '</div>'
//orgnizaton情報格納用
var orglist = [[''],['']]
//emoji変換用
var emoji = [':first_place_medal:',':second_place_medal:',':third_place_medal:',':four:',':five:',':six:',':seven:',':eight:',':nine:',':keycap_ten:']
//slackmsg用
var msg = '*Qiita Organization投稿ランキングチェッカー*' + String.fromCharCode(10) + '順位、投稿数、Organization名' + String.fromCharCode(10)
//スクレイピング&データ加工
for(var i in url){
var html = UrlFetchApp.fetch(url[i]).getContentText()
var name = Parser(html,from1,to1)
var postCnt = Parser(html,from2,to2)
//事後処理
for(var j in name){
orglist[i].push([i
,name[j].slice(name[j].indexOf('>')+1)
,orgurl + name[j].slice(name[j].indexOf('s/')+2
,name[j].indexOf('>')-1)
,postCnt[j]])
}
}
//Slack用にMSG整形
for(var i in orglist){
for(var j=1;j<=10;j++){
if(i == 0 && j == 1){
msg = msg + ' _*週間ランキング*_' + String.fromCharCode(10)
}else if(i == 1 && j == 1){
msg = msg + String.fromCharCode(10) +' *月間ランキング*' + String.fromCharCode(10)
}
msg = msg + ' ' + emoji[j-1] + ' ` ' + orglist[i][j][3] + '` ' + '<' + orglist[i][j][2] + '|' + orglist[i][j][1] + '>' + String.fromCharCode(10)
}
}
Logger.log(msg)
return msg
}
//直前(from)、直後(to)の文字列で囲われたデータを取得する。
function Parser(data,from,to){
/*
data ・・ パース対象の文字列が含まれるテキストデータ
from ・・ パース対象の文字列の直前のテキストを指定
to ・・ パース対象の文字列の直後のテキストを指定
from,toで囲われた文字を全て検索して配列に格納します。
*/
//初期値
var tmp = []
var tmpindex
var fromindex = data.indexOf(from)
var toindex = data.indexOf(to)
if(fromindex != -1){
for(var i=0;i<=data.length;i++){
//後続あるなし判定
if (toindex == -1 || fromindex == -1) {
break;
}
//from < to なら代入
if(fromindex + from.length < toindex){
tmp.push(data.slice(fromindex + from.length,toindex))
}
tmpindex = toindex
//後続indexサーチ
fromindex = data.indexOf(from,tmpindex)
toindex = data.indexOf(to,tmpindex + 1)
}
}
//Logger.log(tmp)
return tmp
}
//SlackへMSG送信(lib_SlackApp使用)
function sendSlack(ToSlackMsg){
var slackApp = SlackApp.create('TOKENKEY')//任意のTOKENKEY
var icon = ':ICON名称:'//任意のアイコン名
var options = {
icon_emoji: icon,
username: "BOT名称"//任意のBot名
}
slackApp.postMessage('#チャンネル', ToSlackMsg, options);//任意のチャンネル名
}
#実際の出力結果は?
以下の形式で、1位〜10位までの週間、月間それぞれのランキングの
順位、Qiita投稿数、Organization名がBotに通知されます。
また、各Organization名には各詳細ページへのリンクを付与している形式で出力されます。
※今回、Slackを投稿する部分で、attachmentsを使用していないので
元ネタに存在する、横棒は省略してます。
#感想は?
GAS+Slackは無料でBotを作って遊ぶには最高の環境ですね。