めるノート

へっぽこWebエンジニアが地団駄を踏んでいる日誌

commitしたら写真を撮られてSlackにアップされるスクリプトを作った

f:id:c5meg1012:20170602222512p:plain

写真はMacBookの画面の上についてるカメラで撮られます。

commitしたら写真を撮られるところまでは旦那さんからPHPスクリプトをもらってたんですが、そこから先、撮った写真がSlackにアップされるスクリプトを書けと言われました。

自分はちょっと前まではPHP書くことも(ただしド素人レベルで)あったのですが、最近はほとんどPHPを書かないので、pre-commitにRubyで書けないかとググってみたんですが、自分の環境(zsh + rbenv)だと一筋縄ではいかないようでした。
あと、ググってもRailsのgemの記事ばかりで、Rubyスクリプトはちょっとしか出てこなかったです(´・ω・`)
まあ途中までPHPで書かれているので、PHPのほうが撮影したファイルを扱いやすいかな、ということでPHPで手段をさがすことにしました。

commitしたら写真を撮られてSlackにアップされるって、どんなプレイだよというツッコミを心のなかでしつつ、ちょっと調べてみたら
https://api.slack.com/methods/files.upload
これがイケそうだというのと、
file_get_contentsでファイルをPOSTできそうだということが分かりました。

なんとかAPIからレスポンスが返ってくる状態にはできたのですが、
invalid_args_name
が解決できず。

ちょっと調べると、file_get_contentsだとinvalid_args_nameでできなかったけど、curlだとできたよ、という記事が出てきました(URL載せようと思って探したけど見つからない…)
なのでcurlでやり直してみたんですが、いかんせんcurlのお作法がわからず苦労しました。

結局一週間くらい泣きながらやってみてもできなくって、深夜に旦那さんにきいてもますますわからない事を言われて余計にヒステリックになる始末でした。
そんな中、今朝、旦那さんから「これは?」と言われた記事を参考にして、ようやくできました。

www.mrwhal3.com

うまくいかなかった原因はふたつあって、ひとつは、
PHP5.6からファイルの取り扱い方が変更になったため、
$file = new CurlFile('filename.png', 'image/png');
という感じでCurlFileを使わないといけないということ。

もうひとつは、先述の通り、curlでPOSTするお作法が全然わからなかったということでした。
SlackのAPIや、ググッて日本語ですく出て来る記事には、getでテキストファイルなどを送る方法がメインで書いてあったので、そっちにとらわれてしまっていたり、curlで検索してもいろいろ出すぎてよくわからなかったり…という感じでした。
curlでPOSTするお作法については、分かったら色々便利そうだなぁという感じなので、もうちょっと詳しくなりたいです。詳しい人教えて下さい(´・ω・`)

実際に動かしたスクリプトは以下です。
.git/hooks/pre-commitに書く場合は最初にPHPのPATHをかきましょう。

#!/usr/bin/php
<?php

// ディレクトリは好きなところに
$dir = '/Users/meg/.gitshots/'.date('Y/m/d');
$file = date('His').'.jpg';

if (false === is_dir($dir)) {
    echo "Create directory {$dir}\n";
    mkdir($dir,0777,true);
}

echo "Taking capture into {$dir}/{$file} \n";

pclose(popen("imagesnap -q -w 3 {$dir}/{$file} &> /dev/null &", 'r'));

// ここでsleepしないと画像ファイルが生成される前にスクリプトが動いちゃうので
// ファイルがありませんというエラーが出ちゃいます
sleep(5);

//ここはSlackAPIで各自取得してください
$slacktoken = "xxx-xxx-xxxx";
$channelId = 'xxxxxxx';

$header = array();
$header[] = 'Content-Type: multipart/form-data';
$file = new CurlFile("{$dir}/{$file}", 'image/jpg');

$postitems =  array(
    'token' => $slacktoken,
    'channels' => $channelId,
    'file' =>  $file,
    'text' => "コミットしました",
    'title' => "コミットしました",
    'filename' => date('Y/m/d').".jpg"
);
    
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_URL, "https://slack.com/api/files.upload");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS,$postitems);

$data = curl_exec($curl);
echo 'RETURN:'.$data;
curl_close($curl);

iSightのあるMacBookなら brew install imagesnap をした後に実行すれば動くと思います。

ということで、現在、コミットすると夫婦Slackに自分の写真が送られます…
うまくいって嬉しいけど、複雑なキモチ(´・ω・`)