7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

FORKAdvent Calendar 2018

Day 16

baserCMS + HangoutsChat の通知プラグイン

Last updated at Posted at 2018-12-15

突然ですが、皆さんはこまめにメールをチェックしていますか?
私はプログラミングや作業に夢中になるとついついメールの確認をなおざりにしてしまいます。

でもプログラムのエラーって大体メールに通知が来るようにするもの。
昼間それに気付かず、夜遅く帰ろうとした時にエラーを発見した日にはもう……!
せめてチャットとかで通知が来てくれれば、ズボラな人や整理が苦手な人でも気付けるのに……

ということで、この記事では 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から投稿してみる』を参考にしています。

/Chat/Controller/Component/ChatComponent.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;
/Chat/Config/setting.php
$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を作りましょう。

/Chat/Event/ChatControllerEventListener.php
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 を用意しましょう。

/Caht/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 に手を加えます。
$eventBlog.BlogPosts.afterAdd を、 function blogBlogPostsAfterAdd という処理を新しく追加します。

/Chat/Event/ChatControllerEventListener.php
    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 に手を加えます。
$eventMail.Mail.afterSendEmail を、新たに function mailMailAfterSendEmail も追加します。

/Chat/Event/ChatControllerEventListener.php
    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/プラグイン作成ガイド


:christmas_tree: FORK Advent Calendar 2018
:arrow_left: 15日目 Photoshopで画像をスライスするJS @re_sai
:arrow_right: 17日目 Vue.js スマホでコンテンツをスクロールさせたくないようなアプリをつくるコツ @AsaToBan

:christmas_tree: baserCMS Advent Calendar 2018
:arrow_left: 15日目 作成中のbaserCMS用メールプラグインの紹介 @seto1
:arrow_right: 17日目 baserCMS 5で導入予定のCakePHP 3系は2系からどう変わった?@tommy6073

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?