#PowerAutomate のカスタムコネクタでSwitchBot API v1.1に接続する

# 概要
- カスタムコネクタからSwitchBotのAPI v1.1に接続する方法です。
- APIバージョン1.1ではセキュリティが強化され、tokenに加えて、secretキーを使って計算したsignatureを付加する必要があります。 カスタムコネクタ標準のAPI キーだけでは接続できなくなりました。
- そこで、C# カスタムコードを使って認証情報を付加することで接続を実現します。

# Power AutomateとSwitchBot
Power AutomateとSwitchBotの連携については以下の記事が分かりやすいです。
IFTTTなら標準でコネクタが用意されているようですが、Power Automateではカスタムコネクタを作って対応します。

https://qiita.com/f-sumiko/items/2225fffd5ceb1f493b7b

https://speakerdeck.com/rnakamuramartiny/power-automate-woshi-tuterokododedian-zi-ji-qi-wocao-zuo-siyou

# APIの利用
tokenやsecretの発行にはスマホアプリを利用します。
最新のアプリをインストールして発行すると、自動的にv1.1のAPIを利用する形になります。
設定→アプリバージョンを10回タップで発行されます。

詳細は以下ページにあります。

https://github.com/OpenWonderLabs/SwitchBotAPI#getting-started


# カスタムコネクタ
コネクタ自体は一から作る必要はありません。
既に素晴らしいものを作って下さっている方がいます。
※v1.0のものなので、少しだけ変更が必要な部分があります。

以下からswagger.jsonをダウンロードし、
カスタムコネクタの新規作成→オープンAPIをインポート から取り込みます。

https://github.com/rnakamuramartiny/PowerPlatformCustomConnector/blob/main/SwitchBot.swagger.json

## 変更する部分

**全般**
v1.0の部分をv1.1に変更するだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/e7432e84-ae9f-095d-978e-15d28c524113.png)

**セキュリティ**
変更の必要はないのですが、パラメータ名がAuthorizationになっていることを確認しておきます。
後でカスタムコードからAuthorizationヘッダの情報を取得して利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/91223e6f-a344-337e-0466-c29f09f2cddc.png)

**コード(プレビュー)**

コードが有効をオンにします。
貼り付けるコードは次項で解説します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/807f668d-489b-d455-9957-5e46814aebfd.png)


**接続**
テストの前に接続を作成しますが、APIキーにはアプリで発行した「token」だけを貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/a08cce41-6e99-31e7-0b6f-0faf0d46ad37.png)


<br>

# カスタムコードの登録

## 登録するコード
以下のコードをカスタムコードに登録します。
貼り付けた後は、コネクタの更新を押してコードを登録します。

カスタムコネクタが呼び出されると、ExecuteAsync()が実行され、
HttpHeadersに必要な認証情報が付加されます。

AddHttpHeadersの部分は、つい最近、C#版のサンプルコードが公開されましたので、コピペしただけですｗ
→https://github.com/OpenWonderLabs/SwitchBotAPI#open-token-and-secret-key

その部分を除けばほんの数行で実装できます。

```cs

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」に変更します。

```cs
// 元
readonly string _secret = Secrets.config["secret"];
// 自分のsecretキーに変更
readonly string _secret = "Your secret key";
```

コードに直接打ち込む形になるため自己責任でお願いします。

## 仕組み的なもの
カスタムコードを使うと、通常のコネクタの処理を上書きし、APIを呼び出す際に独自のロジックを追加できます。

```Context.Request``` には、```HttpRequestMessage```が格納されており、カスタムコネクタで定義したHeadersやBodyの情報が入っています。
C#のコードによって、```HttpRequestMessage```や```HttpResponseMessage```を編集したり、新たに付加することができます。
この仕組みを使うことで複雑な認証のAPIにも対応できます。

何よりも、カスタムコネクタだけで完結できることが最大のメリットですね。

# テスト
テストを行って動作を確認します。
後はお好きなフローやアプリを構築するだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/6f687d30-5fb4-7de4-00a8-789a9a80df5e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/776fac37-1639-19af-a662-b1d06512a14f.png)


# 開発するときのコード
後ほどリポジトリを公開します。

ローカルの開発環境を作っておくと、Contextにインテリセンスが効くのでコーディングしやすいです。
※
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/ae6edbb0-8374-08be-fec1-528e87c83101.png)


# こちらの記事もよろしくお願いします

https://qiita.com/Rambosan/items/7cda28bac81da794b935

https://qiita.com/Rambosan/items/4fcc5b3055c86403f652