Google Spreadsheetに新しい行が追加されたらwebhookとしてidobataに通知を飛ばす方法

バイト先ではチャットツールとしてidobataを使っています。idobataではwebhookのbotがかなり簡単に作ることが可能で、あるエンドポイントに対してpostでアクセスをすると発言をするbotを構成することができます。また形式としてHTMLをサポートしており、特定のオプションを付けてエンドポイントを叩くことでHTMLにレンダリングされたメッセージを発言させることが可能です。

今回はあるスプレッドシートの新規書き込みがあるとidobataに通知を送る仕組みを作りたく、アドオンの設定をするよりGASで書いたほうが様々な面で良かった為にGASでおおよそのbotを作成しました。そのメモです。

最終更新行の検知

GASでスプレッドシートを利用する場合、まずActiveになっているシートを取得する必要があります。

const sheet = SpreadsheetApp.getActiveSheet() などとすると保持することが可能です。  なおGASは let が使えず constvar で定義をしていく世界観のようです。 Overview of Google Apps Script

次に最終更新の行と列を取得する必要があります。 列は正直どっちでも良いと思うのですが、行は必須となります。 今回のスプレッドシートは、新規依頼が末尾に積まれていくタイプであるのでgetLastRow() で取得する事が可能です。

function add_new_dojo_notice() {
  const sheet = SpreadsheetApp.getActiveSheet()

  const lastRow = sheet.getLastRow()
  const lastColumn = sheet.getLastColumn();

ここから一行の各セルをhtmlに修正してsendするという作業を行っていきます。 今回は予め params_info という変数にbotの出力用も兼ねて種類を配列形式でいれています。

この getRange() では最初に行、次に列番号を指定し、続いて行数の範囲を指定を行います。 なお最後の2変数は省略する事も可能となっています。 ここでは最終更新の1行の各セルを取りたい為、最後の2つは 1,lastColumn としています。

今回は列のサイズ分 i をインクリメントし、セルを右に移動しながら文字列 send_paramas に追記を行っていきます。

ここで注意する事は getRange() で取得する列番号はスプレッドシートの番号であるため、配列形式のようにインデックスが0スタートではありません。基本的に1スタートです。今回は空入力の場合表示させないなどを記述しています。

  for ( var i = 1; i < params_info.length; i++){

    if (sheet.getRange(lastRow,i,1,lastColumn).getValue() == ""){
        continue;
    }

      send_params += sheet.getRange(lastRow,i,1,lastColumn).getValue()
  }

  notice_to_idobata(send_params);
}

実際に通知を送る部分のコードはこの用に素朴になっています。 先程の send_paramssource に紐付けて送っています。

function notice_to_idobata(message) {
  const idobataURL = "IDOBATA.url"

  const playload =
   {
     "source" : message,
     "format" : "html",
   };

  const options = {
    "method" : "post",
    "payload" : playload,
    "format" : "json",
  };

  UrlFetchApp.fetch(idobataURL, options);
  Logger.log(options);
}

注意するべきなのは、idobataにmessageを送る際、送りたいメッセージは source の対応として送らなければなりません。

またこの際にhtmlで送る場合 playloadformat をhtmlに指定しておく必要があります。 指定しなければ、idobata側でHMLタグをただの文字列として解釈します。

options でtypeの指定も可能ですが、これはidobataに対しては意味が無いです。

トリガーの設定

作成したスクリプトは「編集」から「現在のプロジェクトのトリガー」を選択する事でトリガーを仕掛ける事が可能です。 トリガーにはいくつか種類がありますがこのエントリ公式ドキュメントを見る限り「submit」か「値の変更」で行うと良さそうでした。

YAPC::Okinawa 2018 ONNASON そしてYAPCから貰ったもの

3月3日(土)にOISTでYAPC::Okinawaが開催されました。

id:anatofuzはブログ書いたりとか、当日の某アカウントの中の人をやっていたりと、なんとYAPC::Okinawaのスタッフをやっていました。当日はそのお仕事をしており、トークを集中して聞けなかったので後日スライドで補間していきます。なのでこのエントリではトークの感想はちょっとしか書いてないです…。許してつかーさい…。

今ブログを書いていて、なんとなくエモい気分になっているのでこのエントリではエモい話をします。

(というかこのブログではエモい話しかしていないのでは)

YAPC::Okinawaとの関わり

僕がYAPCをOkinawaですると聞いたのは、Perl入学式を受講している真っ只中だった。東京から id:ar_tama さんと id:nekokak さんが来ていて(当時はお二人のことは何も知らなかった) 居酒屋でYAPCする? みたいな話になったと思う。

