カスタム項目(additionalItems)に保存したデータをカスタム項目(Schedule datastore)に移行する

目次

はじめに

Garoon スケジュールのカスタム項目(additionalItems)廃止のスケジュール で案内したとおり、カスタム項目(additionalItems)を段階的に廃止します。

この記事では、Garoon パッケージ版の利用者向けに、Node.js を使って、カスタム項目(additionalItems)に保存したデータをカスタム項目(Schedule datastore)に移行するサンプルコードを紹介します。

サンプルコード

予定 ID が 1 の予定データについて、additionalItems に登録されている値を Schedule datastore に移行するサンプルコードです。

実際には 1 件の予定を取得する を使って予定データを取得し、取得した予定データの ID を使って繰り返し処理してください。
システムへの負荷を考慮するため、予定の期間を指定するなど、移行する対象の予定を絞り込んで実施してください。

対象の Garoon のバージョン

サンプルコードの動作対象は、パッケージ版 Garoon 5.9 または 5.15 です。
動作確認は、パッケージ版 Garoon 5.15.2 で行っています。
クラウド版ではすでにカスタム項目(additionalItems)の機能を利用できないため、このサンプルコードは動作しません。

下準備

サンプルコードを実行するパソコンに、 Node.js (External link) をインストールします。
サンプルコードは、Node.js v18.18.0 で動作を確認しています。

STEP1:プロジェクトのディレクトリーの作成

プロジェクトのディレクトリーを作成します。

1
2
mkdir migrate-additionalitems
cd migrate-additionalitems

STEP2:必要なライブラリのインストール

package.json を作成します。

1
npm init -y

必要なライブラリをインストールします。

1
npm install node-fetch@v2

STEP3:JavaScript ファイルの作成

次の内容をテキストエディタに貼り付け、ファイルを保存します。
ここでは例として、ファイル名を「sample.js」とします。

利用中の Garoon の環境に合わせて、次の箇所を変更してください。

  • garoonUrl(13 行目):Garoon をインストールしているサーバーの URL
    Windows 版と Linux 版で URL が異なります。

    • Windows 版の例:http://IP_ADDRESS_OR_HOST_NAME/scripts/INSTALL_IDENTIFER/grn.exe
    • Linux 版の例:http://IP_ADDRESS_OR_HOST_NAME/cgi-bin/INSTALL_IDENTIFER/grn.cgi

    環境に合わせてそれぞれ以下を置き換えてください。

    • IP_ADDRESS_OR_HOST_NAME:Garoon のインストール先の IP アドレスまたはホスト名
    • INSTALL_IDENTIFER:Garoon のインストール識別子

これはヘルプに掲載している Windows のディレクトリー構成 (External link) または Linux 版のディレクトリー構成 (External link) でインストールしたときの例です。
インストールするディレクトリーを変更している場合は、パスを読み替えてください。

  • username(16 行目):Garoon REST API を実行するユーザーのログイン名
  • password(17 行目):Garoon REST API を実行するユーザーのパスワード
  • customName(22 行目):カスタム項目(Schedule datastore)のキー名
    移行するカスタマイズに合わせた、独自のキー名を設定してください。
    キー名の命名規則は、 カスタム項目(Schedule datastore) の命名規則 を参照してください。
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
/* global Buffer */
/*
 * カスタム項目(additionalItems)に保存したデータをカスタム項目(Schedule datastore)に移行するサンプルコード
 * Copyright (c) 2019 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */
'use strict';
const fetch = require('node-fetch');

// Garoon をインストールしているサーバーの URL(以下は、Windows 版の場合)
const garoonUrl = 'http://サーバーのIPアドレスまたはホスト名/scripts/インストール識別子/grn.exe';

// Garoon のログイン名とパスワード
const username = 'YOUR_USER_NAME';
const password = 'YOUR_USER_PASSWORD';

// カスタム項目(Schedule datastore)のキー名
// カスタマイズに応じて変更してください
// 命名規則は https://cybozu.dev/ja/garoon/docs/js-api/schedule/set-schedule-datastore/#naming_rule を参照してください
const customName = 'com.example.sample.additionalItemsBackup';

const buff = new Buffer.from(`${username}:${password}`);
const headers = {
  'X-Cybozu-Authorization': buff.toString('base64'),
};

/**
 * additionalItems に登録されている値を取得する
 * @param scheduleId 予定ID
 * @returns additionalItems に登録されている値
 */
async function getAdditionalItemsValue({scheduleId}) {
  const resp = await fetch(
    `${garoonUrl}/api/v1/schedule/events/${scheduleId}`,
    {
      method: 'GET',
      headers,
    }
  );
  const data = await resp.json();
  const {additionalItems} = data;
  if (!additionalItems) {
    throw new Error('additionalItems プロパティが見つかりませんでした');
  }
  return additionalItems.item.value;
}

/**
 * カスタム項目(Schedule datastore)に値を登録する
 * @param scheduleId 予定ID
 * @param additionalItemsValue additionalItems の値
 * @returns API の実行結果
 */
async function postScheduleDataStore({scheduleId, additionalItemsValue}) {
  const body = {
    value: JSON.parse(additionalItemsValue),
  };
  const resp = await fetch(
    `${garoonUrl}/api/v1/schedule/events/${scheduleId}/datastore/${customName}`,
    {
      method: 'POST',
      headers: {
        ...headers,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(body),
    }
  );
  if (!resp.ok) {
    const err = await resp.text();
    throw new Error(err);
  }
  const data = await resp.json();
  return data;
}

(async () => {

  // 予定のID
  const scheduleId = 1;

  try {
    console.log(`予定ID:${scheduleId}`);
    // additionalItems の値を取得する
    const additionalItemsValue = await getAdditionalItemsValue({scheduleId});
    // additionalItems の値が存在しないときは、何もしない
    if (!additionalItemsValue) {
      console.log('additionalItems を利用していないため、値の移行をスキップしました');
      return;
    }

    // Schedule datastore に additionalItems の値を登録する
    await postScheduleDataStore({
      scheduleId,
      additionalItemsValue,
    });
    console.log('additionalItems の値を Schedule datastore に移行しました');
  } catch (err) {
    console.error(err);
  }
})();

STEP4:動作確認

次のコマンドを実行します。

1
node sample.js

「additionalItems の値を Schedule datastore に移行しました」が表示されることを確認します。

使用した API

information

この Tips は、パッケージ版 Garoon 5.15 で動作を確認しています。