10
7

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 3 years have passed since last update.

MATLAB/SimulinkAdvent Calendar 2020

Day 23

MATLABでもっとLINEにNotifyしたい!

Last updated at Posted at 2020-12-22

これは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(本文)などのプロパティを持つ。methodmatlab.net.http.RequestMethodオブジェクトで、headermatlab.net.http.HeaderFieldオブジェクトで、bodymatlab.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オブジェクトに渡せばよい。

まとめ

担当日かなりギリギリ(というか前日)に、コードの作成、記事の執筆をやってたので結構焦ってた(汗)。
けど、ちゃんと目標の画像の送信ができたのでオールオッケーです。

~~スタンプの送信をやりたいと言ってたのは見なかったことにしてください。~~今週末くらいにやります!
このコードの関数化なども今年中には…
ストックして続報を待て!

10
7
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
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?