Directory API

Directory API로 구성원, 조직, 그룹 등 Admin에서 구성원 메뉴에 있는 구성원과 조직의 리소스를 조회하고 수정할 수 있다. Directory API로 접근할 수 있는 리소스는 다음과 같다.

  • 구성원(users)
  • 그룹(groups)
  • 조직(orgunits)
  • 직급(levels)
  • 직책(positions)
  • 사용자 유형(user-types)
  • 사용자 지정 필드(custom-fields)
  • 구성원 커스텀 속성(user-custom-properties)
  • 상태(profile-statuses)

Directory API를 호출하려면 구성원 계정 또는 서비스 계정으로 인증하여 얻은 Access Token이 필요하다.

API scope는 다음과 같다.

  • directory: 모든 리소스에 접근 가능
  • user: 구성원 리소스만 접근 가능
  • group: 그룹 리소스만 접근 가능
  • orgunit: 조직 리소스만 접근 가능

리소스 지정 정보 {#designate-resource}

API로 구성원, 그룹, 조직, 직급, 직책, 사용자 유형, 사용자 지정 필드 리소스에 접근할 때, 리소스 ID나 외부 키, 로그인 ID를 이용해 리소스를 지정하고 식별할 수 있다.

리소스 ID {#resource-id}

리소스 ID는 각 리소스를 추가할 때 시스템에서 지정되는 고유 ID이다. 리소스 ID에는 다음과 같은 특징이 있으므로 API로 리소스를 지정하고 식별하는 데 리소스 ID를 사용하는 것이 좋다.

  • 각 리소스에는 항상 리소스 ID가 부여된다.
  • 리소스 ID는 리소스의 영구값이다.
  • 리소스 ID는 고유하다.
  • API로 리소스 조회 시 리소스 ID가 항상 포함된다.

외부 키 {#external-key}

외부 키(external key)는 NAVER WORKS의 각 리소스에 API 사용자 또는 관리자가 할당할 수 있는 임의의 값이다.

고객사의 사내 시스템 ID를 NAVER WORKS 리소스의 외부 키로 등록하면 NAVER WORKS에서 동일하게 사용할 수 있다

외부 키는 API를 사용해 등록하거나 Developer Console의 조직 연동에서 등록한다. API를 사용한 외부 키의 일괄 등록은 외부 키 수정 및 목록 조회를 참고한다.

외부 키를 사용해 리소스를 지정하는 경우 다음 형식으로 표시된다.

externalKey:ExternalKey 값

외부 키 제한 {#external-key-limitation}

리소스 유형에 따라 외부 키에 사용할 수 있는 문자와 값은 테넌트 혹은 도메인 내에서 유일해야 한다.

각 제한은 아래 표와 같다.

리소스속성문자 제한제한 범위
구성원(users)userExternalKey% \ # / ?는 사용할 수 없다.테넌트
조직(orgunits)orgUnitExternalKey% \ # / ?는 사용할 수 없다.테넌트
그룹(groups)groupExternalKey% \ # / ?는 사용할 수 없다.테넌트
사용자 유형(user-types)userTypeExternalKey% # / ? 는 사용할 수 없다.테넌트
직책(position)positionExternalKey% # / ?는 사용할 수 없다.도메인
직급(levels)levelExternalKey% # / ?는 사용할 수 없다.도메인
사용자 지정 필드(custom-fields)customFieldExternalKey영문과 숫자만 사용할 수 있다(단, 첫 번째 문자는 영문만 입력 가능). 대소문자를 구분하지 않는다.도메인

로그인 ID {#login-id}

구성원의 외부 키는 로그인 시 ID로 지정할 수 있다.


구성원(users) {#user}

NAVER WORKS의 구성원에 해당하는 리소스이다.

주의
API로 조회하거나 설정할 수 있는 속성은 NAVER WORKS Admin에 설정된 구성원 속성에 따라 달라진다.

참고
구성원은 awaiting(활성화 전), pending(대기 중), using(사용 중), suspended(일시정지), deleted(삭제) 6가지의 단계를 가진다. 각 단계는 구성원 목록 및 상세 정보 조회 API를 통해 확인할 수 있으며 상세 내용은 아래와 같다.

상태ParameterDescription
awaitingisAwaitingactivationDate 이전의 계정 상태.
이후 SSO 연동 여부에 따라 pending 또는 using 상태로 변경된다.
pendingisPending미접속 상태.
관리자가 구성원을 추가한 후 첫로그인을 하지 않은 상태를 의미한다.
usingn/a사용 중 상태.
suspendedisSuspended이일시정지 상태.
로그인은 불가하나 구성원의 데이터는 삭제되지 않고 유지된다.
deletedisDeleted삭제 상태.
삭제 시점으로부터 7일 간 이 상태로 유지되다가 7일이 지난 시점 데이터가 삭제된다.

구성원 추가 및 수정 {#add-update-user}

구성원을 추가하고 수정한다. 비밀번호는 구성원을 추가할 때만 설정할 수 있다.

HTTP RequestDescription
POST /users구성원 추가
PUT /users/{userId}구성원 수정
PATCH /users/{userId}구성원 부분 수정

구성원 목록 조회 {#get-user-list}

도메인의 구성원 목록을 조회한다. 목록을 정렬하고 필터링할 수 있다.

HTTP RequestDescription
GET /users구성원 목록 조회

구성원 조회 {#get-user-information}

구성원 조회는 사용 방법에 따라 제한된 필드만 포함하는 응답을 얻을 수 있다.

다음의 세 가지 방법으로 구성원을 조회할 수 있다. 요청 구문은 동일하지만 Access Token 발급 시 지정한 scope에 따라 응답으로 반환되는 정보가 다르다.

HTTP RequestDescription
GET /users/{userId}구성원 조회.
Scope: user.read / user
구성원의 모든 정보가 반환된다.
GET /users/{userId}구성원 프로필 조회.
Scope: user.profile.read
구성원의 프로필 정보만 반환된다.
개인 이메일 주소(privateEmail)나 생년월일(birthday)등의 개인 정보는 포함되지 않는다.
GET /users/{userId}구성원 메일 주소 조회.
Scope: user.email.read
구성원 ID(userId)와 로그인 ID(email)만 반환된다.

구성원 삭제 {#delete-user}

구성원 삭제는 일반 삭제와 즉시 삭제가 있다. 일반 삭제한 구성원은 삭제 후 7일 이내에 삭제를 취소할 수 있다. 삭제 후 7일이 지나거나 즉시 삭제한 구성원은 복구할 수 없다.

HTTP RequestDescription
DELETE /users/{userId}구성원 삭제
DELETE /users/{userId}/forcedelete구성원 즉시 삭제
POST /users/{userId}/undelete구성원 삭제 취소

구성원 사진 관리 {#manage-user-photo}

구성원 사진은 다음 API로 관리한다.

HTTP RequestDescription
POST /users/{userId}/photo구성원 사진 업로드
GET /users/{userId}/photo구성원 사진 조회
DELETE /users/{userId}/photo구성원 사진 삭제

파일 업로드/다운로드 방법에 대한 자세한 내용은 파일 업로드/다운로드를 참고한다.

구성원 상태 관리 {#manage-user-status}

구성원의 상태는 다음 API로 관리한다. 도메인의 상태 관리는 상태(profile-statuses)를 참고한다.

HTTP RequestDescription
POST /users/{userId}/user-profile-statuses구성원 상태 추가
GET /users/{userId}/user-profile-statuses구성원 상태 목록 조회
GET /users/{userId}/user-profile-statuses/{userProfileStatusId}구성원 상태 조회
PUT /users/{userId}/user-profile-statuses/{userProfileStatusId}구성원 상태 수정
PATCH /users/{userId}/user-profile-statuses/{userProfileStatusId}구성원 상태 부분 수정
DELETE /users/{userId}/user-profile-statuses/{userProfileStatusId}구성원 상태 삭제

구성원은 '현재 상태'와 '예약 상태'를 등록할 수 있다.

{     "userProfileStatuses": [         {             "profileStatusId": "AWAY",             "statusMessage": "외출 중입니다.",             "startTime": "2023-05-11T09:00:00+09:00",             "endTime": "2023-05-11T12:00:00+09:00",             ...         }     ]}

외부 연동 권한 관리 {#manage-link-to-externaluser}

외부 NAVER WORKS 사용자 또는 LINE 사용자와의 대화 권한을 관리할 수 있다.

다음 API로 외부 NAVER WORKS 사용자와의 대화 권한을 관리한다.

HTTP RequestDescription
POST /users/link-to-works도메인의 외부 NAVER WORKS 연동 권한 부여
POST /users/{userId}/link-to-works구성원의 외부 NAVER WORKS 연동 권한 부여
POST /users/{userId}/unlink-to-works구성원의 외부 NAVER WORKS 연동 권한 삭제

다음 API로 외부 LINE 사용자와의 대화 권한을 관리한다.

HTTP RequestDescription
POST /users/link-to-line도메인의 외부 LINE 연동 권한 부여
POST /users/{userId}/link-to-line구성원의 외부 LINE 연동 권한 부여
POST /users/{userId}/unlink-to-line구성원의 외부 LINE 연동 권한 삭제

다음 API로 구성원의 외부 대화 상대 추가 URL을 관리한다.

HTTP RequestDescription
GET /users/{userId}/link-url구성원 외부 대화 상대 추가 URL 조회
POST /users/{userId}/link-url/reset구성원 외부 대화 상대 추가 URL 초기화

주의

user scope가 필요하다. directory scope로는 외부 연동 권한을 관리할 수 없다.

사용자 일시 정지 및 휴직 {#user-suspend-leaveofabsence}

구성원이 휴직할 경우 '휴직' 또는 '일시 정지'로 설정할 수 있다. 휴직으로 설정된 구성원은 프로필과 조직도에 휴직 정보가 표시된다. 또, API로 조회한 구성원 정보에 leaveOfAbsence로 표시된다. 일시 정지된 구성원은 NAVER WORKS에 로그인할 수 없으며, API로 조회한 구성원 정보에 isSuspended로 표시된다.

HTTP RequestDescription
POST /users/{userId}/suspend구성원 일시 정지
POST /users/{userId}/unsuspend구성원 일시 정지 취소
POST /users/{userId}/set-leave-of-absence구성원 휴직 설정
POST /users/{userId}/clear-leave-of-absence구성원 휴직 해제

구성원 관리 {#manage-user}

다음 API로 구성원을 초대하거나 강제로 로그아웃시킬 수 있다.

HTTP RequestDescription
POST /users/{userId}/send-invitation-email구성원 초대 메일 재발송
POST /users/send-invitation-email구성원 초대 이메일 일괄 재발송
POST /users/{userId}/force-logout구성원 강제 로그아웃

그룹(groups) {#group}

프로젝트나 사내 모임 활동과 같은 커뮤니케이션을 위한 그룹(groups)을 만들 수 있다. 그룹은 다음 API로 관리한다.

HTTP RequestDescription
POST /groups그룹 추가
GET /groups그룹 목록 조회
GET /groups/{groupId}그룹 조회
PUT /groups/{groupId}그룹 수정
PATCH /groups/{groupId}그룹의 부분 수정
DELETE /groups/{groupId}그룹 삭제
GET /groups/{groupId}/administrators그룹 관리자 목록 조회
POST /groups/{groupId}/administrators그룹 관리자 추가
DELETE /groups/{groupId}/administrators/{userId}그룹 관리자 삭제
GET /groups/{groupId}/members그룹 구성원 목록 조회
POST /groups/{groupId}/members그룹 구성원 추가
DELETE /groups/{groupId}/members/{id}그룹 구성원 삭제

그룹에서는 메시지, 노트, 캘린더, 할 일, 폴더 등의 기능을 활용할 수 있다. 그룹은 도메인 단위로 관리한다. 그룹을 관리할 그룹 마스터를 한 명 이상 지정해야 하며, 구성원, 조직 또는 다른 그룹을 그룹에 추가할 수 있다.

{     "groupName": "검증",     "administrators": [         {             "userId": "user-40d6-450f-1c78-1234567890ab",             "userExternalKey": null         },         {             "userId": "user-08ee-41fb-1a61-1234567890ab",             "userExternalKey": null         }     ],     "members": [         {             "id": "user-40d6-450f-1c78-1234567890ab",             "type": "USER",             "externalKey": null         },         {             "id": "orgunit-5c41-4baf-239e-1234567890ab",             "type": "ORGUNIT",             "externalKey": null         },         {             "id": "group-6bb3-40ea-37a7-1234567890ab",             "type": "GROUP",             "externalKey": null         }     ],...}

동적 그룹 {#dynamic-group}

동적 그룹을 사용하면 조건(쿼리)을 작성하여 그룹 구성원을 특정한 규칙에 따라 자동으로 관리할 수 있다. 해당 조건과 일치하는 구성원이 자동으로 그룹 구성원에 추가되거나 삭제된다.

동적 그룹의 쿼리 작성법은 다음과 같다.

사용할 수 있는 속성 {#dynamic-group-query-property}

쿼리 작성 시 사용할 수 있는 속성은 다음과 같다.

User AttributeDescriptionExample
user.userTypeId구성원 사용자 유형 ID 규칙 지정user.userTypeId == 'usertypei-70c3-46a8-22dd-03ef7c571975'
user.levelId구성원 직급 ID 규칙 지정user.levelId == 'levelid8e-70c3-46a8-22dd-03ef7c571975'
user.location구성원 근무처 규칙 지정user.location == 'Office'
user.task구성원 담당 업무 규칙 지정user.task == 'Planing'
user.organizations.exists(organization, organization.domainId={domainId})구성원의 소속 회사 규칙 지정user.organizations.exists(organization, organization.domainId == 123)
user.organizations.exists(organization, organization.domainId={domainId} && organization.primary=true)구성원의 소속 회사 및 원직 여부 규칙 지정user.organizations.exists(organization, organization.domainId == 123 && organization.primary==true)
user.organizations.orgUnits.exists(orgUnit, orgUnit.orgUnitId == '{orgUnitId}')구성원의 직속 조직 규칙 지정user.organizations.orgUnits.exists(orgUnit, orgUnit.orgUnitId == 'orgunit8e-70c3-46a8-22dd-03ef7c571975')
user.organizations.orgUnits.exists(orgUnit, orgUnit.isManager == true)구성원의 직속 조직에서의 조직장 규칙 지정user.organizations.orgUnits.exists(orgUnit, orgUnit.orgUnitId == 'orgunit8e-70c3-46a8-22dd-03ef7c571975' && orgUnit.isManager == true)
user.organizations.orgUnits.exists(orgUnit, orgUnit.positionId == '{positionId}')구성원의 직책 규칙 지정user.organizations.orgUnits.exists(orgUnit, orgUnit.positionId == 'positione-70c3-46a8-22dd-03ef7c571975')
user.organizations.orgUnits.exists(orgUnit, orgUnit.orgUnitId == '{orgUnitId}' && orgUnit.positionId == '{positionId}')구성원의 직속 조직 및 해당 조직에서의 직책 규칙 지정user.organizations.orgUnits.exists(orgUnit, orgUnit.orgUnitId == 'orgunit8e-70c3-46a8-22dd-03ef7c571975' && orgUnit.positionId == 'positione-70c3-46a8-22dd-03ef7c571975')

함수 {#dynamic-group-query-function}

Function NameDescriptionExample
isMemberOfOrgUnit조직 ID를 입력받는다.
조직 ID에 해당하는 조직과 그 조직의 모든 하위 조직 구성원을 그룹 구성원으로 추가한다.
user.isMemberOfOrgUnit('orgunit8e-70c3-46a8-22dd-03ef7c571975')
isMemberOfGroup그룹 ID를 입력받는다.
그룹 ID에 해당하는 그룹의 구성원을 그룹 구성원으로 추가한다.
user.isMemberOfGroup('groupit8e-70c3-46a8-22dd-03ef7c571975')

Negative Support

조건문을 괄호(( ))로 감싸고, 앞에 느낌표(!)를 추가한다.

User AttributeNegative SupportExample
user.userTypeIdY!(user.userTypeId == 'usertypei-70c3-46a8-22dd-03ef7c571975')
user.levelIdY!(user.levelId == 'levelid8e-70c3-46a8-22dd-03ef7c571975')
user.locationY!(user.location == 'Office')
user.taskY!(user.task == 'Planing')
user.organizations.exists(organization, organization.domainId={domainId})NN/A
user.organizations.exists(organization, organization.domainId={domainId} && organization.primary=true)NN/A
user.organizations.orgUnits.exists(orgUnit, orgUnit.orgUnitId == '{orgUnitId}')Y!(user.organizations.orgUnits.exists(orgUnit, orgUnit.orgUnitId == 'orgunit8e-70c3-46a8-22dd-03ef7c571975'))
user.organizations.orgUnits.exists(orgUnit, orgUnit.isManager == true)Y!(user.organizations.orgUnits.exists(orgUnit, orgUnit.orgUnitId == 'orgunit8e-70c3-46a8-22dd-03ef7c571975' && orgUnit.isManager == true)
user.organizations.orgUnits.exists(orgUnit, orgUnit.positionId == '{positionId}')Y!(user.organizations.orgUnits.exists(orgUnit, orgUnit.positionId == 'positione-70c3-46a8-22dd-03ef7c571975'))
user.organizations.orgUnits.exists(orgUnit, orgUnit.orgUnitId == '{orgUnitId}' && orgUnit.positionId == '{positionId}')Y!(user.organizations.orgUnits.exists(orgUnit, orgUnit.orgUnitId == 'orgunit8e-70c3-46a8-22dd-03ef7c571975' && orgUnit.positionId == 'positione-70c3-46a8-22dd-03ef7c571975'))
Function NameNegative SupportExample
isMemberOfOrgUnitY!(user.isMemberOfOrgUnit('orgunit8e-70c3-46a8-22dd-03ef7c571975'))
isMemberOfGroupY!(user.isMemberOfGroup('groupit8e-70c3-46a8-22dd-03ef7c571975'))

조건 {#dynamic-group-query-condition}

조건은 쿼리의 최소 단위이다. 다음과 같은 형태로 입력한다.

{속성} {속성과 값 사이의 연산자} {값} 

예시) user.userTypeId == 'usertypei-70c3-46a8-22dd-03ef7c571975'

연산자 {#dynamic-group-query-operator}

다음은 조건과 조건 사이에 사용할 수 있는 논리 연산자이다.

  • &&: AND 연산자. 두 가지 조건을 모두 만족하는 구성원만 조회한다.
  • ||: OR 연산자. 두 가지 조건 중 하나라도 만족하는 구성원을 조회한다.

다음은 속성과 값 사이에 사용할 수 있는 연산자이다.

  • ==: 동등 연산자. 속성이 값과 정확히 일치하는 구성원만 조회한다.

조건의 우선순위 {#dynamic-group-query-priority}

연산 시 조건의 우선순위는 다음과 같다.

  1. 괄호로 묶인 조건
  2. &&로 연결된 조건
  3. ||로 연결된 조건
  4. 1, 2, 3 우선순위가 동일하면, 왼쪽 조건부터 처리한다.

예시)

  • A || B && C: B && C 조건부터 처리함.
  • (A || B) && C: 괄호로 묶인 A || B 조건부터 처리함.
  • A || B || C: 우선순위가 동일하므로 왼쪽 조건인 A || B부터 처리함.

제한 사항 {#dynamic-group-query-restriction}

다음과 같은 제한 사항이 적용된다.

  • 쿼리에 사용할 수 있는 속성은 최대 10개이다.
  • 부정문은 하나의 조건에만 적용할 수 있다.
  • 함수 내부에는 부정문을 포함할 수 없다.
  • 처리 순서에 따른 괄호를 입력할 때 괄호의 깊이는 2 이하여야 한다.

조직(orgunits) {#orgunit}

회사의 조직 정보에 따라 NAVER WORKS에 조직(orgunits)을 등록할 수 있다. 프로젝트나 사내 모임 등은 조직이 아닌 그룹을 이용한다. 조직은 다음 API로 관리한다.

HTTP RequestDescription
POST /orgunits조직 추가
GET /orgunits조직 목록 조회
GET /orgunits/{orgUnitId}조직 조회
PUT /orgunits/{orgUnitId}조직 수정
PATCH /orgunits/{orgUnitId}조직의 부분 수정
DELETE /orgunits/{orgUnitId}조직 삭제
POST /orgunits/{orgUnitId}/move조직 이동
GET /orgunits/{orgUnitId}/members조직 구성원 목록 조회

조직은 메시지, 노트, 캘린더, 할 일, 폴더 등의 기능을 활용할 수 있다. 조직은 도메인 단위로 관리한다. 구성원이 속한 조직은 조직 목록(orgUnits)에서 확인하고 구성할 수 있다.

{     "email": "user@example.com",     "organizations": [         {          ...             "orgUnits": [                 {                     "orgUnitId": "orgunit-0faa-4f37-22bb-1234567890ab",                     "orgUnitName": "영업부",                     ...                }             ]         }     ],     ...

조직도 조회 제한 {#orgunit-access-restrict}

조직도에서 조회 제한 설정을 할 수 있다.

구성원 조회 제한은 다음 API로 설정한다.

HTTP RequestDescription
POST /orgunits/{orgUnitId}/orgunit-access-restrict구성원 조회 제한 설정
GET /orgunits/{orgUnitId}/orgunit-access-restrict구성원 조회 제한 조회
PUT /orgunits/{orgUnitId}/orgunit-access-restrict구성원 조회 제한 수정
DELETE /orgunits/{orgUnitId}/orgunit-access-restrict구성원 조회 제한 삭제

사용자 유형 조회 제한은 다음 API로 설정한다.

HTTP RequestDescription
POST /directory/user-types/{userTypeId}/orgunit-access-restrict사용자 유형 조회 제한 설정
GET /directory/user-types/{userTypeId}/orgunit-access-restrict사용자 유형 조회 제한 조회
PUT /directory/user-types/{userTypeId}/orgunit-access-restrict사용자 유형 조회 제한 수정
DELETE /directory/user-types/{userTypeId}/orgunit-access-restrict사용자 유형 조회 제한 삭제

조직 조회 제한은 다음 API로 설정한다.

HTTP RequestDescription
POST /orgunits/{orgUnitId}/orgunit-access-restrict조직 조회 제한 설정
GET /orgunits/{orgUnitId}/orgunit-access-restrict조직 조회 제한 조회
PUT /orgunits/{orgUnitId}/orgunit-access-restrict조직 조회 제한 수정
DELETE /orgunits/{orgUnitId}/orgunit-access-restrict조직 조회 제한 삭제

조회 제한은 '구성원', '사용자 유형', '조직' 순으로 적용된다.
예를 들어, 특정 구성원의 조회 제한이 구성원과 사용자 유형, 조직에 설정되어 있으면 우선순위에 따라 구성원에 설정된 조회 제한이 적용되며, 조회 제한 타입에 따라 자신만 조회하거나, 소속된 조직, 또는 소속된 조직과 선택한 조직만 조회할 수 있다.


직급(levels) {#level}

직급(levels)은 구성원에게 부여되는 대리, 과장과 같은 직무 등급이다. 직급은 다음 API로 관리한다.

HTTP RequestDescription
POST /directory/levels/enable직급 사용 ON
POST /directory/levels/disable직급 사용 OFF
POST /directory/levels직급 추가
GET /directory/levels직급 목록 조회
GET /directory/levels/{levelId}직급 조회
PUT /directory/levels/{levelId}직급 수정
PATCH /directory/levels/{levelId}직급 부분 수정
DELETE /directory/levels/{levelId}직급 삭제

직급은 도메인 단위로 관리한다. 구성원의 직급은 자동으로 부여되는 ID(levelId)로 지정하고 조회할 수 있다.

{    "email": "user@example.com",    "organizations": [       {          "domainId": 12345678,          "organizationName": "샘플 상점",          "levelId": "level-1999-4212-7979-1234567890ab",          "levelName": "임원"...

직책(positions) {#position}

직책(positions)은 사용자에게 부여된 직무상 책임의 단위이다. 직책은 다음 API로 관리한다.

HTTP RequestDescription
POST /directory/positions/enable직책 사용 ON
POST /directory/positions/disable직책 사용 OFF
POST /directory/positions직책 추가
GET /directory/positions직책 목록 조회
GET /directory/positions/{positionId}직위 조회
PUT /directory/positions/{positionId}직위 수정
PATCH /directory/positions/{positionId}직책 부분 수정
DELETE /directory/positions/{positionId}직책 삭제

직책은 도메인 단위로 관리한다. 구성원은 여러 개의 조직(orgUnits)에 소속될 수 있으므로 조직마다 다른 직책(positions)을 할당할 수 있다.

{     "email": "user@example.com",     "organizations": [         {             ...             "orgUnits": [                 {                     "orgUnitId": "orgunit-0faa-4f37-22bb-1234567890ab",                     "orgUnitName": "영업부",                     "primary": false,                     "positionId": null,                 ...                },                {                     "orgUnitId": "orgunitc-1d15-4cdf-246b-1234567890ab",                     "orgUnitName": "영업 일과",                     "primary": true,                     "positionId": "position-821e-41af-8142-1234567890ab",                     "positionName": "과장",                     ...                }             ]         }     ],     ...}

사용자 유형(user-types) {#user-type}

사용자 유형(user-types)은 서비스 이용, 조직도의 열람 제한, 드라이브와 게시판에서의 공유 제한 등의 차등 권한 부여 시 사용하는 관리 구성원의 속성이다. 사용자 유형은 다음 API로 관리한다.

HTTP RequestDescription
POST /directory/user-types/enable사용자 유형 사용 ON
POST /directory/user-types/disable사용자 유형 사용 OFF
POST /directory/user-types사용자 유형 추가
GET /directory/user-types사용자 유형 목록 조회
GET /directory/user-types/{userTypeId}사용자 유형 조회
PUT /directory/user-types/{userTypeId}사용자 유형 수정
PATCH /directory/user-types/{userTypeId}사용자 유형 부분 수정
DELETE /directory/user-types/{userTypeId}사용자 유형 삭제

사용자 유형은 도메인 단위로 관리한다. 구성원의 사용자 유형은 자동으로 부여되는 ID(userTypeId)로 지정하고 조회할 수 있다.

{    "email": "user@example.com",    "userTypeId": "employmenttype-75b9-48dd-917a-1234567890ab",    "userTypeName": "계약직"

사용자 지정 필드(custom-fields) {#custom-field}

사용자 지정 필드(custom-fields)는 구성원에게 추가로 할당할 수 있는 링크 등의 필드이다. 다음 API로 관리할 수 있다.

HTTP RequestDescription
POST /directory/custom-fields사용자 지정 필드 정의 추가
GET /directory/custom-fields사용자 지정 필드 정의 목록 조회
GET /directory/custom-fields/{customFieldId}사용자 지정 필드 정의 조회
PATCH /directory/custom-fields/{customFieldId}사용자 지정 필드 정의 수정
DELETE /directory/custom-fields/{customFieldId}사용자 지정 필드 정의 삭제

사용자 지정 필드는 도메인당 최대 5개까지 등록할 수 있다. 구성원은 도메인에 등록된 사용자 지정 필드를 사용하여 최대 100개의 값을 입력할 수 있다.

{     "email": "user@example.com",     "customFields": [         {             "customFieldId": "customfield-36fe-4b1a-af0e-1234567890ab",             "value": "일하는 문화를 바꿉니다",             "link": null,             "customFieldExternalKey": "CustomFldProject"         },         {             "customFieldId": "customfield-36fe-4b1a-af0e-1234567890ab",             "value": "건강이 최고",             "link": null,             "customFieldExternalKey": "CustomFldProject"         }     ],     ...}

주의

사용자 지정 필드는 구성원 커스텀 속성(user-custom-properties)으로 전환하는 것을 권장한다. 사용자 지정 필드를 사용하면 구성원 커스텀 속성(user-custom-properties)에서만 제공되는 일부 신규 기능을 조회하거나 수정할 수 없다.

  • 사용자 지정 필드는 구성원 커스텀 속성으로 자동으로 마이그레이션된다.
    • customFieldExternalKey → fieldName(customFieldExternalKey 값이 없으면 fieldName은 자동 생성)
    • customFieldId → customPropertyId
    • customFieldName → displayName
  • 사용자 지정 필드에 존재하지 않던 파라미터들은 구성원 커스텀 속성에서 기본값으로 생성된다.
    • multiValued: true
    • mandatory: false
    • readAccessType: ALL
    • writeAccessType: ADMIN

구성원 커스텀 속성(user-custom-properties) {#user-custom-properties}

구성원 커스텀 속성(user-custom-properties)은 기본 제공 속성 외에 구성원에게 추가로 정의할 수 있는 속성이다. 다음 API로 관리할 수 있다.

HTTP RequestDescription
POST /directory/users/custom-properties구성원 커스텀 속성 추가
GET /directory/users/custom-properties구성원 커스텀 속성 목록 조회
GET /directory/users/custom-properties/{customPropertyId}구성원 커스텀 속성 조회
PATCH /directory/users/custom-properties/{customPropertyId}구성원 커스텀 속성 수정
DELETE /directory/users/custom-properties/{customPropertyId}구성원 커스텀 속성 삭제

구성원 커스텀 속성은 도메인당 최대 50개까지 등록할 수 있다. 커스텀 속성이 multiValued이면 해당 속성에는 최대 10개의 값을 입력할 수 있다. 커스텀 속성의 종류로는 텍스트, 링크, 숫자, 날짜가 있으며, 텍스트의 경우 옵션 목록(options)도 설정할 수 있다. 속성별로 필수 여부, 읽기 및 수정 권한을 설정할 수 있다. 속성별로 단일값, 다중값 여부를 설정할 수 있다.

구성원의 커스텀 속성은 구성원(users) API의 customProperties 필드를 이용해 설정하거나 조회할 수 있다.

{  "email": "user@example.com",  "customProperties": {    "field_string": "string",    "field_string_multiValued": [      "string"    ],    "field_string_option": "optionName1",    "field_string_multiValued_option": [      "optionName1"    ],    "field_date": "YYYY-MM-DD",    "field_date_multiValued": [      "YYYY-MM-DD"    ],    "field_integer": 123,    "field_integer_multiValued": [      123    ],    "field_link": {      "text": "string",      "link": "string"    },    "field_link_multiValued": [      {        "text": "string",        "link": "string"      }    ]  },  ...}

주의

  • 구성원 커스텀 속성(user-custom-properties)으로 신규 속성을 생성한 경우:
    • 구성원(users)의 customFields에서는 multiValued=true이면서 propertyType이 STRING 또는 LINK인 경우에만 해당 속성을 설정할 수 있다. 단, propertyType이 STRING이어도 options의 값이 존재하면 해당 속성을 사용할 수 없다.
    • 구성원(users)의 customFields와 customProperties를 동시에 입력하면 customProperties의 값이 우선 적용된다.

상태(profile-statuses) {#profile-status}

상태를 설정하면 조직도, 프로필, 메시지방 멤버 목록에 상태에 따라 아이콘이 표시된다. 상태는 다음 API로 관리할 수 있다.

HTTP RequestDescription
POST /directory/profile-statuses/enable상태 사용 ON
POST /directory/profile-statuses/disable상태 사용 OFF
POST /directory/profile-statuses상태 추가
GET /directory/profile-statuses상태 목록 조회
GET /directory/profile-statuses/{profileStatusId}상태 조회
PUT /directory/profile-statuses/{profileStatusId}상태 수정
PATCH /directory/profile-statuses/{profileStatusId}상태 부분 수정
DELETE /directory/profile-statuses/{profileStatusId}상태 삭제

상태는 도메인 단위로 관리한다. 기본값으로 설정된 BUSY, AWAY, LEAVE_OFFICE, ABSENCE는 변경하거나 삭제할 수 없다. 사용자 상태는 기본값을 포함하여 최대 10개까지 등록할 수 있다.
자세한 내용은 구성원 상태 관리를 참고한다.


외부 키 수정 및 목록 조회 {#externalkey-bulk-manage}

다음 API로 외부 키를 수정하거나 목록을 조회할 수 있다.

HTTP RequestDescription
POST /users/external-keys구성원 외부 키 목록 수정
GET /users/external-keys구성원 외부 키 목록 조회
POST /groups/external-keys그룹 외부 키 목록 수정
GET /groups/external-keys그룹 외부 키 목록 조회
POST /orgunits/external-keys조직 외부 키 목록 수정
GET /orgunits/external-keys조직 외부 키 목록 조회
POST /directory/levels/external-keys직급 외부 키 목록 수정
GET /directory/levels/external-keys직급 외부 키 목록 가져오기
POST /directory/positions/external-keys직책 외부 키 목록 수정
GET /directory/positions/external-keys직책 외부 키 목록 조회
POST /directory/user-types/external-keys사용자 유형 외부 키 목록 수정
GET /directory/user-types/external-keys사용자 유형 외부 키 목록 조회

조직 연동 {#org-sync}

조직 연동이란 고객사의 조직 정보를 NAVER WORKS의 조직 정보와 동기화하는 작업을 의미한다. Directory API를 이용하면 고객사의 조직 정보를 NAVER WORKS의 조직 정보와 동기화할 수 있다.

조직 연동을 사용하려면 아래와 같은 준비가 필요하다.

  • Directory scope를 포함하는 클라이언트 앱
  • 서비스 계정
  • Developer Console의 조직 연동 설정(선택)

조직 연동 메뉴 {#org-sync-menu}

Developer Console의 조직연동 메뉴에서 다음과 같은 설정을 할 수 있다.

조직 연동 사용 설정 {#org-sync-setting}

연동하고자 하는 항목(조직/구성원, 직급/직책, 그룹, 사용자 유형, 사용언어, 상태연동)을 On으로 설정할 수 있다. 구성원의 회사 겸직을 설정하려면 겸직 도메인도 조직 연동 사용 설정을 On으로 설정해야 한다. 조직 연동 설정 시 서비스에서 다음과 같은 기능이 제한된다.

조직 연동 항목 설정에 따른 Admin의 동작 {#admin-operation-restriction}

  • 조직 연동 사용 설정을 On으로 적용하면, ‘승인대기’ 중인 구성원은 모두 삭제되고 Admin의 구성원 초대 기능도 사용하지 않는 것으로 자동 설정된다.
  • 조직/구성원을 On으로 설정하면 NAVER WORKS Admin에서 구성원과 조직을 조회만 할 수 있다. 조직 사용 기능을 허용하도록 선택하면 NAVER WORKS Admin에서 조직 사용 기능의 사용 여부를 설정할 수 있다.
  • 직급/직책을 On으로 설정하면 NAVER WORKS Admin에 구성원 > 직급/직책이 노출되지 않는다.
  • 그룹을 On으로 설정하면 NAVER WORKS Admin에서 그룹 기본 정보를 수정할 수 없다. 그룹 기능을 허용하도록 선택하면 NAVER WORKS Admin에서 그룹 기능의 사용 여부를 설정할 수 있다.
  • 사용자 유형를 On으로 설정하면 NAVER WORKS Admin에 구성원 > 사용자 유형가 노출되지 않는다.

조직 연동 항목 설정에 따른 구성원의 동작 {#user-operation-restriction}

  • 조직/구성원을 On으로 설정하면 구성원이 프로필 사진을 직접 편집할 수 있도록 허용하거나 허용하지 않을 수 있다.
  • 사용언어를 On으로 설정하면 구성원이 언어·시간대 항목을 설정할 수 없다.
  • 상태연동을 On으로 설정하면 구성원이 상태 항목을 설정할 수 없다.

조직 연동 항목 접근 {#org-sync-access}

조직, 구성원, 그룹, 사용자 유형, 직급, 직책, 상태를 구성하는 각각의 항목은 다음과 같은 방법으로 식별하거나 접근할 수 있다.

  • 리소스 ID 사용(권장): 조직, 구성원, 그룹, 사용자 유형, 직급, 직책, 상태의 각 항목 생성 시 자동으로 발급되는 리소스 ID를 이용해 접근할 수 있다.
  • 외부 키 매핑(External Key Mapping) 사용: 조직, 구성원, 그룹, 사용자 유형, 직급, 직책, 상태의 각 항목을 연동할 수 있는 ID를 추가로 지정하여 사용 중인 그룹웨어 정보와 연결할 수 있다. 외부 키는 특수문자 %와 \를 허용하지 않으며, 항목별로 중복 조건이 다르다.
    • 조직, 구성원, 그룹, 사용자 유형: 테넌트 내에 유일해야 한다.
    • 직급, 직책: 도메인 내에서 유일해야 한다.

Directory API는 리소스 ID 또는 외부 키 매핑을 사용해 접근할 수 있다.

외부 키 매핑 방법 {#external-key-mapping}

항목별로 전체 정보를 다운로드해 수정한 후 다시 등록하여 매핑할 수 있다.

  1. Developer Console에서 조직연동을 선택한다.
  2. 각 External Key Mapping 항목의 다운로드를 클릭한다.
  3. 다운로드한 CSV 파일에 외부 키 항목을 입력한 후 저장한다.
  4. 파일첨부를 클릭해 파일을 등록한다.
  5. 미리보기 화면에서 등록한 파일을 확인하고 중복된 외부 키가 있으면 수정한다.
  6. 저장을 클릭한다.

Custom URL 설정 {#custom-url}

조직도 팝업, 메일 주소록, 개인 정보 팝업에서 지정된 URL에 해당하는 화면을 표시한다. 팝업으로 표시할 경우 구성원 이름을 #SEARCHTEXT #파라미터에 포함하여 제공한다.

참고

Custom URL은 조직 연동 및 API 설정과 관계없이 설정할 수 있다.

조직 정보 배치 작업 시 주의 사항 {#org-sync-by-api}

조직 연동 사용 준비를 마쳤으면, Directory API를 사용할 수 있다.

  • Directory API를 사용한 조직 연동 배치 작업은 다음과 같이 직책/직급/사용자 유형 → 조직 → 구성원 → 그룹 순서로 진행할 것을 권장한다. 예를 들어, 구성원을 추가하기 전에 소속될 조직을 설정해야 한다.

ALT

[그림 1 조직 연동 배치]

  • 조직 연동은 일(day) 단위 배치로 실행할 것을 권장한다.
  • 각 단계에서 실패 시 롤백 프로세스는 자사의 정책에 맞게 적용한다. 단, 한 단계 안에서 일부가 실패했을 때(조직 중 일부가 실패)는 계속 진행하고, 한 단계 전체가 실패하면(조직 전체가 실패) 배치를 중단할 것을 권장한다.
  • API를 동시에 5회 이상 호출하지 않도록 관리한다. 특히, 조직 관련 API는 단일 스레드로 호출해야 한다.
  • 구성원이나 그룹 등의 수정 API 호출 시 수정된 정보만 연동하여 불필요한 작업을 최소화한다. 예) 부분 조직 개편으로 일부 조직의 이름이 변경된 경우
  • 호출에 실패한 API 요청에 대해서 반드시 방어 로직을 구현해야 한다.
  • API 요청 실패를 감지할 수 있도록 로그 관리 혹은 모니터링 시스템을 함께 구축한다.