MATLABからslack apiを使ってプロット画像を投稿する方法

# やりたいこと
MATLABで長時間かかる処理を投げるときに、進歩をSlackで通知できるようにしたい！！
->webwriteでできた！
ついでに(途中)結果のプロット画像を送ってもらえれば、もっとべんりかも！！
->webwriteでうまくできない！！


# 前準備(slack api)
ここにアクセスして、tokenを取得します。
[https://api.slack.com/apps](https://api.slack.com/apps)

Scopesは、**chat:write**と**files:write**を使います。

これとか参考になると思います。
https://qiita.com/ykhirao/items/3b19ee6a1458cfb4ba21




# 文字を送るだけならwebwriteで簡単にできる
　文字だけの通知をSlackに送信したいなら、webwrite関数を使用することで簡単に送信することができます。サンプルコードを載せておきます。
使用するAPIのリファレンスもおいておきます。
[https://api.slack.com/methods/chat.postMessage](https://api.slack.com/methods/chat.postMessage)

```
url = "https://slack.com/api/chat.postMessage";
token = "";  %自分で発行したAPIトークン
text = "test";  %通知の本文
channel = "#チャンネル名";  %送信先のチャンネル
responseData = webwrite(url, "token",token ,"text",text,"channel",channel);
```
# plotを画像にしたい
saveas関数を使用してプロットを画像に保存できます。imgpathには相対絶対パスで画像の保存場所と名前を指定できます。

```
imgpath="適当な画像名";
saveas(gcf,imgpath);
```


# 画像を送りたい
[files.uploadのリファレンス](https://api.slack.com/methods/files.upload)曰く、webwriteの引数に**file**か**contents**で画像を渡すとよさそうです。が、webwriteでいい感じに渡す方法が分かりませんでした。
そこで、[マルチパート フォーム メッセージの送信](https://jp.mathworks.com/help/matlab/matlab_external/send-multipart-form-messages.html)を参考にしてコードを作成しました。

```
import matlab.net.http.*
import matlab.net.http.field.*
import matlab.net.http.io.*

upload_url = matlab.net.URI('https://slack.com/api/files.upload');
token = "";  %自分で発行したAPIトークン
text = "test";  %通知の本文
channel = "#チャンネル名";  %送信先のチャンネル
imgpath = "";  %送信したい画像のパス（保存に使用したものと同じものを使用できる）

provider = MultipartFormProvider('token', token, 'channels', channel, 'filename', imgpath, 'initial_comment', text, "file", FileProvider(imgpath));
req = RequestMessage('POST',[], provider);
responseData = req.send(upload_url);
```

## 自分の環境で発生したエラー
先のコードだと、たまにdatefieldが未来になってしまうエラーが発生しました。
雑な対処として、datefieldをすごい過去にしました。多分こんなことしなくてもいいです。
```
dateField = matlab.net.http.field.DateField(datetime('yesterday'));  %昨日
req = RequestMessage('POST',[dateField], provider);
```


# いいかんじにまとめたやつ
自分で使う用にいい感じの関数を作成したので、おまけに載せておきます。
自分のトークンとチャンネル名、画像のパスを指定すれば使えます。
画像名に日時を入れて重複避けにしています。
パスの記述がWindowsなので、困る人は書き換えるとよいです。


SlackSend(text)：textの文字列をSlackに投稿できます。
SlackSend(text,gcf,title)：titleを画像名に含めて現在のプロット画像を保存し、textの文字列を本文として画像Slackに投稿できます。

```
function SlackSend(text,myGCF,title)
import matlab.net.http.*
import matlab.net.http.field.*
import matlab.net.http.io.*

url = matlab.net.URI("https://slack.com/api/chat.postMessage");
token = "";
channel = "";

image_dir=".";

dateField = matlab.net.http.field.DateField(datetime('yesterday'));
    switch nargin
        case 1
            provider = MultipartFormProvider( "token",token ,"text",text,"channel",channel);
            req = RequestMessage('POST',[dateField], provider);
            responseData = req.send(url);

        case 3
            %保存するよ
            imgname = append(title,"_", char(datetime('now','Format','yyyyMMddHHmmss')), '.png');
            imgpath= append(image_dir , '\', imgname);          
            saveas(myGCF,imgpath);
            
            % file.upload APIのURL
            upload_url = matlab.net.URI('https://slack.com/api/files.upload');
            
            % Slackに送信  
            provider = MultipartFormProvider('token', token, 'channels', channel, 'filename', imgname, 'initial_comment', text, 'title', title, "file", FileProvider(imgpath));

            req = RequestMessage('POST',[], provider);
            responseData = req.send(upload_url);
        otherwise
            disp("SlackSend:の数が合わないよ");
    end
end
```