あの時はPerlは好きだったけど、まさか自分がスタッフをする事になるとは思っていなかった。

その後FukuokaのMTGに参加させていただいたりとか、JPA側のOkinawa担当の平子さん方と決起集会をしたりなどした。 JPAの皆さんからしていただいた事以上の事は返せなかったと思っているけど、非常に有り難い経験をさせて頂きました。ありがとうございます。

沖縄で普段はコアメンバーとして、沖縄-東京をGoogleハングアウトで接続してMTGを行ったりした。基本はインターネットの人なので、twitterとかブログなどを担当していた気がする。

個人的な思い

過去のエントリにも書いたとおり 色々な経験をした結果「ウッ」っとなってしまうことが多発していて、特に年明けは最悪だった。他にはPerlの某企業からお祈りされたことなどもある。

大学に行くこともできなくなり、カウンセリングと病院に連行され、ついた名前は双極性障害である。完全にウッをしてしまった。

YAPC::Okinawaのslackでは来来月に差し迫ったYAPCの準備でwebサイトを更新したりとか、ブログを書いたりしなければならないのに、何もすることが出来なくなってしまった。

全てに対して後ろ向きで、Perlの事も好きではなくなりそうだった。僕はPerlが好きだけど、Perlは僕のことが好きではない感じがした。

そんな中、僕の代わりの仕事をしてもらったのは id:codehex さんであり、 id:sorehaedamame さんであり、 id:touba_rumba さんであり @selaさんだった。

通院もしたけれど、Okinawa.pmの皆さんを初めて、Perl入学式でもお世話になっている id:karupanerura さんやid:papix さんや id:gomayumax さんや Twitterでの友人である id:kaoru1615 くんから前向きになる力を貰えた。

YAPCの準備は確かに大変だったけど、人々が支え合っている事を知れたし、僕もその人々の中に居ることができたのが本当に嬉しかった。

準備をしていく中で段々と前向きにまたなることが出来て、Dockerを使ったwebアプリをちょっと書いて見ることが出来た。Slackbotも作ることができた。久々にAcmeモジュールをリリースすることも、webservice名前空間のモジュールをリリースすることもできた。バイトを始めることもできたし、出来ることが増えていった気がする。

僕はYAPCを通して、再びPerlのことが好きになれた。 Perlは僕に書かれたくないのではなくて、僕がPerlを拒否していただけだった気がした。

再び好きになったPerlには大好きなシジルが輝いて見えた。

当日

前にも書いたけど、当日はリソースが追いつかない感じがあってちゃんと聞いたトークはあまりなかった。

それでも、あの初心者にも、Perlを書いてない人にも、そして熟練のPerlMongerの全ての人が楽しめるトークだったとは思っている。スピーカーの皆さん本当にありがとうございました。

個人的には id:papix さんのLTで「思いは言葉に」というのが印象に残っていた。id:note103 さんのトークPerl入学式のメンバーとしてはこの沖縄でやっていただいた事がとても嬉しかった。

また、書いておきたいのは id:unimarimo がしたLTは、ちょうど去年僕がKansaiでしたLTを彷彿とさせていてエモい気分になった。

あの時は id:papix さんや id:codehex さんから渡されたバトンだったけど、僕も渡せているのかな。そんな気がした。

最後に

僕はYAPCは人を変えるイベントだと思っている。

id:codehex さんが言うとおり

開催するからには、僕らが感動したあの YAPC のように、誰かの何かしらのきっかけになって欲しいと強く思っていました。

YAPC::Okinawa 2018 を終えて - YAPC::Japan 運営ブログ

だから個人的には鬱陶しいかもしれないけど、沢山の人をYAPCに誘った覚えがあるし、 id:unimarimo にはボランティアスタッフの他にLTを進めた。それは僕がYAPCと出会ったあの経験があるからだった。

初めてのYAPCであるYAPC::KansaiでYAPCに来るエンジニアの方々の業績や、トーク内容もわからないことが多いのにLTをしたあの日から、僕の人生は変わったと思う。

当然サクセスストーリーだけではなく、大きな挫折やウッを経験してしまった事もある。毎日が楽しいだけでなくて、「俺は一体…」となることや、コードを眺めて何も手が動かず数分たったこともある。

それでもKansai,Fukuokaのあの時から僕は一歩進めたし、最後のスタッフ撮影で写真に取ってもらう事に対して後ろめたさのようなものが無くなった。完走できたかどうかはわからないけど、やりきった気はした。

YAPC::KansaiでPerlが一番好きになって、YAPC::FukuokaでPerlMongerの一員に慣れた気がして、YAPC::Okinawaでもう一度Perlと向き合う力を貰った。YAPCは常に何か僕に力をくれる気がした。

