GASからMisocaAPIを呼び出して取引先登録(formData)しようとするが、なぜか振込先情報のArrayデータエラーが出て完了できない


GASをつかってMisoca APIから取引先を登録するコードを書いています。  
そして、Misoca APIの取引先登録APIのリクエスト形式はこうなっています。

MIsoca API v3 ドキュメント：  
<https://doc.misoca.jp/>

[![Misoca
API取引先登録](https://i.stack.imgur.com/NziT8.png)](https://i.stack.imgur.com/NziT8.png)

私が書いたコードは以下の通りです。

[code]

    function regContentGroup() {
      //アクセストークンの取得
      var service = getService_();
      //アプリケーション認証履歴の確認
      if (service.hasAccess()) {
        var bankData = [];
        bankData.push("ほげ銀行 日本支店 (普) 00000000 サンプルコウザ");
        //パラメーター群の設定
        var formData = {
          'recipient_name': 'サンプル２株式会社',
          'recipient_title': '御中',
          'recipient_ruby': 'サンプルニカブシキガイシャ',
          'tax_option': 'USE_SENDER',
          'mail_settings[subjects][estimate]': 'お見積もり書',
          'mail_settings[subjects][delivery_slip]': '納品明細書',
          'mail_settings[subjects][invoice]': 'ご請求書',
          'bank_accounts[detail]': ['ほげ銀行 ほげ支店 (普) 123456789', 'ふが信用金庫 ふが支店 (当) 987654321']
        };
        //認証履歴がある場合の処理
        var url = 'https://app.misoca.jp/api/v3/contact_group'; //取引先登録エンドポイント
        var options = {
        'method' : 'post',
        'headers' : {Authorization: 'Bearer ' + service.getAccessToken()},
        'payload' : formData,
      };
      var response = UrlFetchApp.fetch(url, options);
      //返却された情報の処理
      var result = JSON.parse(response.getContentText());
      Logger.log(JSON.stringify(result, null, 2));
      } else {
        //認証履歴がない場合の処理
        var authorizationUrl = service.getAuthorizationUrl();
        Logger.log('Open the following URL and re-run the script: %s',
            authorizationUrl);
      }
    }
    
[/code]

そしてこのコードを実行すると、以下のようなエラーコードが返ってきます。

[code]

    Exception: Request failed for https://app.misoca.jp returned code 400. Truncated server response: {"error":"bank_accounts is invalid"} (use muteHttpExceptions option to examine full response)
    
[/code]

架空の銀行口座なのがいけないのかと思い、実際に存在する自分の口座を設定してみたりもしたのですが、一向に成功しませんでした。

※ちなみに、銀行口座のパラメーターを省いてリクエストすると成功します。  
その際のレスポンス

[code]

    {
      "id": ******, //IDは伏せ字
      "user_id": ******, //IDは伏せ字
      "recipient_name": "サンプル２株式会社",
      "recipient_ruby": "サンプルニカブシキガイシャ",
      "recipient_title": "御中",
      "mail_settings": {
        "subjects": {
          "estimate": "お見積もり書",
          "delivery_slip": "納品明細書",
          "invoice": "ご請求書"
        }
      },
      "trashed": false,
      "trashed_at": null,
      "tax_option": "USE_SENDER",
      "corporate_number": null,
      "lock_version": 0,
      "created_at": "2023-10-19T02:43:20.000+09:00",
      "updated_at": "2023-10-19T02:43:20.000+09:00",
      "bank_accounts": []
    }
    
[/code]

もしかすると、ものすごく初歩的なミスに気づけていないだけかもしれませんが  
どなたかご教示いただければと思います。




テストをすることができないため、この回答は推測によります。

UrlFetchAppを使ってformDataとしてオブジェクトを送る場合、値は文字型に自動で変換されます。このとき、`'bank_accounts[detail]':
['ほげ銀行 ほげ支店 (普) 123456789', 'ふが信用金庫 ふが支店 (当) 987654321']`では、オブジェクトである`['ほげ銀行
ほげ支店 (普) 123456789', 'ふが信用金庫 ふが支店 (当)
987654321']`がそのまま使用されるため、`[Ljava.lang.Object;###`のような値に変換されてしまいます。[Ref1](https://stackoverflow.com/q/67896066),
[Ref2](https://stackoverflow.com/q/75368758) これはGoogle Apps
Scriptの仕様のようです。表示されているスクリプトとエラーメッセージからこれが問題になっているのではないかと推測しました。

これを修正すると、次のような修正はいかがでしょうか。テストができないため、複数提案させていただきます。全て外れの場合はすみません。

### 修正案1

#### From:

[code]

    var formData = {
      'recipient_name': 'サンプル２株式会社',
      'recipient_title': '御中',
      'recipient_ruby': 'サンプルニカブシキガイシャ',
      'tax_option': 'USE_SENDER',
      'mail_settings[subjects][estimate]': 'お見積もり書',
      'mail_settings[subjects][delivery_slip]': '納品明細書',
      'mail_settings[subjects][invoice]': 'ご請求書',
      'bank_accounts[detail]': ['ほげ銀行 ほげ支店 (普) 123456789', 'ふが信用金庫 ふが支店 (当) 987654321']
    };
    
[/code]

#### To:

[code]

    var formData = {
      'recipient_name': 'サンプル２株式会社',
      'recipient_title': '御中',
      'recipient_ruby': 'サンプルニカブシキガイシャ',
      'tax_option': 'USE_SENDER',
      'mail_settings[subjects][estimate]': 'お見積もり書',
      'mail_settings[subjects][delivery_slip]': '納品明細書',
      'mail_settings[subjects][invoice]': 'ご請求書',
      'bank_accounts[detail]': ['ほげ銀行 ほげ支店 (普) 123456789', 'ふが信用金庫 ふが支店 (当) 987654321']
    };
    formData = Object.entries(formData).flatMap(([k, v]) => Array.isArray(v) ? v.map(e => `${k}=${e}`) : `${k}=${v}`).join("&");
    
[/code]

### 修正案2

#### From:

[code]

    var formData = {
      'recipient_name': 'サンプル２株式会社',
      'recipient_title': '御中',
      'recipient_ruby': 'サンプルニカブシキガイシャ',
      'tax_option': 'USE_SENDER',
      'mail_settings[subjects][estimate]': 'お見積もり書',
      'mail_settings[subjects][delivery_slip]': '納品明細書',
      'mail_settings[subjects][invoice]': 'ご請求書',
      'bank_accounts[detail]': ['ほげ銀行 ほげ支店 (普) 123456789', 'ふが信用金庫 ふが支店 (当) 987654321']
    };
    
[/code]

#### To:

[code]

    var formData = {
      'recipient_name': 'サンプル２株式会社',
      'recipient_title': '御中',
      'recipient_ruby': 'サンプルニカブシキガイシャ',
      'tax_option': 'USE_SENDER',
      'mail_settings[subjects][estimate]': 'お見積もり書',
      'mail_settings[subjects][delivery_slip]': '納品明細書',
      'mail_settings[subjects][invoice]': 'ご請求書',
      'bank_accounts[detail]': ['ほげ銀行 ほげ支店 (普) 123456789', 'ふが信用金庫 ふが支店 (当) 987654321']
    };
    formData = Object.entries(formData).map(([k, v]) => `${k}=${v}`).join("&"); // or formData = Object.entries(formData).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join("&");
    
[/code]

### 修正案3

#### From:

[code]

    'bank_accounts[detail]': ['ほげ銀行 ほげ支店 (普) 123456789', 'ふが信用金庫 ふが支店 (当) 987654321']
    
[/code]

#### To:

[code]

    'bank_accounts[detail]': JSON.stringify(['ほげ銀行 ほげ支店 (普) 123456789', 'ふが信用金庫 ふが支店 (当) 987654321'])
    
[/code]

### 修正案4

#### From:

[code]

    'bank_accounts[detail]': ['ほげ銀行 ほげ支店 (普) 123456789', 'ふが信用金庫 ふが支店 (当) 987654321']
    
[/code]

#### To:

[code]

    'bank_accounts[detail][0]': 'ほげ銀行 ほげ支店 (普) 123456789',
    'bank_accounts[detail][1]': 'ふが信用金庫 ふが支店 (当) 987654321',
    
[/code]

### Note:

残念ながら、公式のドキュメントには具体的なサンプルが掲載されていないため、上記の修正案が正しいかどうかは不明です。また、それぞれの値である`ほげ銀行
ほげ支店 (普)
123456789`のフォーマットも正しいかどうか不明です。そのため、もしも上記の案で解決しない場合は、APIの管理側にサンプル値を提供してもらうのも良いかもしれません。

