はじめに
とある事情があり、スマートロックほしい。スマートロック超便利。作ろう。となったので作ったのですが。色々な罠を踏み抜いたのでそれを書いていきます。なお、大量に罠を踏み抜いた理由は以下のような変な構成にしたからです。(この構成にした理由は、上からの「早く作りなさい」という圧力と、私のスキル)
さて、三回目の今回はWebHook編です。
WebGLでネットワークを使う
前回の、UnityのWebGLではネットワークが使えないというままだと救いがないのでUnity WebGLでネットワークを使う方法を紹介してきます。
UnityのNetWork
WebGLではWWW
クラスとUnityWebRequest
クラスが使えます。今はWWW
は使わないほうがいいとされています。使い方は以下のもののようです。
kanのメモ帳 : UnityWebRequestの使い方【Unity】
私が作っているときは上のような便利なページを見つけられなかったので以下のようにJSで書きました。サンプル数は圧倒的にJSのほうが多いです。
JSでNetWork
UnityでJSを使うには.jslibにJSの関数を書いて、C#から呼び出します。公式ページの説明はこちらです。
URLにpostすることを元に解説していきます。
mergeInto(LibraryManager.library, {
//ここに関数を書く
})
基本はこの形です。
次に、関数を宣言していきます。
mergeInto(LibraryManager.library, {
post1: function (url, msg1, msg2) {
//中身
}, //複数の関数を書くときは間にコロンを忘れずに
post2: function (url, msg1, msg2){
//同じく
} //最後のところにはコロンはないよ
}
このように書くと、ダブルコロンの前が関数名となり、かっこの中はC#と同じように引数となります。型名を書かないのがJSです。
このように書いた関数を、C#(Unity)から使うには以下のようにします。
public static class Hoge{
[DllImport("__Internal")]
private static extern void post1(string url, string msg1, string msg2);
[DllImport("__Internal")]
private static extern void post2(string url, string msg1, string msg2);
}
[DllImport("__Internal")]
の後に.jslibで書いた関数と同じ名前、同じ引数の数の関数を宣言すると、使えるようになります。
JSONでURLにPost
ではJSON形式でURLにPostする関数を作ります。
post1(url, msg1, msg2){
var j_url = Pointer_stringify(url);
var j_msg1 = Pointer_stringify(msg1);
var j_msg2 = Pointer_stringify(msg2);
}
string型は、そのままJSに渡せないので、Pointer_stringify()
関数を使ってJSのstringにします。
それでは完成させます。
post1: function(url, msg1, msg2){
var j_url = Pointer_stringify(url);
var j_msg1 = Pointer_stringify(msg1);
var j_msg2 = Pointer_stringify(msg2);
//これはJSONで送ってるよと伝える
var headers = new Headers({
'Content-Type': 'application/json',
});
//中身のJSONにする配列製作
var bodys = {
"msg1": j_msg1,
"msg2": j_msg2, //JSでJSON(というか配列)を作るときは最後の後のコロンを忘れずに
};
//これでURLにPOSTしている
fetch(j_url,{
method : 'POST',
headers : headers,
body : JSON.stringify(bodys)
});
},
URLエンコードでURLにPost
次に、URLエンコードでURLにPostします。
var bodys = 'msg1=' + encodeURIComponent(j_msg1) + '&msg2=' + encodeURIComponent(j_msg2);
変数名=encodeURIComponent(中身)
としてやることで、bodyをURLエンコードできます。変数をいくつも送るときは、間を&
でつなぎます。その他はJSONの時とほぼ変わりません。
完成版は以下です。
post2: function(url, msg1, msg2){
var j_url = Pointer_stringify(url);
var j_msg1 = Pointer_stringify(msg1);
var j_msg2 = Pointer_stringify(msg2);
//JSONじゃなくてURLエンコードなのに注意
var headers = new Headers( {
'Content-Type': 'application/x-www-form-urlencoded',
}
);
var bodys = 'msg1=' + encodeURIComponent(j_msg1) + '&msg2=' + encodeURIComponent(j_msg2);
fetch(j_gas,{
method : 'POST',
body : bodys,
headers : headers
}
);
}
Beebotteに情報を送る
以上のことを踏まえて、どのような壁に当たってどのような罠にはまって最終的にどのように実現したのか書いていきます。
Beebotte SDK の罠
BeeBotteには、C#用のSDKもあり、こりゃ楽だと思っていました。Editor上では。しかし、このSDKも例にもれず.NETのNetworking
を使っていましたので、当然ブラウザ上では動きませんでした。
何とか原因を見つけ出し、SDKにあった.NETのNetworking
を全てUnityのものに置き換えたところ、次の罠が待って今した。(なお、SDK自体は使いやすかったです。)
http-request-headerの罠
UnityのWebReqestに置き換えたものをブラウザ上で実行したところ、http requestのdateは変更することはできません
みたいなエラーが出ました。(詳細なエラーメッセージ覚えていなくてすいません。)
色々調べたところ、どうやらchromeではセキュリティー的にいくつかのhttp-request-headerの値は変更できないみたいです。ということで全く別の道を探す必要が出てきました。
公式に載っていた別のやり方(失敗)
- beebotteの公式にクライアント側のJSでPublishできるものがあったが、サーバーを経由するもので、サーバーレスの今回は断念。
- MQTTで送信するJSはあったが、node.jsのもので、MQTTからMQTTは送れないので断念。
なんとかbeebotteへ送れた
必死に公式のドキュメントを見ていると、cURLの物ってそのままPostではないか?うまく書き直したら行けるのでは?と思い、これが大当たり。何とかなりました。以下がcURL。
curl -i -H "Content-Type: application/json" \
-H "X-Auth-Token: YOUR_CHANNEL_TOKEN" \
-X POST -d '{"data":"Hello World"}' \
http://api.beebotte.com/v1/data/publish/private-(チャンネル名)/(トピック名)
そして、以下がJSに直したもの。
var j_url = "http://api.beebotte.com/v1/data/publish/private-(チャンネル名)/(トピック名)";
var j_token = "YOUR_CHANNEL_TOKEN";
var bodys = {
"data" : "Hello World",
};
const headers = new Headers( {
"Content-type" : "application/json",
"X-Auth-Token": j_token,
}
);
fetch(j_url, {
method : 'POST',
body : JSON.stringify(bodys),
headers: headers
}
LineBotに情報を送る
多人数で鍵の管理をする予定だったので、開けたり、閉めたりする時に通知があると便利だと思い作りました。
LineBotに関しては皆さんよくやられているようで、たくさん参考資料があってやりやすかったです。また、公式のドキュメントは豊富でした。(ただし肝心のところがないのはお約束)
LineBotの罠1
Webhookがあったので直接Postしようとしましたが、CORSによってはじかれました。よって、GASを経由して送るという方針に転換しました。ただ、一つ罠あったんですけど。
GASの罠
bodyをLineで使うJSON形式でPostしましたが、これがいけませんでした。GASへはJSON形式でPostできないようです。(なぜかCORSエラーが返ってきて謎だった。)そのため、x-www-form-urlencoded
でPostしました。
LineBotの罠2
運用に入ってから気づいたことなのですが、異様に早くメッセージの上限に達しました。なぜかと理由を探ったところ、グループでは、一発言につき人数分の発言をしたこととなるようです。(おかげで数日しか持たないbotとなった)
SlackBotに情報を送る
こちらはLine以上に資料があり、Webhookのインテグレーションもすんなりと行き、ほぼ問題なくできました。一点を除いては。
SlackBotの罠
こちらもJSONのPostができませんでした。しかし、こちらは少々特殊で、http-request-header
のContent-Type
をapplication/x-www-form-urlencoded
するだけですんなり通りました。なんでやねん。body、JSONや。
The next is...
なんとか他のサービスにつなげることができたのでここは以上です。次はラズパイ編です。
シリーズ一覧
- NCMB編
- Unity WebGL編
- WebHook編 ←いまここ
- ラズパイ編