GASでQiitaOrganizationメンバーの新規投稿を自動で拾いChatworkに通知する


はじめに

弊社ARIでは4月から全社員でアウトプットを活性化していく活動を開始しました。その取組みの一貫としてQiitaOrganizationを立ち上げ、みんなで投稿を相互応援しています。この記事を作成している2020年6月6日時点で、Organizationの登録者は23人、エントリ数は49本です。新人や若手層が積極的に投稿してくれているのが嬉しいです。登録者100人目指してがんばります。

さて今回は最近用意したGASのスクリプトのご紹介です。
現在我々はOrganization登録者同士の相互情報共有のため、専用のChatWorkのグループを用意しています。
Qiitaに投稿したらそこで共有して、お互いに応援・盛上げていこうという主旨です。ただ面倒なのと、中には自分から知らせるのが少し恥ずかしいと共有を控えるメンバーもいました。そこでOrganizationの最新エントリをそのChatWorkグループに自動で通知する処理をGAS(GoogleAppsScript)で用意しました。

軽く調べたところ結構似たような記事は多く見つかったので、簡単にできるかなと最初は思いました。ただ実際やってみると、微妙に要件が違う物が多く、完成までそれなりに試行錯誤してしまいました。私が苦労したことは同じ様に苦労する方が出るかも知れません。用意した内容が似たいような課題をお持ちの方に役に立つのではないかと思い、参考事例としてこちらに公開させていただきました。

想定読者

  • GASやRSSについてある程度知識をもっている
  • ChatWorkユーザーである

処理概要

  • ある特定のQiita Organizationの最新コンテンツを公開されているRSSから取得します。
  • 取得した記事情報はGoogle Spreadsheetに転記します。
  • 公開日時を見て新たらしい記事情報のみをSpreadsheetに更新します。
  • 同時に特定のChatWorkグループに更新情報を通知します。

RSSの中身

取得したRSSフィードから転記したGoogle Spreadsheet

自動投稿されたChatWork通知

参考にさせていただいた記事とメモ

Qiita API v2ドキュメント - Qiita:Developer
Organization単位で取得できるAPIがあるかを探しましたが、見つけられませんでした。
よって今回はAPIからの取得は断念。。。

[社内メンバーの Qiita 新着投稿を Slack で共有するスクリプトを GAS で作った話 - Qiita(https://qiita.com/tanabee/items/665917d9ab976661115c)
基本的な流れはこの記事を参考にしました。ただこの記事のコメントからOrganizationのRSSがあることを知りました。

スクレイピングだと画面が変わるたびに修正するのが嫌なので、RSS経由の取得とすることにしました。

Qiita OrganizationのRSSを取得する方法 - Qiita
この記事でOrganizationのRSSパスを調べました。

GASをパイプラインにしてQiita RSSのSlack通知を改善する。 - Qiita
この記事でRSSフィードを取り込む方法を調べました。この記事にたどり着くまで少し苦戦しました。
var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
が肝でした。

【Google Apps Script】その16 GASとスプレッドシートだけで簡易RSSリーダーを作り、Chatworkに新着通知する - Qiita
ChatWork通知の部分をこちらから流用させてもらいました。APIトークンやルームIDの指定はこちらの記事を見て下さい。

ちなみにGoogle SpreadsheetのIMPORTFEEED関数はとても便利ですね。使い方も簡単ですし、知っておくと便利だと思います。

スクリプト

正直公開できるレベルではなく、書きっぷりは自分で見ても素人感満載ですが、どうか優しくご指導ください


function InformNewcontets(){
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName("contens");

  //公開されているRSS情報を読み込む
  var response = UrlFetchApp.fetch('https://qiita.com/organizations/ari-group/activities.atom'); 
  var xml = XmlService.parse(response.getContentText());
  var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
  var entries = xml.getRootElement().getChildren("entry", atom);

  entries.reverse();//最新が下にくるように

  const FValues = sheet.getRange('D:D').getValues();//F列の値を全て取得
  const LastRow = FValues.filter(String).length;//空白の要素を除いた長さを取得
  var LastPublished = sheet.getRange(LastRow,4).getValue();//シートにある一番投稿が古いもの

  var count = 0;//新しいものをカウントする

  for (var i=0; i<entries.length; i++) {
    var published = new Date(entries[i].getChild('published', atom).getValue());

    //console.log("published:"+published);
    //console.log("LastPublished:"+LastPublished);
    //取得したRSS情報の更新日時と、最終行の更新日時(LastPublished)と比較して新しいもののみ追加する
    if(published > LastPublished){
      count = count+1;

      //最終行の下に追加する
      sheet.getRange(LastRow+count, 1).setValue(entries[i].getChild('title', atom).getValue());
      sheet.getRange(LastRow+count, 2).setValue(entries[i].getChild('link', atom).getAttribute('href').getValue());
      sheet.getRange(LastRow+count, 3).setValue(entries[i].getChild('author', atom).getChild('name', atom).getValue());
      sheet.getRange(LastRow+count, 4).setValue(Utilities.formatDate(published, "JST", "yyyy/MM/dd HH:mm:ss"));

      //チャットワークに投稿する
      var body = entries[i].getChild('title', atom).getValue() +'\n'+entries[i].getChild('link', atom).getAttribute('href').getValue();
      requestToChatwork("Qiitaエントリがありました!みんなで応援しましょう! (clap)",body);//メッセージは良い感じに!
    }
  } 

}

// chatworkにリクエストを送る
function requestToChatwork(subject, body) {
  var token = 'XXXXXXX'; // ここにトークンを入力
  var roomId = 'XXXXXXXXXXX'; // ここに投稿したい部屋のIDを入力
  var body  = '[info][title]' + subject + '[/title]' + body + '[/info]';
  var payload = {
    'body': body
  }
  var headers = {
    'X-ChatWorkToken': token
  }
  var options = {
    'method' : 'POST',
    'payload' : payload,
    'headers' : headers
  }
  var url = 'https://api.chatwork.com/v2/rooms/' + roomId + '/messages';
  UrlFetchApp.fetch(url, options);
}

GASトリガーへの設定(スケジュール設定)


タイマーのアイコンを押します。


トリガーを作成します。


こんな感じで設定しています。(1分おきはやりすぎですが)

最後に

Google Spreadsheet やGASは、相当応用範囲が広く非常に便利です。例えば自分はGoogle Calendarの当日予定をChatWorkのマイグループに毎朝自動投稿させています。(デイリーログを書くのに予定の一覧がテキストであると便利なんですよね)
Qiitaをはじめ参考になる記事がネットに大量にあるので、やりたいことをGoogleで検索すれば、大抵近い事例が見つかります。自分のような非エンジニア層でも挑戦できて本当にありがたいです。広くおすすめしたいです。

合わせて読みたい

GASでBacklogの期限切れチケットを定時に自動で拾いChatworkに通知する - Qiita