技術のメモ帳

気が向いたときに書いてます

[GAS]はてなブックマーク REST APIを扱うライブラリ

今回は、Google Apps Scriptで、はてなブックマーク REST APIを扱うライブラリを作成してみました。

当エントリでは、利用方法を簡単に説明したいと思います。

アプリケーション登録

まず、はてなアカウントを取得し、下記ページを参考に、アプリケーションを登録します。

Consumer key を取得して OAuth 開発をはじめよう - Hatena Developer Center

アプリケーション登録後、consumer keyとconsumer secretを控えておいてください

認証用ライブラリの有効化と実装

APIの認証が、OAuth1だったため、(現在ではOAuthConfigは利用できないので)Google製のライブラリであるapps-script-oauth1を利用しています。

なお、実装については以下エントリを参考が非常に参考になりました。ありがとうございました。

まず、スクリプトエディタを開き、ライブラリを選択。M2L32TH_TklmEvt57DzRR-sLo7O4tWOsVと入力して、有効化してください。

有効化が完了したら、次のコードを書くと、OAuthで認証できます。

'use strict';

/**
 * OAuth認証用インスタンス
 * @params {string} consumer_key
 * @params {string} consumer_secret
 * @params {string} scope
**/
var service = HatenaWebService.getInstance(
  '***CONSUMER_KEY***',
  '***CONSUMER_SECRET***',
  'read_public,read_private,write_public,write_private'
);

// 認証を行う
function authorize() {
  service.authorize();
}

// 認証をリセット
function reset() {
  service.reset();
}

// 認証後のコールバック
function authCallback(request) {
  return service.authCallback(request);
}

なお、OAuth1で認証する手順として、手作業でブラウザからアプリケーションの利用を許可する必要があります。

コードをコピペしたら、authorize()を実行し、ログに表示されるURLを展開し認証してください。

はてなブックマークREST APIを操作する

こちらもモデルを操作するように利用できるようにするため、ライブラリ化しました。

MYkfPTbIKGEDQ4CBIBKtjfMLo7O4tWOsVと入力して、有効化してください。

有効化が完了したら、次のコードを書くと、はてなブックマーク REST APIを操作できます。

以下は実装例となります。HatenaBookmarkのインスタンス生成時には、上記の認証サービスが必要です。

'use strict';

// ブックマークモデル
var bookmark = HatenaBookmark.getInstance(service);

// ユーザー自身の情報を取得
function getMy() {
  var response = bookmark.get('my');
  Logger.log(JSON.parse(response));
}

// タグ一覧を取得
function getTags() {
  var response = bookmark.get('tags');
  Logger.log(JSON.parse(response));
}

// ブックマークを取得(url必須)
function getBookmark() {
  var response = bookmark.get('bookmark', { url: 'http://www.yahoo.co.jp/' });
  Logger.log(JSON.parse(response));
}

// エントリー情報を取得(url必須)
function getEntry() {
  var response = bookmark.get('entry', { url: 'http://www.yahoo.co.jp/' });
  Logger.log(JSON.parse(response));
}

// ブックマークの作成・更新(url必須)
function postBookmark() {
  var response = bookmark.post('bookmark', { url: 'http://www.yahoo.co.jp/' });
  Logger.log(JSON.parse(response));
}

// ブックマークの削除(url必須)
function destroyBookmark() {
  var response = bookmark.destroy('bookmark', { url: 'http://www.yahoo.co.jp/' });
  Logger.log(JSON.parse(response));
}

なお、APIの仕様により、POST/PUT/PATCH(作成/更新)は同一メソッドから行えます。

実行例では、URL以外のパラメータを渡していませんが、コメントやタグなども設定できるので、興味があればAPIのドキュメントを参考に利用してみてください。

各ライブラリのコード

最後にライブラリのコードです。認証用ライブラリについては、ブックマーク以外でも利用できます。

追記

このエントリ作成時は、認証とブックマークのライブラリが同一だったのですが、はてなブログなど、他のサービスでも利用できるよう、認証のみ別のライブラリに分割しました。

[GAS]Google Apps Scriptは、Strictモードを認識するのか?

TIPSです。

結論から言うと、JavaScriptインタプリタを利用しているので、Strictモードで動作します。

確認したコードは、次の通りです。

