WioTerminalでGASのAPIをアクセスするときにはまったこと

2024/03/04に公開

眠っていたWioTerminalがあったので、洗濯物を外干しできるか、いつ頃乾くかお知らせしてくれるガジェットを作りました。その時にGASで作ったWebAPIにアクセスするとき、リダイレクトではまったので対応策をメモしておきます。

GASのWebAPIにアクセスするとどうなるか?

GASでWebアプリとしてデプロイする際に、アクセス先のURLが表示されます。このURLにアクセスするとステータスコード302が戻り、別のところにリダイレクトされます。ライブラリで対応してくれていれば簡単なのですが、今のライブラリはリダイレクトには対応していないっぽいので自前でどうにかしてあげる必要があります。

どう対応したか

ソースコードはこんな感じ。ステータスコードを見て、302が戻ってきたらヘッダーに定義されるLocationからリダイレクト先のURLを取得し、そこから再度接続をするようにします。

String GetRequest(String url) {
  HTTPClient https;
  String payload = "";

  Serial.println("Start GET Request");
  Serial.println(url);

  const char *headerKeys[] = {"Location"};
  const size_t headerKeysCount = sizeof(headerKeys) / sizeof(headerKeys[0]);
  https.collectHeaders(headerKeys, headerKeysCount);  

  if (https.begin(client, url)) {  // HTTPS
    Serial.print("[HTTPS] GET...\n");
    int httpCode = https.GET();

    // Show information
    Serial.printf("[HTTPS] GET... code: %d\n",httpCode);
    Serial.println(https.headers());
    Serial.println(https.header("Location"));

    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      // file found at server
      if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
        payload = https.getString();
        Serial.println(payload);
      } else if (httpCode == HTTP_CODE_FOUND ) {
        // Redirect URL
        String redirect_url = https.header("Location");
        https.end();
        return GetRequest(redirect_url);
      } else {
        payload = https.getString();
        Serial.println(payload);
      }
    } else {
      Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
    }
    https.end();
  } else {
    Serial.printf("[HTTPS] Unable to connect\n");
  }

  return payload;

}

ほかにハマりそうなこと

ソースを見ていたら、MTUのサイズ分しかデータを引っ張ってこないように見えるので、大きなデータを取得しようとする場合は気を付けないといけません。また、一度電源を切らないとWiFiの接続が怪しくなるような挙動も見られました。

Discussion