カスタム項目(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/id/ea99237141ef5eed3c5436a2/#name-rules を参照してください
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で動作を確認しています。