fbpx

メニュー

WordPressからSlackに手作り通知

高橋文樹 高橋文樹

この投稿は 8年半 前に公開されました。いまではもう無効になった内容を含んでいるかもしれないことをご了承ください。

こんにちは。最近破滅派にもSlackを導入しました。正確には前から導入してたんですけど、TravisやGithubからのボット投稿を延々と僕が眺めるだけだったのですが、それを編集部的に使っていこうということになったのですね。

さて、掲題の件なのですが、WordPressはCMSとして利用されているはずなので、共同編集の場合はいろんな通知があると助かります。具体例を上げるとこんな感じ。

  • 公開権限のない人が投稿を公開申請した(投稿者からpublish_postsの権限を剥奪しておいて、編集者がチェックの上で公開を行うなど)
  • Cron処理などでランキングを自動生成しており、そのランキングが作成された
  • ものすごく重要な情報(決済サービスのIDなど)が変更された

こういう場合、Slackに通知を送っておくと色々便利かもしれません。まあ、メールでもいいんですけどね。

WordPressとSlackを連携するプラグインはいくつかある(ズバリSlackもある)のですが、Slackへの投稿自体はそんなに難しくないので、やり方を紹介します。

ステップ1. WebhookのURLを取得

Incoming Webhooksのページに移動して、新たに作成します。チャンネルやアイコンの指定などを行えますが、これは上書きできるので、適当に。

「slack incoming webhook」でググればたどり着く
「slack incoming webhook」でググればたどり着く

必要なのはWebhook URLというヤツ。このURLにJSONをPOSTすると投稿されます。このURLが漏れてしまうと外部の人が好きなように投稿できてセキュリティ的にウザいことになりますが、その場合は再生成できます。

モザイクのかかってる部分が知られちゃダメな部分
モザイクのかかってる部分が知られちゃダメな部分

ステップ2. 関数を作成

JSONをPOSTするだけなので、こんな感じの関数を用意しておけばよいでしょう。

/**
 * Slackに投稿する
 *
 * @param string $content Slackに投稿する文字列
 * @param array $attachment 添付がある場合は、連想配列を渡す
 * @param string $channel 初期値は '#general'
 * @return bool
 */
function hametuha_slack( $content, $attachment = [], $channel = '#general' ) {
    // wp-config.phpとかに、上で取得したWebhook URLを定義しておく
    if ( ! defined( 'SLACK_ENDPOINT' ) ) {
        return false;
    }
    $payload = [
        'channel' => $channel,
    ];
    if ( WP_DEBUG ) {
        // デバッグモードならテストをつける
        $content = "【テスト投稿】 {$content}";
    }
    $payload['text'] = $content;
    // attachmentsについては
    // @see https://api.slack.com/docs/attachments

    if ( $attachment ) {
        $payload['attachments'] = [ $attachment ];
    }
    $ch = curl_init();
    curl_setopt_array( $ch, [
        CURLOPT_URL => SLACK_ENDPOINT,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => 'payload='.json_encode( $payload ),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_TIMEOUT => 5,
    ] );
    $result = curl_exec( $ch );
    curl_close( $ch );
    return false !== $result;
}

これでhametuha_slack( '通知があります' );と書くだけで通知が行えます。

ステップ3. 任意の場所で実行

あとは好きな場所で実行すればよいのですが、なにか具体例が必要ですね。今回は次のようなケースを想定します。

  • 毎日50件のコンテンツが投稿されるサイトである。
  • 特定の投稿タイプ special-column は広告記事であり、広告担当者はそれがきちんと公開されたかどうか知っておく必要がある。
  • よって、special-columnが公開された場合、広告関連チャンネル #ads にSlackが通知される。

これを実現するコードはこんな感じでしょうか。

/**
 * 投稿が公開されたときにSlack
 *
 * @param string $new_status
 * @param string $old_status
 * @param object $post
 */
add_action( 'transition_post_status', function ( $new_status, $old_status, $post ) {
    //はじめて公開にしたときだけ。非公開はありえないとする。
    if ( 'special-column' === $post->post_type && 'publish' === $new_status ) {
        switch ( $old_status ) {
            case 'new':
            case 'draft':
            case 'pending':
            case 'auto-draft':
            case 'future':
                  $string = sprintf( '広告記事が公開されました: <%s|%s>', get_permalink( $post ), get_the_title( $post ) );
                  hametuha_slack( $string, [], '#ad' );
                  break;
        }
    }
}, 10, 3 );

ちなみに、破滅派では以下のケースで通知を行っています。

  • 電子書籍の販売申請があった
  • 電子書籍が販売開始された
電子書籍販売通知。ボーダーの色が変でしたね。
電子書籍販売通知。ボーダーの色が変でしたね。

公開される情報だったら、たとえばTwitterの投稿に特定の文字列が入っている場合だけIFTTTとかZapier使ってSlack連携できるので、そっちの方が手っ取り早いかもしれません。

プラグインを利用してもいいのですが、プラグインに該当する機能がない場合やサーバが複数台構成の場合は自分でできるとなにかとはかどります。関数自体も20行程度とシンプルですし、使わなくなったら中身空っぽにしておけばよいので、便利なのではないでしょうか。なにより手作りなので、心がこもっています(真顔)

ちなみに破滅派の運営に興味がある人はこちらを読んでみてください。終わり。

[429] [429] Client error: `POST https://webservices.amazon.co.jp/paapi5/getitems` resulted in a `429 Too Many Requests` response: {"__type":"com.amazon.paapi5#TooManyRequestsException","Errors":[{"Code":"TooManyRequests","Message":"The request was de (truncated...)

すべての投稿を見る

高橋文樹ニュースレター

高橋文樹が最近の活動報告、サイトでパブリックにできない情報などをお伝えするメーリングリストです。 滅多に送りませんので、ぜひご登録お願いいたします。 お得なダウンロードコンテンツなども計画中です。