そんなYAPCと少しでも関われたのは嬉しかったし、誇りに思っている。

YAPC::Okinawaに関わった全ての皆さんありがとうございました。

さて、エモい話はここまでにして、次からは手を動かしたいと思う。

次のYAPC::Tokyoではトークをしようと思うので、(採択されれば)皆さんよろしくお願いします。

YassLab株式会社さんでバイトを始めました

という訳でYassLab株式会社さんでバイトを始めました。お声掛け頂いて有り難いです!!

リモートでRubyをモリモリ書いていく系のバイトです。 今現在は CoderDojoJapan が稼働しているRalsのコードをんだりとワイワイやっていきという感じです。

技術系のバイト+Ruby+リモートの全てが初めてなのでワクワクしています。(インターンは何回かしましたがお金が発生しなかった)

ちゃんとした(?)バイト自体始めてなので、自分のペースを確立し、しっかりとcommit出来るように頑っていきたいと思います。やっていくぞ!!!

RubyのArray.new(5,'default')っぽいことをPerlでする試み

始まり

Rubyを勉強し始めていて、RubyArray.new(5,'default') などとすると、要素数5の配列が生成されるが、これら1つ1つの要素は同じオブジェクトIDを所持している為 a[0].upcase! などとすると全ての要素が変更される事を知った。

普段書いているのはPerlなので、Perlではどのようにするとこれが再現できるかを考えてみた。

試みる

id:mackee_w さんに拾っていただき試みが始まる。

そして書いたコード

#!/usr/bin/env perl
use strict;
use warnings;
use DDP { deparse => 1 };

my $hoge = {hoge => "saru"};

my @hoge = map { $hoge } (1..10);

p @hoge;

さらに別の方法が議論される。

そして書かれたコード達

#!/usr/bin/env perl
use strict;
use warnings;
use DDP { deparse => 1 };

my $hoge = {hoge => "saru"};

#my @hoge = map { $hoge } (1..10);
#
#p @hoge;

my @array =  ($hoge) x 10;

p @array;
use Data::Dumper;
my $h = { hoge => "huga" };
warn Dumper [ ($h) x 10 ];

解説

PerlではオブジェクトIDのようなものはリファレンスそのものなので、リファレンスをリストコンテキストでn回増やし配列に代入するとこのような事が可能だった。

mapの例は (1..10) で範囲を表して同じようなことを行っている。

感想

Perlで考えてみると実際の処理が解ってくる気がした。

「良いコードを書く技術」読んだ

大学図書館で目にしたので読んでみました。

良いコードを書く技術 ?読みやすく保守しやすいプログラミング作法 (WEB+DB PRESS plus)

良いコードを書く技術 ?読みやすく保守しやすいプログラミング作法 (WEB+DB PRESS plus)

無いようはリーダブルコード的な話が6割。残りはメタプログラミングデザインパターン的な話でした。

中でもよく書かれていたのが「スコープ」の問題。例えばその変数はfor文の中で宣言するべきなのか、というところからクラス変数かインスタンス変数にするべきかなど…あらゆるスコープを意識しろと書かれていました。

名前重要や再利用性、抽象度を高めることはリーダブルコードにも書かれていたので、改めて大事だなと思うとともに「結局本を読んでも手を動かさないとこの辺習得できないな」などという所感を得ました。

後半はメタプログラミング的な話で、Java特有のテクニックの様な部分が多かった印象です。メタプログラミングについてはあまり学習できていないのでRubyあたりで学習したいと思っています。

cpmでinstallしたCPANモジュールの個人的パス通し法

cpmでinstallしたPerlモジュールを使おうという時の個人的な技です


追記

追記:cpmの作者のid:shoichikaji さんから 2か3がおすすめ との情報を頂きました。ありがとうございます。


1 carton exec

わかりやすく無難な方法だと思っています。

carton exec -- perl hoge.pl  的な感じでの実行です。

2 perl -I$PWD/local/lib/perl5

主にbin以下に落としたcuiアプリを起動する際に使っています。 例えばmorboを起動する時は

perl -I$PWD/local/lib/perl5/ local/bin/morbo みたいに実行します。

3 env PERL5LIB

環境変数PERL5LIB にパスを通すやり方です。 direnvを使う時に使っています。

4 FindBin+lib

スクリプトを書く時に使う事が多いです。

   use FindBin;
   use lib "$FindBin::Bin/local/lib/perl5";

これをvimスニペットに設定しているのでぱぱっとやってしまう事が多いです。

個人的な知見なので、何かいい方法などあれば教えていただければ嬉しいです。

--