概要
- カスタムコネクタからSwitchBotのAPI v1.1に接続する方法です。
- APIバージョン1.1ではセキュリティが強化され、tokenに加えて、secretキーを使って計算したsignatureを付加する必要があります。 カスタムコネクタ標準のAPI キーだけでは接続できなくなりました。
- そこで、C# カスタムコードを使って認証情報を付加することで接続を実現します。
Power AutomateとSwitchBot
Power AutomateとSwitchBotの連携については以下の記事が分かりやすいです。
IFTTTなら標準でコネクタが用意されているようですが、Power Automateではカスタムコネクタを作って対応します。
APIの利用
tokenやsecretの発行にはスマホアプリを利用します。
最新のアプリをインストールして発行すると、自動的にv1.1のAPIを利用する形になります。
設定→アプリバージョンを10回タップで発行されます。
詳細は以下ページにあります。
カスタムコネクタ
コネクタ自体は一から作る必要はありません。
既に素晴らしいものを作って下さっている方がいます。
※v1.0のものなので、少しだけ変更が必要な部分があります。
以下からswagger.jsonをダウンロードし、
カスタムコネクタの新規作成→オープンAPIをインポート から取り込みます。
変更する部分
セキュリティ
変更の必要はないのですが、パラメータ名がAuthorizationになっていることを確認しておきます。
後でカスタムコードからAuthorizationヘッダの情報を取得して利用します。
コード(プレビュー)
コードが有効をオンにします。
貼り付けるコードは次項で解説します。
接続
テストの前に接続を作成しますが、APIキーにはアプリで発行した「token」だけを貼り付けます。
カスタムコードの登録
登録するコード
以下のコードをカスタムコードに登録します。
貼り付けた後は、コネクタの更新を押してコードを登録します。
カスタムコネクタが呼び出されると、ExecuteAsync()が実行され、
HttpHeadersに必要な認証情報が付加されます。
AddHttpHeadersの部分は、つい最近、C#版のサンプルコードが公開されましたので、コピペしただけですw
→https://github.com/OpenWonderLabs/SwitchBotAPI#open-token-and-secret-key
その部分を除けばほんの数行で実装できます。
public class Script: ScriptBase {
// 自身のsecretを設定
readonly string _secret = Secrets.config["secret"];
public override async Task<HttpResponseMessage> ExecuteAsync() {
var token = Context.Request.Headers.Authorization.ToString();
AddHttpHeaders(Context.Request.Headers , token, _secret);
return await Context.SendAsync(Context.Request, CancellationToken);
}
/// <summary>
/// headers にsignatureを付加します。
/// </summary>
/// <param name="headers"></param>
/// <param name="token"></param>
/// <param name="secret"></param>
private void AddHttpHeaders(HttpRequestHeaders headers, string token, string secret)
{
// https://github.com/OpenWonderLabs/SwitchBotAPI#api-usage
DateTime dt1970 = new DateTime(1970, 1, 1);
DateTime current = DateTime.Now;
TimeSpan span = current - dt1970;
long time = Convert.ToInt64(span.TotalMilliseconds);
string nonce = Guid.NewGuid().ToString();
string data = token + time.ToString() + nonce;
Encoding utf8 = Encoding.UTF8;
HMACSHA256 hmac = new HMACSHA256(utf8.GetBytes(secret));
string signature = Convert.ToBase64String(hmac.ComputeHash(utf8.GetBytes(data)));
// headers.TryAddWithoutValidation(@"Authorization", token);
headers.TryAddWithoutValidation(@"sign", signature);
headers.TryAddWithoutValidation(@"nonce", nonce);
headers.TryAddWithoutValidation(@"t", time.ToString());
}
}
変更が必要な部分
Secrets.config["secret"]
の部分をアプリから取得した「secret」に変更します。
// 元
readonly string _secret = Secrets.config["secret"];
// 自分のsecretキーに変更
readonly string _secret = "Your secret key";
コードに直接打ち込む形になるため自己責任でお願いします。
仕組み的なもの
カスタムコードを使うと、通常のコネクタの処理を上書きし、APIを呼び出す際に独自のロジックを追加できます。
Context.Request
には、HttpRequestMessage
が格納されており、カスタムコネクタで定義したHeadersやBodyの情報が入っています。
C#のコードによって、HttpRequestMessage
やHttpResponseMessage
を編集したり、新たに付加することができます。
この仕組みを使うことで複雑な認証のAPIにも対応できます。
何よりも、カスタムコネクタだけで完結できることが最大のメリットですね。
テスト
テストを行って動作を確認します。
後はお好きなフローやアプリを構築するだけです。
開発するときのコード
後ほどリポジトリを公開します。
ローカルの開発環境を作っておくと、Contextにインテリセンスが効くのでコーディングしやすいです。
※
こちらの記事もよろしくお願いします