突然ですが、皆さんはこまめにメールをチェックしていますか?
私はプログラミングや作業に夢中になるとついついメールの確認をなおざりにしてしまいます。
でもプログラムのエラーって大体メールに通知が来るようにするもの。
昼間それに気付かず、夜遅く帰ろうとした時にエラーを発見した日にはもう……!
せめてチャットとかで通知が来てくれれば、ズボラな人や整理が苦手な人でも気付けるのに……
ということで、この記事では baserCMS という CakePHP で作られているCMSにその機能を実装してみます!通知先のチャットツールはGoogleの HangoutsChat にしました。
今回はbaserCMSにプラグインとして実装する方法をご紹介しますが、CakePHPで作られたプログラムあればbaserCMSに限らず少し直すだけで取り入れられると思います。気になる方は是非お試しください。
HangoutsChat のWebhook設定
HangoutsChat で通知を受信する準備
はじめにHangoutsChatで通知を受け取る場所を用意しましょう。
イメージとしてはPHPからHangoutsChatのプログラムにPOST送信を行います。
このPOSTを受け取るものを Webhook といいます。チャットルームにWebhookを追加することで、そのチャットルームに対してPOSTを送信し通知を出します。
Webhookの設定は 『GASからhangout chatにPostする』 がわかりやすいのでご参照ください。
baserCMS プラグインの開発
baserCMS のプラグイン設置
baserCMSにプラグインを入れる時は /app/Plugin/プラグイン名
のように設置します。
今回は Chat
という名前のプラグインを開発してみます。Chatプラグインの中身は次のようになります。
/app/Plugin/Chat/
Config/
setting.php
Controller/
Component/
ChatComponent.php
Event/
ChatControllerEventListener.php
VERSION.txt
config.php
この記事では中でも次の2ファイルをメインに説明していきます。
/Chat/Controller/Component/ChatComponent.php
/Chat/Event/ChatControllerEventListener.php
その他のファイルは一旦なくても動くので、気になる方は 『第1回 プラグイン作成の準備・初期設定』 をご参照ください。
HangoutsChat に通知を送信する処理
baserCMSからHangoutsChatに通知する為の処理を書きます。
今回は様々な場面で共通で使えるよう、Componentを使います。
/Chat/Controller/Component/ChatComponent.php
というComponentを作りましょう。
通知の処理は『HangoutsChatにPHPから投稿してみる』を参考にしています。
class ChatComponent extends Component
{
public $controller = NULL;
public function send($message)
{
$webhookUrl = Configure::read('HangoutsChat.webhookUrl');
if (empty($webhookUrl) || !preg_match('#\Ahttps://chat.googleapis.com/v1/spaces/#', $webhookUrl)) return FALSE;
$data = json_encode(['text' => $message], JSON_UNESCAPED_UNICODE);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $webhookUrl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_exec($curl);
curl_close($curl);
return TRUE;
}
}
この中の次の箇所はHangoutsChatの通知先のWebhookを設定しています。
$webhookUrl = Configure::read('Chat.webhookUrl');
if (empty($webhookUrl) || !preg_match('#\Ahttps://chat.googleapis.com/v1/spaces/#', $webhookUrl)) return FALSE;
$config = [];
$config['Chat'] = [
'webhookUrl' => 'https://chat.googleapis.com/v1/spaces/XXXXXXXXXX'
];
Configure::read('HangoutsChat.webhookUrl')
と書くことで プラグインの中で Chat.webhookUrl
キーに設定した値を取得しています。ここで直接WebhookのURLを設定しても問題ありません。
Component の読み込み
上記で作成したComponentの処理を好きなタイミングで呼べるように読み込みます。
CakePHPの便利な機能、イベントシステムを使ってみます。イベントシステムを使うことで、baserCMS本体をいじらずともプラグインから本体に対して処理の変更や追加を行うことができます。
/Chat/Event/ChatControllerEventListener.php
というEventListnerを作りましょう。
class ChatControllerEventListener extends BcControllerEventListener
{
public $events = [
'initialize'
];
public function initialize(CakeEvent $event)
{
$Controller = $event->subject();
$Controller->components[] = 'Chat.Chat';
$Controller->Chat = $Controller->Components->load('Chat.Chat');
return TRUE;
}
}
initialize
は各actionの前に読み込まれ、 beforeFilter
よりも先に呼ばれるイベントです。initializeのタイミングでComponentを読み込むことで、様々なシーンで通知処理を使えるようにしています。
$Controller->components[]
には プラグイン名.Component名
というルールでComponentを追加します。
これでChatプラグインのベースが完成しました。
通知タイミングの設定
プラグインの有効化
baserCMSからHangoutsCahtに通知を送信する準備ができました。では実際に通知を送信してみましょう。
まずは開発したプラグインが動くようにbaserCMSでChatプラグインを有効化させます。
baserCMSの管理画面にログインして、プラグイン管理の画面に移動しましょう。一番下にChatプラグインが追加されています。 /Chat/config.php
に設定を書いていない場合は情報が少ないかもしれませんが、動作に影響はありません。
それでは早速プラグインをインストールして有効化してみましょう。
Controllerから通知
まずは任意のControllerから通知を送信する方法です。
新しく /Chat/Controller/SampleController.php
を用意しましょう。
class SampleController extends AppController
{
public function index()
{
$this->Chat->send('Controllerから通知するテスト');
$this->autoRender = FALSE;
echo 'Chat通知テストページ';
return;
}
}
上記のControllerのURLは baserCMS設置URL/chat/sample/
になります。
既にEventListenerでComponentを読み込んでくれているので $this->Chat->send('メッセージ')
だけでHangoutsChatに通知を送信することができます。勿論これはChatプラグイン外のControllerでも有効です。
記事が投稿されたら通知
続いて、元々baserCMSに備わっている機能にHangoutsChatへの通知送信を追加してみましょう。
まずはブログに新規記事が投稿された時に通知を送信してみます。
既存の /Chat/Event/ChatControllerEventListener.php
に手を加えます。
$event
に Blog.BlogPosts.afterAdd
を、 function blogBlogPostsAfterAdd
という処理を新しく追加します。
public $event = [
'initialize',
'Blog.BlogPosts.afterAdd'
];
public function blogBlogPostsAfterAdd(CakeEvent $event)
{
$Controller = $event->subject();
$data = $Controller->request->data['BlogPost'];
$message = sprintf('新着記事 『%s』 が投稿されました', $data['name']);
$Controller->Chat->send($message);
return TRUE;
}
Blog.BlogPosts.afterAdd
はBlogプラグインのBlogPostsController限定で afterAdd
という新規記事登録後に動くイベントです。他のイベントにおいても プラグイン名.Controller名.イベント名
とすることで対象を絞ることができます。
ここでは $Controller->request->data['BlogPost']
で記事内容を取得し、通知の中に利用しています。
お問い合わせを受け付けたら通知
ユーザーからのお問い合わせに機敏に対応することも大切ですね。お問い合わせを受けたらHangoutsChatに通知してみましょう。
今回も記事投稿時と同じように /Chat/Event/ChatControllerEventListener.php
に手を加えます。
$event
に Mail.Mail.afterSendEmail
を、新たに function mailMailAfterSendEmail
も追加します。
public $event = [
'initialize',
'Blog.BlogPosts.afterAdd',
'Mail.Mail.afterSendEmail'
];
public function mailMailAfterSendEmail(CakeEvent $event)
{
$Controller = $event->subject();
$data = $Controller->request->data['MailMessage'];
$message = sprintf('%s さんからお問い合わせがありました', $data['name_1']);
$Controller->Chat->send($message);
return TRUE;
}
Mail.Mail.afterSendEmail
はMailプラグインのMailController限定で afterSendEmail
というメール送信直後に動くイベントです。 $Controller->request->data['MailMessage']
でユーザーの入力内容を取得しています。
この他にもbaserCMSに用意されているイベントはbaserCMS公式ガイドの 『ver4/プラグイン作成ガイド』 で紹介されています。
このようにイベントシステムを使うことで本体に手を加えずに処理を追加することができます。勿論デフォルトのイベントシステムでは対応できないシーンもありますが、1行書き足すだけで処理を追加できます。 肝心のエラー時の通知は書いていないけど気にしない。
とりあえず $this->Chat->send('メッセージ')
って書けば好きな時に通知を送信できるよ!
皆さんもエラーに気を付けつつ、開発ライフを楽しみましょう!
備考
開発環境
- PHP 7.1.23
- CakePHP 2.10.6
- baserCMS 4.1.4
参照
GASからhangout chatにPostする
HangoutsChatにPHPから投稿してみる
baserCMS ver4/プラグイン作成ガイド
FORK Advent Calendar 2018
15日目 Photoshopで画像をスライスするJS @re_sai
17日目 Vue.js スマホでコンテンツをスクロールさせたくないようなアプリをつくるコツ @AsaToBan
baserCMS Advent Calendar 2018
15日目 作成中のbaserCMS用メールプラグインの紹介 @seto1
17日目 baserCMS 5で導入予定のCakePHP 3系は2系からどう変わった?@tommy6073