Matlab から Slack に通知を送る

  • 0
    いいね
  • 0
    コメント

    TL;DR

    1. Get Webhook URL from https://slack.com/services/new/incoming-webhook.
      • You can get URL like https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXXXX
    2. Download slack_incoming.matlab from my gist.
    3. Execute as follows on matlab.

      >> url = 'https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXXXX';
      >> slack_incoming(url, 'text', 'text from matlab', 'channel', '#matlab');
      
    4. You can get message from matlab
      slack_incoming.png

    はじめに

    研究者の間でも(Nature)活用の進むチャットアプリである Slack
    そして、数値計算ソフトウェアとして利用されるMATLAB
    これらを組み合わせることで快適な解析環境の構築を手助けする。

    ソースは以下で公開 (MIT License)
    gist

    必要なもの

    • Matlab (R2017a student でテスト)
      • webwrite 関数が2015a で導入されたものなのでそれ以前の環境では動かない?)
    • Slack (Incoming Webhooks)

    概要

    Slack の Incoming Webhooks に対して、MATLAB の webwrite を用いて HTTPリクエストを送信する。

    方法

    使うまでにいくつかの手順が必要

    SlackのWebhook URLを取得する

    http://qiita.com/vmmhypervisor/items/18c99624a84df8b31008
    を参考にWebhook URLを取得する。

    以下のようなアドレスを取得できる。
    https://hooks.slack.com/TXXXXX/BXXXXX/XXXXXXXXXX
    説明でもこのアドレスを用いるが、使用する際には各自のものに書き換える。

    payload を整形し、POSTする。

    MATLABの関数webwriteを用いることで、指定したURLにデータをPOSTことができる。
    ここではWebhook URLを指定する。

    送信するpayloadの形式はSlackによってJSON形式のkey/valueペア方式と定められている。
    以下の点に注意

    • 改行文字を含まないこと
    • 少なくともtextプロパティ(key)は含めること
      • ただしattachments プロパティがある場合、その値(value)内にtextプロパティがあれば大丈夫なようだ(詳細は未確認)

    例:{"text": "Message from MATLAB", "channel": "#matlab",}

    MATLAB上でこの形式に合うように文字列を作成して送信すればよい。

    関数の説明

    以上の内容を実現するために、今回作成した関数では、payloadの整形を行う部分を実装した。
    help の文章は以下の通り

    >> help slack_incoming
      response = slack_incoming(url, payload)
      url      : [char]  Webhook URL (you have to get Webhook URL from Slack)
      payload  : [char, struct]  payload must be JSON style string or struct
                 # payload is a case when varagin is a single argument 
      varargin : [char/char] optional mode for define payload as key/value pair
    
      response : 'ok'        POST of payload was succeeded.
                 otherwise   failed to POST
    
      see also Slack Incoming Webhooks <https://api.slack.com/incoming-webhooks>
    

    使い方

    入力urlpayload(実体はvarargin)
    出力 はIncoming Webhook の応答('ok'なら成功、それ以外は失敗)

    url は SlackのWebhook URL

    >> url = 'https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXXXX';
    

    payload としては、以下の3パターンを想定している。
    :one: 整形済みの文字列 [char]

    >> # Use JSON str
    >> payload = '{"text":"text from matlab","channel":"#matlab"}'
    
    payload =
    
        '{"text":"text from matlab","channel":"#matlab"}'
    
    >> slack_incoming(url, payload);
    

    :two: JSON形式に従った構造体 [struct]

    >> # Use struct
    >> payload = struct('text', 'text from matlab', 'channel', '#matlab')
    
    payload = 
    
      フィールドをもつ struct:
    
           text: 'text'
        channel: '#matlab'
    
    >> slack_incoming(url, payload);
    

    :three: key/valueペアの可変長入力(偶数個の文字列) [char, char, ...]

    >> # Use key/value pair
    >> slack_incoming(url, 'text', 'text from matlab', 'channel', '#matlab');
    

    わざわざ書き分けたが、 :one:, :two:, :three: の違いはほとんどない
    実際以下の3例は同じ結果になる

    >> slack_incoming(url, 'text', 'text from matlab', 'channel', '#matlab');
    >> slack_incoming(url, struct('text', 'text from matlab', 'channel', '#matlab'));
    >> slack_incoming(url, jsonencode(struct('text', 'text from matlab', 'channel', '#matlab')));
    

    jsonencode は2016bからの実装なので、このコード中では使用していない。

    注意

    • keyの重複のチェックをしていないため、:three: のパターンでは、同じkeyが存在した場合に後の値によって書き換えられる。
    • 基本的に送信する内容のチェックをしていないので、エラーが返ってきたら送信した内容を自分で確認する。

    おすすめの使い方

    毎回 Webhook URL を入力するのは面倒なので以下のような関数を作成し、URLを関数のファイルに直接書き込んでおくと便利である。

    以下のようなことも可能になる。

    • 最初に定義したパラメータが入力に含まれる場合は上書きされるのでデフォルトの値として設定できる。
    • 変更したくないパラメータは送信の直前に書き変えれば入力によって変更できない。
    function response = slack_example(text, varargin)
    %% slack_example(text)
    
    url = 'https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXXXX';
    payload = struct('text', text);
    
    % Default key-value(can be changed)
    payload.channel = '#matlab';
    
    if mod(nargin-1, 2)
      error('slack_example:KEY_VALUE_PAIR', 'options must be {key, value} pair');
    end
    
    
    for fi = 1:(nargin-1)/2
      if ~ischar(varargin{fi*2})
        error('slack_example:ALL_VALUE_MUST_BE_CHAR', 'All value must have char');
      end
      payload.(varargin{fi*2-1}) = varargin{fi*2};
    end
    
    % Restricted key-value (change is not allowed)
    payload.username = 'MATLAB';
    
    response = slack_incoming(url, payload);
    

    実行例:
    このメッセージは #general チャンネルに MATLAB というユーザー名で投稿される。

    >> slack_example('Hello Slack.', 'icon_emoji', ':ghost:', 'channel', '#general', 'username', 'GHOST');
    

    slack_example.png
    ※デフォルトの チャンネルである#matlab#general変更されている点と、ユーザー名であるMATLABGHOST変更されていない点に注目

    まとめ

    • MATLABからSlackへメッセージを送信する関数を作成した。
    • 実行には、Webhook URLを取得する必要がある。
    • 自分用の関数を作成して使うとさらに便利になる。