function strict() {
  "use strict";
  var obj = { p: 1, p: 2 }; // Strictモードの場合、同一keyは代入不可
  Logger.log(obj);
}

function notStrict() {
  var obj = { p: 1, p: 2 }; // 非Strictモードの場合、同一keyは代入可能
  Logger.log(obj);
}

なので今後はちゃんとStrictモードで書いていこうと思いました(一行目に"use strict";と書くのがベタでよさそうですね)

参考リンク

[GAS]doPostでログを出力する方法

今回はTIPSです。Google Apps Scriptの公開アプリケーションで、doPost()を実装するとき、Logger.log()メソッドが使えないので、ログが確認しにくい難点があります。他の方はどうやっているのか分かりませぬが、苦肉の策として、SpreadSheetを開いて書き込むという処理でログを確認しています。

具体的には以下の通りです。

function doPost(e) {
  logging(JSON.stringify(e));
}

function logging(str) {
  var sheet = SpreadsheetApp.openById('***YOUR_ID***').getActiveSheet(),
      ts    = new Date().toLocaleString('japanese', {timeZone: 'Asia/Osaka'});
  sheet.appendRow([ts, str]);
}

Spreadsheetとgsが関連付けされている場合は、openById()メソッドよりも、getActiveSpreadsheet()メソッドを使った方が不要な引数がなくスッキリしますが、個人的には、ログ出力用のファイルを1つ作成して、そこに書き込むようにしています。

もっと他の良い方法があったら、どなたか教えて下さい(きっとあるはず…)

[GAS]PivotalTrackerのアクティビティをSlackに通知する

今回は、PivotalTrackerのActivity WebHookを受けて、(Bot経由で)Slackにアクティビティを送信して通知するWebアプリケーションを、Google Apps Scriptで書いてみます。

実装手順としては次の通りです。

  1. 新規gsファイルを作成
  2. doPost()関数を作成
  3. Pivotal TrackerからPOSTされるデータを加工する
  4. SlackにPOSTする(ライブラリを使用)
  5. 処理結果をテキストで返す
  6. Projectの[Integration]→[Activity Web Hook]に公開アプリケーションのURLを入力

まずは、SlackAppライブラリを導入します。GASからSlackにPOSTする方法の詳しい手順は、過去エントリを参考にしてください。

yoshiyuki-hirano.hatenablog.jp

なお、送信されるPostDataの仕様は、PivotalTrackerのAPIドキュメントに記載されています。

実装したコード

JSONが送られてくるので、それをパースしてSlackに渡すだけのシンプルな処理です。

function doPost(e) {
  PivotalTrackerWebHookHandler(e, function(err, result) {
    try {
      if (err) throw err;
      var slack = SlackApp.create('xoxb-9918463123-nIYXVA3jxk8hrZGUcsMtsMoc'),
          props = {
            channelId: 'C0ATXJ1AM',
            userName: 'gas',
            message: [
              "*[", result.project.name, "] ", result.primary_resources[0].name, "*\n",
              result.message, "\n",
              "https://www.pivotaltracker.com/story/show/", result.primary_resources[0].id
            ].join('')
          };
      slack.postMessage(props.channelId, props.message, { username: props.userName });
      return makeResponse('success');
    } catch(ex) {
      return makeResponse(ex.toString());
    }
  });
}

function PivotalTrackerWebHookHandler(e, callback) {
  try {
    if (!e.postData) throw new Error('Missing required postData.');
    var result = JSON.parse(e.postData.contents);
    callback(null, result);
  } catch(ex) {
    var result = { message: ex.toString() };
    callback(ex, result);
  }
}

function makeResponse(message) {
  var mimeType = ContentService.MimeType.TEXT;
  return ContentService.createTextOutput(message).setMimeType(mimeType);
}

動作確認

PivotalTrackerでStoryに変更が加えられると…

このようなテンプレで、Slackに通知が送信されました。

アクティビティ別にゴニョゴニョしたい場合も、処理を追加するなり、テンプレ毎に関数分けるなりすれば、簡単に実装可能です。

PivotalTrackerを利用して、ストーリーベースの開発を行っているのであれば、導入しても便利かもしれませんね。

[GAS]シートの行列の幅と高さを変更して方眼紙化する

