0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NetSuiteの保存検索をGoogleスプレッドシートへ転記するためのNetSuite側設定まとめ(RESTlet / OAuth2)

0
Posted at

導入

前回は、NetSuite の保存検索を Google スプレッドシートへ自動転記できる、という全体像を紹介しました。参考

今回は、そのために必要な NetSuite 側の設定 を整理します。

やることは主に4つです。

  • 必要な機能を有効化する
  • OAuth 2.0 用の統合を作る
  • 保存検索を作成する(この記事では省略します)
  • RESTlet を作成・デプロイする

NetSuite の RESTlet は、外部アプリや他の SuiteScript から呼び出せる SuiteScript です。外部連携の入口として使えます。参考

1.必要な機能を有効化する

設定 > 会社 > 機能を有効化 から、以下の機能が有効になっていることを確認します。参考

  • Server SuiteScript
  • REST Web Services
  • Token-Based Authentication
  • OAuth 2.0

2. 統合レコードを作成する

次に、OAuth 2.0 接続のための統合レコードを作成します。

設定 > 統合 > 統合の管理 > 新規 から次の項目を確認して作成します。

  • 状態:有効
  • 承認コード:✓
  • 適用範囲:RESTletに✓
  • リダイレクトURI:GASのウェブアプリURL(次回記事で紹介します)
  • ユーザー資格情報:✓

作成後、次の2項目を確認します。

  • Client ID
  • Client Secret

※クライアント資格情報は作成後に一度しか表示されないため、忘れずに控えておきましょう。

3.RESTlet を作成する

次に、保存検索の結果を返す RESTlet を作成します。

サンプルコード
/**
 * @NApiVersion 2.1
 * @NScriptType Restlet
 *
 * Public-safe sample version:
 * - No default Saved Search ID
 * - searchId is required
 * - pageIndex/pageSize are validated
 * - No stack trace is returned in error responses
 */
define(['N/search'], (search) => {

  function get(params) {
    try {
      const searchId = params && params.searchId ? String(params.searchId).trim() : '';
      if (!searchId) {
        throw new Error('Missing required parameter: searchId');
      }

      const pageIndex = parseInt((params && params.pageIndex) || '0', 10);
      const requestedPageSize = parseInt((params && params.pageSize) || '500', 10);
      const pageSize = Math.min(requestedPageSize, 1000);

      if (!Number.isInteger(pageIndex) || pageIndex < 0) {
        throw new Error('Invalid parameter: pageIndex must be a non-negative integer');
      }

      if (!Number.isInteger(requestedPageSize) || requestedPageSize <= 0) {
        throw new Error('Invalid parameter: pageSize must be a positive integer');
      }

      const s = search.load({ id: searchId });
      const paged = s.runPaged({ pageSize });

      const totalPages = paged.pageRanges.length;
      const columns = s.columns;

      const header = columns.map(c => (c.label || c.name) + (c.join ? `(${c.join})` : ''));

      let rows = [];
      if (pageIndex >= 0 && pageIndex < totalPages) {
        const page = paged.fetch({ index: pageIndex });
        rows = page.data.map(r =>
          columns.map(c => {
            const t = r.getText(c);
            const v = r.getValue(c);
            // Return only string/number/boolean/null to avoid Date/Object surprises.
            const val = (t !== null && t !== '' && t !== undefined) ? t : v;
            return (val === undefined) ? null : val;
          })
        );
      }

      const resp = {
        ok: true,
        meta: { searchId, totalCount: paged.count, totalPages, pageIndex, pageSize },
        header,
        rows
      };

      return JSON.stringify(resp);

    } catch (e) {
      return JSON.stringify({ ok: false, error: String(e) });
    }
  }

  return { get };
});

今回の公開用サンプルでは、SuiteScript 2.1 の RESTlet として次のような処理を行います。

  1. searchId を受け取る
  2. search.load({ id: searchId }) で保存検索を読む
  3. runPaged({ pageSize }) でページングする
  4. header と rows を JSON で返す

RESTlet を作成したらデプロイします。
ここで後から GAS 側に設定する値が出てきます。
image.png

  • RESTlet Base URL
  • Script ID
  • Deploy ID

GAS 側のサンプルでは、これらを次の Script Properties として使います。(次回記事で説明します)

  • NS_RESTLET_BASE_URL
  • NS_RESTLET_SCRIPT_ID
  • NS_RESTLET_DEPLOY_ID

なんとNetsuite側の設定はこれだけです!

次回予告

次の記事では、GAS 側の設定をまとめます。

  • Web アプリとしてのデプロイ
  • Script Properties / User Properties
  • OAuth コールバック
  • スプレッドシート設定
  • 定期実行

まで見ていきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?