これはMATLAB/Simulink Advent Calendar 2020 23日目の記事です。昨日は@griffin921さんのカバレッジってなんですか?~元ハードエンジニアから見た見解~でした。
2020/12/28更新
スタンプの送信やちょろまかしてた箇所の修正を行いました。思ったより分量が大きくなったので、こちらの記事にまとめています。よしなに!
これは何?
ぶっちゃけると、これの焼き増しです。
フィルムカメラかな?
環境
MATLAB R2020a
今できること、やりたいこと
できること
- matlabからlineにメッセージを送る
やりたいこと
- HTTPインターフェースでやる
- スタンプの送信
- 画像の送信
課題
この前作ったものではLINE APIを叩くのにRESTful Webサービス関数を使っていた。ところが、Webサービスの中には「RESTful Web サービスの関数でサポートされていない機能を必要」とするものがあるようで、実際、画像の送信の糸口はつかめていなかった。
一方で、HTTPインターフェースの方にはmatlab.net.http.io.ContentProvider
クラスがあり、画像やファイルの送信も手軽にできそう。前回のリベンジを兼ねて、HTTPインターフェースを用いての実装をめざした。
HTTPインターフェースでのメッセージの送信
とりあえずコード
import matlab.net.http.io.*
import matlab.net.http.*
import matlab.net.*
msg = "test message from MATLAB";
token = 'hogehoge';
method = RequestMethod('POST');
header = HeaderField('Authorization', ['Bearer ', token], 'Content-Type', 'application/x-www-form-urlencoded');
msg_provider = FormProvider('message');
msg_provider.Parameters.Value = msg;
r = RequestMessage(method, header, msg_provider);
uri = URI('https://notify-api.line.me/api/notify');
resp = send(r,uri);
status = resp.StatusCode
(やっぱり)申し訳程度の解説
HTTPインターフェースではHTTPメッセージの送信にsend
を用いる。その引数にメッセージと送り先(URL/URI)を渡すわけだけど、前回のwebwrite
と違ってcharやstringでベタ打ちができない。メッセージにはmatlab.net.http.RequestMessage
オブジェクトを渡してあげる必要がある(URL/URIはcharやstringでもOK)。
matlab.net.http.RequestMessage
オブジェクトはmethod
(要求メソッド)、header
(ヘッダー)、body
(本文)などのプロパティを持つ。method
はmatlab.net.http.RequestMethod
オブジェクトで、header
はmatlab.net.http.HeaderField
オブジェクトで、body
はmatlab.net.http.MessageBody
オブジェクトかmatlab.net.http.io.ContentProvider
オブジェクトで指定してやる必要がある。
要求メソッドはPOST
に指定。LINE Notify API Documentに書いてた。
ヘッダーには、認証情報と本文のContent-Type
を指定。LINE Notify API Documentには、「Content-Typeはapplication/x-www-form-urlencoded
もしくはmultipart/form-data
」とあったんだけど、前者しかうまくいかなかった。
本文はMessageBody
オブジェクトではなく、ContentProvider
の子クラスのFormProvider
オブジェクトで指定。これはトライ&エラーを繰り返して見つけたんだけど、Content-Type
が「なんちゃらform」ってなってるところから気づくべきだった。
画像の送信
とりあえずコード
import matlab.net.http.io.*
import matlab.net.http.*
import matlab.net.*
msg = "test message from MATLAB";
token = 'hogehoge';
method = RequestMethod('POST');
header = HeaderField('Authorization', ['Bearer ', token], 'Content-Type', 'multipart/form-data');
msg_provider = matlab.net.http.io.FormProvider('message');
msg_provider.Parameters.Value = msg;
img_provider = matlab.net.http.io.FileProvider('test.png');
provider = MultipartFormProvider('message', msg_provider, 'imageFile', img_provider);
r = RequestMessage(method, header, provider);
uri = 'https://notify-api.line.me/api/notify';
resp = send(r,uri);
status = resp.StatusCode
(やっぱり)申し訳程度の解説
画像を送信するとき(スタンプを送るときもだけど)、注意すべきはメッセージがないと400エラーを返されて終わるということ。コマンドウィンドウにエラーが表示されるわけではないので分かりにくいったらありゃしない。そういうわけで、画像やスタンプを送るときもメッセージを送らないとダメなんだけど、RequestMessage
オブジェクトはbody
を1つしか持てない。
というわけで、新しいクラス、matlab.net.http.io.MultipartFormProvider
クラスの登場。このオブジェクトは複数のContentProvider
オブジェクトをまとめて持つことができる。こいつにメッセージを入れたmsg_provider
と画像ファイルを入れたimg_provider
を渡して、生成されたMultipartFormProvider
オブジェクトをRequestMessage
オブジェクトに渡せばよい。
まとめ
担当日かなりギリギリ(というか前日)に、コードの作成、記事の執筆をやってたので結構焦ってた(汗)。
けど、ちゃんと目標の画像の送信ができたのでオールオッケーです。
~~スタンプの送信をやりたいと言ってたのは見なかったことにしてください。~~今週末くらいにやります!
このコードの関数化なども今年中には…
ストックして続報を待て!