ユーザマニュアル

プリザンター10周年記念イベントアーカイブ公開中 プリザンター×MCPサーバ 「プリザンターをもっと活用するために」資料ダウンロード 「プリザンター入門」発売中!

2026/03/17

MANUAL

開発者向け機能:API:グループ操作:グループ更新

## 概要 APIを使用してグループを更新する事ができます。 ## 事前準備 APIの操作を行う前に[APIキーの作成](/manual/api-key)を実施してください。また、この機能はテナント管理者でないと行えないため、ユーザ管理からテナント管理者の設定を行ってください。 ## リクエスト 下記のリクエスト形式で、jsonデータを送信します。 |設定項目|値| |:--|:--| |HTTPメソッド|POST| |Content-Type |application/json| |文字コード|UTF-8| |URL|http://{サーバー名}/api/groups/{グループId}/update(※1)| |Body|以下のjsonデータを参考のこと| (※1){サーバー名}、{グループId}の部分は、適宜、環境に合わせて編集してください。   pleasanter.netの場合は以下の形式になります。   https\://pleasanter.net/fs/api/groups/{グループId}/update ##### JSON ``` { "ApiVersion": 1.1, "ApiKey": "026dfsS19fds1y7ayR1R5b67..", "GroupName": "[更新後のグループの名前]", "Body": "APIによるグループ更新サンプルです。", "GroupMembers": [ "User,1,True", "Dept,1,False" ], "GroupChildren": [ "Group,1," ] } ``` #### GroupMembersについて 1. カンマ区切りにてグループメンバーとするユーザ、組織の情報を配列で指定します。 1. グループメンバーの更新は洗い替えで行われます。新規追加するグループメンバーと、所属を変更しないグループメンバーの情報をすべて配列に記述してください。 |カラム|設定例|設定内容| |:--|:--|:--| |1カラム目|User|ユーザを登録する場合は'User'、組織を登録する場合は'Dept'を指定します。| |2カラム目|1|ユーザ・組織のIDを指定します。| |3カラム目|True|管理者権限を付与する場合Trueを設定、付与しない場合はFalseを設定します。| #### GroupChildrenについて 1. カンマ区切りにて子グループに追加するグループの情報を配列で指定します。 1. 子グループの更新は洗い替えで行われます。新規追加するグループと、変更しないグループの情報をすべて配列に記述してください。 |カラム|設定内容| |:--|:--| |1カラム目|'Group'固定。| |2カラム目|グループのIDを指定します。| |3カラム目|ブランク固定。| ## レスポンス 下記の形式のjsonデータが返却されます。 ##### JSON ``` { "Id": 12345, "StatusCode": 200, "Message": "\" 新しいグループの名前 \" を更新しました。" } ``` ## サンプルコード ##### コード内の【 ... 】 は適宜修正してください。 <details> <summary>1. 外部連携されたCSVを読み込みグループおよび親子関係を作成/更新する</summary> 本サンプルは、外部システムから出力されたCSVをもとに Pleasanterのグループ作成API / グループ更新APIを利用して グループおよび親子関係を登録するサンプルです。 #### 概要 外部システムの組織情報をCSVで受け取り、 Pleasanterのグループ作成・更新APIを利用してグループ構造を作成します。 本サンプルでは **2フェーズ処理** で実現しています。 | フェーズ | 処理内容 | | ------ | ------------------- | | Phase1 | グループ本体とメンバーを作成 / 更新 | | Phase2 | グループ親子関係を更新 | 処理の流れは次の通りです。 1. 入力CSVを読み込む 2. Pleasanterから既存グループを取得する(/api/groups/get) 3. Pleasanterから既存ユーザを取得する(/api/users/get) 4. Phase1-グループ名をもとに create / update を判定し、グループ本体とメンバーを登録する(/api/groups/create または /api/groups/{GroupId}/update) 5. Pleasanterから既存グループを再取得する(/api/groups/get) 6. Phase2-親子関係を含めてグループを再更新する(/api/groups/{GroupId}/update) #### 前提 ユーザは事前にPleasanterへ登録済み グループ名は一意である(作成/更新の判定に使用) #### 入力ファイル 入力ファイルは4つです。 ``` input/ ├ groups.csv ├ users.csv ├ user_group_memberships.csv └ group_relations.csv ``` ##### groups.csv グループ情報を定義します。 | 列名 | 説明 | | ---------- | ----------- | | group_code | グループ識別コード | | group_name | グループ名 | | is_active | 1:有効 / 0:無効 | | remark | 説明 | サンプル ``` group_code,group_name,is_active,remark GRP_ADMIN,管理本部,1,管理部門 GRP_SALES,営業本部,1,営業部門 GRP_EAST,東日本営業部,1,営業東日本 ``` ##### users.csv ユーザ情報を定義します。 | 列名 | 説明 | | --------- | ---------------- | | user_id | ユーザ識別ID | | login_id | PleasanterログインID | | user_name | ユーザ名 | | mail | メール | | is_active | 1:有効 / 0:無効 | サンプル ``` user_id,login_id,user_name,mail,is_active 0001,yamada.taro,山田 太郎,yamada@example.co.jp,1 0002,sato.hanako,佐藤 花子,sato@example.co.jp,1 ``` ##### user_group_memberships.csv グループのメンバー情報を定義します。 | 列名 | 説明 | | -------------- | --------- | | user_id | ユーザID | | group_code | グループコード | | is_active | 1:有効 / 0:無効 | | is_group_admin | 1:グループ管理者 / 0:通常ユーザ  | サンプル ``` user_id,group_code,is_active,is_group_admin 0001,GRP_ADMIN,1,1 0002,GRP_SALES,1,0 ``` ##### group_relations.csv グループの親子関係を定義します。 | 列名 | 説明 | | ----------------- | ----- | | parent_group_code | 親グループ | | child_group_code | 子グループ | | is_active | 1:対象 / 0:対象外 | サンプル ``` parent_group_code,child_group_code,is_active GRP_SALES,GRP_EAST,1 ``` ##### Python(api_group_upsert.py) ``` import csv import json from pathlib import Path import requests # ============================== # Pleasanter 接続設定 # ============================== BASE_URL = "【URL】" API_KEY = "【APIキー】" API_VERSION = 1.1 # ============================== # ファイル設定(環境にあわせ適宜変更してください) # ============================== INPUT_DIR = Path("./input") GROUPS_CSV = INPUT_DIR / "groups.csv" USERS_CSV = INPUT_DIR / "users.csv" MEMBERSHIPS_CSV = INPUT_DIR / "user_group_memberships.csv" RELATIONS_CSV = INPUT_DIR / "group_relations.csv" # ============================== # CSV入力設定(環境にあわせ適宜変更してください) # ============================== def read_csv(path): with open(path, "r", encoding="utf-8-sig", newline="") as f: return [ {k.strip(): (v or "").strip() for k, v in row.items()} for row in csv.DictReader(f) ] def is_active(row): return str(row.get("is_active", "1")).strip() == "1" def to_bool_text(value): return "True" if str(value).strip() == "1" else "False" # ============================== # Pleasanter API操作 # ============================== def post_json(url, payload): r = requests.post( url, json=payload, headers={"Content-Type": "application/json"}, timeout=60, ) r.raise_for_status() return r.json() # ============================== # グループ取得 # ============================== def get_groups(): data = post_json( f"{BASE_URL}/api/groups/get", {"ApiVersion": API_VERSION, "ApiKey": API_KEY}, ) return { row["GroupName"]: row for row in data.get("Response", {}).get("Data", []) if row.get("GroupName") } # ============================== # ユーザー取得 # ============================== def get_users(): data = post_json( f"{BASE_URL}/api/users/get", {"ApiVersion": API_VERSION, "ApiKey": API_KEY}, ) return { row["LoginId"]: row for row in data.get("Response", {}).get("Data", []) if row.get("LoginId") } # ============================== # グループの作成/更新 # ============================== def upsert_group(group_name, payload, existing_groups): current = existing_groups.get(group_name) if current: url = f"{BASE_URL}/api/groups/{current['GroupId']}/update" result = post_json(url, payload) print(f"[UPDATE] {group_name}") else: url = f"{BASE_URL}/api/groups/create" result = post_json(url, payload) print(f"[CREATE] {group_name}") return result # ============================== # グループメンバーの設定 # ============================== def build_member_map(memberships): result = {} for row in memberships: if not is_active(row): continue group_code = row["group_code"] result.setdefault(group_code, []).append(row) return result # ============================== # 親子関係の構築 # ============================== def build_relation_map(relations): result = {} for row in relations: if not is_active(row): continue parent_code = row["parent_group_code"] result.setdefault(parent_code, []).append(row["child_group_code"]) return result # ============================== # Phase1のリクエストペイロードの構築 # ============================== def build_payload_phase1(group_row, member_rows, users_by_id, pleasanter_users): members = [] for row in member_rows: user = users_by_id[row["user_id"]] login_id = user["login_id"] pleasanter_user = pleasanter_users[login_id] user_id = pleasanter_user["UserId"] is_admin = to_bool_text(row.get("is_group_admin", "0")) members.append(f"User,{user_id},{is_admin}") return { "ApiVersion": API_VERSION, "ApiKey": API_KEY, "GroupName": group_row["group_name"], "Body": group_row.get("remark", ""), "GroupMembers": members, "GroupChildren": [], } # ============================== # Phase2のリクエストペイロードの構築 # ============================== def build_payload_phase2( group_row, member_rows, child_codes, users_by_id, groups_by_code, pleasanter_users, existing_groups, ): members = [] for row in member_rows: user = users_by_id[row["user_id"]] login_id = user["login_id"] pleasanter_user = pleasanter_users[login_id] user_id = pleasanter_user["UserId"] is_admin = to_bool_text(row.get("is_group_admin", "0")) members.append(f"User,{user_id},{is_admin}") children = [] for child_code in child_codes: child_name = groups_by_code[child_code]["group_name"] child_group = existing_groups[child_name] children.append(f"Group,{child_group['GroupId']},") return { "ApiVersion": API_VERSION, "ApiKey": API_KEY, "GroupName": group_row["group_name"], "Body": group_row.get("remark", ""), "GroupMembers": members, "GroupChildren": children, } # ============================== # メイン処理 # ============================== def main(): groups = read_csv(GROUPS_CSV) users = read_csv(USERS_CSV) memberships = read_csv(MEMBERSHIPS_CSV) relations = read_csv(RELATIONS_CSV) groups_by_code = {row["group_code"]: row for row in groups} users_by_id = {row["user_id"]: row for row in users} members_by_group = build_member_map(memberships) children_by_parent = build_relation_map(relations) pleasanter_users = get_users() existing_groups = get_groups() # Phase 1: 全グループを作成/更新(子グループなし) print("=== Phase 1 ===") for group in groups: payload = build_payload_phase1( group, members_by_group.get(group["group_code"], []), users_by_id, pleasanter_users, ) upsert_group(group["group_name"], payload, existing_groups) existing_groups = get_groups() # Phase 2: 親子関係を更新 print("=== Phase 2 ===") existing_groups = get_groups() for group in groups: payload = build_payload_phase2( group, members_by_group.get(group["group_code"], []), children_by_parent.get(group["group_code"], []), users_by_id, groups_by_code, pleasanter_users, existing_groups, ) upsert_group(group["group_name"], payload, existing_groups) if __name__ == "__main__": main() ``` ##### 実行 ``` >python api_group_upsert.py ``` ##### 実行結果 ``` === Phase 1 === [CREATE] 管理本部 [CREATE] 営業本部 [CREATE] 東日本営業部 === Phase 2 === [UPDATE] 管理本部 [UPDATE] 営業本部 [UPDATE] 東日本営業部 ``` </details> ## 対応バージョン |対応バージョン|内容| |:--|:--| |1.2.24.0以降|機能追加| |1.3.4.0 以降|GroupMembersを追加| ## エラー時の確認事項 [・API使用時の注意点やエラーが発生する場合の確認事項](/manual/faq-api) [・FAQ:変更後の設定ファイルやAPIリクエスト(JSON形式)が正しく認識されない場合の確認事項](/manual/faq-json-format) ## 仕様変更について **※ 2019年10月よりAPIの仕様が一部変更となりました。** - 分類, 数値, 日付, 説明, チェック項目はjsonにそのまま記載する方法から「~Hash」の中に記載する方法へ変更されました。 **※ 2018年11月よりAPIの仕様が一部変更となりました。** - URLの形式が '/pleasanter/api_items/xxxx' から '/pleasanter/api/items/xxxx' に変更されました。 - Content-Type の指定が'application/x-www-form-urlencoded' から 'application/json'に変更されました。
TOP