

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]

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


CC BY-SA 4.0
2023-10-18T17:37:05.553
96521
2023-10-20T07:42:07.307
2023-10-20T05:40:39.470
3060
36023
question
google-apps-script
GASからMisocaAPIを呼び出して取引先登録(formData)しようとするが、なぜか振込先情報のArrayデータエラーが出て完了できない


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

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の管理側にサンプル値を提供してもらうのも良いかもしれません。


CC BY-SA 4.0
2023-10-19T01:39:54.253
96522
2023-10-19T01:39:54.253
19460
96521
answer


## 前提として

Misoca
API上での直接動作確認をしていないですが、SwaggerドキュメントとOpenAPI(v3)を使った簡易的なWebAPIでの挙動を見た上での回答とはなっています。

## 回答本文

下記のように、`bank_accounts[detail]`の値を`formData`内に定義する時点で`.join()`を使ってカンマ区切り文字列にすることで正常に受け付ける可能性があります。

[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'].join(",")
        };
    
[/code]

GASのUrlFetchlAppクラスでpayloadにJavaScriptオブジェクトを渡す場合、「key=string,value=string or
blob」のキーバーリューペアである必要がありそうです。（[Ref1](https://developers.google.com/apps-
script/reference/url-fetch/url-fetch-app?hl=ja#fetchurl,-params)）  
配列の場合、`[Ljava.lang.Object;@698a3686`といったようなGAS内部のオブジェクト表現に変換されてしまいます。（[fetchのかわりにgetRequestを用いることで、リクエストなしに簡易的な挙動確認を行えます](https://developers.google.com/apps-
script/reference/url-fetch/url-fetch-app?hl=ja#getrequesturl,-params)）

Swagger v2のドキュメント上だと、Form parameterを受け付けるAPIに対して`type:
array`な値をポストする際には次のどちらかの形式を要求しています。  
※ドキュメントの例示上だと後者はGETでのみ例示されているが、おそらくPOSTでも可能

  * `param=value1&param=value2`のような「指定パラメータを複数回記述する」形式
  * `param=value1,value2`のような「カンマ区切りの値を指定する」形式

既存のコードの構造としてJavaScriptオブジェクトをpayloadに引き渡す場合、複数の同一キーを持つオブジェクトを作成しようとしても片方に上書きされるため、前者の手法を使うのが難しいです。

そのため、後者の手法を用いてformDataの値を`string[]`形式から`.join()`を使って単一の`string`形式に変換することでAPIが受け付ける可能性があります。


CC BY-SA 4.0
2023-10-20T07:42:07.307
96531
2023-10-20T07:42:07.307
2784
96521
answer