今回は、Google Apps Scriptを使って、表示中のシートの行列の幅と高さを変更し、いわゆる、エクセル方眼紙化する関数を実装してみます。

以下が仕様となります。

  1. メニューから関数を実行
  2. promptで幅を入力
  3. すべての行列が2の幅に変更される

実装したコード

行列の幅を変更するメソッドは、SheetクラスのsetColumnWidth()setRowHeight()にあたりますので、シンプルに入力した値をそれらメソッドに渡します。

なお、Spreadsheetでは、ColumnsはZ列まで、Rowsは1000行まで指定できるようです。

実装したコードは次のようになりました。

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Script').addItem('GraphPaperize', 'GraphPaperize').addToUi();
}

function onEdit() {
  onOpen();
}

function GraphPaperize() {
  var ui          = SpreadsheetApp.getUi(),
      sheet       = SpreadsheetApp.getActiveSheet(),
      response    = ui.prompt('Enter width/height of cells (default 15):'),
      defaultSize = 15;

  if (response.getSelectedButton() == ui.Button.OK) {
    var inputSize = parseInt(response.getResponseText()),
        size      = (inputSize > 0) ? inputSize : defaultSize;
    for(var i = 1; i <= 1000; i++) {
      sheet.setRowHeight(i, size);
      if (i <= 26) sheet.setColumnWidth(i, size);
    }
  }
}

動作確認

関数を実行すると、次のようになります。

▼実行前のシート

▼promptでサイズを入力します。

▼方眼紙のようになりました。

参考リンク

Class Sheet  |  Apps Script  |  Google Developers

[GAS]SpreadsheetでYouTube検索・閲覧ができるAngularJSアプリケーション

今回は前回に引き続き、YouTube Serviceを利用したGoogle Apps Scriptを書いていきます。

Spreadsheetでサイドバーから展開できるアドオンを想定して実装します。

動作サンプル

仕様は次の通りです。

  1. メニューからサイドバーを展開
  2. 検索フォームに文字列を入力
  3. 検索結果の表示と、各コンテンツの再生
  4. 検索結果をSpreadsheetに出力
  5. 選択中のセルの値からも動画の再生を可能に

▼アドオンを起動すると、検索フォームが表示され…

▼検索すると、コンテンツが表示されます。

▼各コンテンツをクリックすると、モーダルダイアログで動画が再生され...

▼「Output to spreadsheet」で検索結果が新規シートに出力されます。

…といったテスト用のアドオンを作成しました。

実装したコード

ささっと組んだため、インジェクションの作法など、あまり気にしておりませんが。

Google Apps Script上でAngularJSを使ったのは初めてだったのですが、テンプレートの文字列部分以外は、すんなりいけました。

後日コードを整理してアドオンとして公開しようと思います。

参考リンク

[GAS]SpreadsheetからYouTube動画を再生する

今回は、SpreadsheetからYouTube動画を再生するコードをGoogle Apps Scriptで書いてみました。

単純に埋め込み用のiframeを表示するだけでは脳がないので、アクティブなセルからIDを取得して、表示するようにしてみました。

実装したコード

特に難しいことはしておらず、onOpen()→showModalDialog()で表示するのみです。

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('SCRIPT').addItem('Play', 'showModalDialog').addToUi();
}

function onEdit() {
  onOpen();
}

function showModalDialog() {
  var html = HtmlService.createTemplateFromFile('viewer').evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME).setWidth(420).setHeight(315);
  SpreadsheetApp.getUi().showModalDialog(html, 'YouTube Player');
}

function getYouTubeUrl() {
  var id = SpreadsheetApp.getActiveSheet().getActiveCell().getValue();
  return 'https://www.youtube.com/embed/'+id+'?cc_load_policy=0&vq=highres&rel=0&loop=1&autoplay=1';
}

テンプレートは次のようになります。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <iframe width="420" height="315" src="<?!= getYouTubeUrl(); ?>" frameborder="0" allowfullscreen></iframe>
  </body>
</html>

動作確認

表示されました。利用するシチュエーションが分かりませんねw

GASの拡張APIで、YouTubeの検索APIが利用できるので、それを使う前段として、このような誰得の実装をしてみました。

参考リンク

YouTube動画をブログ埋め込み時に使える便利なカスタマイズ方法!パラメーター14選まとめ[前編] | movieTIMES ムービータイムス