> For the complete documentation index, see [llms.txt](/llms.txt)

# GS2-Friend SDK for Game Engine API 레퍼런스

게임 엔진용 GS2-Friend SDK의 모델 사양과 API 레퍼런스



## 모델

### EzProfile

프로필<br>

프로필은 게임 플레이어에 관한 정보를 저장합니다.<br>

프로필은 공개 범위별로 설정할 수 있으며, 3가지 종류가 있습니다.<br>

- friend 친구 관계가 성립된 상대방이 열람 가능한 내용<br>
- follow 팔로우하고 있는 상대방이 열람 가능한 내용<br>
- public 누구나 열람 가능한 내용

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| userId | string |  | ✓ |  |  ~ 128자 | 사용자ID |
| publicProfile | string |  |  |  |  ~ 1024자 | 공개되는 프로필<br>관계와 상관없이 모든 플레이어에게 표시되는 프로필 정보입니다. 일반적으로 표시 이름, 아바타, 기타 공개 가능한 정보에 사용됩니다. |
| followerProfile | string |  |  |  |  ~ 1024자 | 팔로워에게 공개되는 프로필<br>이 사용자를 팔로우하고 있는 플레이어에게만 표시되는 프로필 정보입니다. 공개 프로필보다 상세한 정보(게임플레이 통계나 상태 메시지 등)를 포함할 수 있습니다. |
| friendProfile | string |  |  |  |  ~ 1024자 | 친구에게 공개되는 프로필<br>상호 친구 관계가 성립된 플레이어에게만 표시되는 프로필 정보입니다. 가장 프라이빗한 프로필 수준으로, 연락처나 개인 메시지 등 개인 정보를 공유하기에 적합합니다. |

**관련 메서드:**
getProfile - 플레이어 자신의 프로필 가져오기
updateProfile - 플레이어 자신의 프로필 업데이트하기


---

### EzBlackList

블랙리스트<br>

플레이어가 차단한 사용자의 목록을 관리합니다.<br>
차단된 사용자는 이 플레이어에게 친구 요청을 보내거나 팔로우할 수 없게 되어, 원치 않는 상호작용을 제어하는 메커니즘을 제공합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| userId | string |  | ✓ |  |  ~ 128자 | 사용자ID |
| targetUserIds | List&lt;string&gt; |  |  |  | 0 ~ 1000 items | 블랙리스트의 사용자 ID 목록<br>이 플레이어가 차단한 사용자 ID 목록입니다. 차단된 사용자는 이 플레이어에게 친구 요청이나 팔로우 요청을 보낼 수 없습니다. |

**관련 메서드:**
registerBlackList - 플레이어 차단하기
unregisterBlackList - 플레이어 차단 해제하기


---

### EzFollowUser

팔로우 사용자<br>

현재 사용자가 팔로우하고 있는 사용자를 나타냅니다. 팔로우 대상 사용자의 공개 프로필과 팔로워 수준의 프로필 정보에 대한 접근을 제공하며, 이는 팔로워에게는 표시되지만 일반에는 공개되지 않습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| userId | string |  | ✓ |  |  ~ 128자 | 사용자ID |
| publicProfile | string |  |  |  |  ~ 1024자 | 공개되는 프로필<br>팔로우 대상 사용자의 공개 프로필 정보로, 모든 플레이어가 접근할 수 있습니다. |
| followerProfile | string |  |  |  |  ~ 1024자 | 팔로워에게 공개되는 프로필<br>팔로워에게만 표시되는 프로필 정보입니다. 공개 프로필보다 상세한 정보를 포함할 수 있습니다. |

**관련 메서드:**
describeFollowUsers - 플레이어가 팔로우하는 플레이어 목록 가져오기
follow - 다른 플레이어 팔로우하기
getFollowUser - 특정 플레이어를 팔로우하고 있는지 확인하기
unfollow - 플레이어 팔로우 해제하기


---

### EzFriendUser

친구 사용자<br>

현재 사용자와 상호 친구 관계가 성립된 사용자를 나타냅니다. 친구의 공개 프로필과 친구 수준의 프로필 정보에 대한 접근을 제공하며, 이는 확인된 친구에게만 표시됩니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| userId | string |  | ✓ |  |  ~ 128자 | 사용자ID |
| publicProfile | string |  |  |  |  ~ 1024자 | 공개되는 프로필<br>친구의 공개 프로필 정보로, 모든 플레이어가 접근할 수 있습니다. |
| friendProfile | string |  |  |  |  ~ 1024자 | 친구에게 공개되는 프로필<br>확인된 친구에게만 표시되는 친구의 프로필 정보입니다. 공개 프로필보다 프라이빗한 정보를 포함합니다. |

**관련 메서드:**
deleteFriend - 친구 목록에서 플레이어 삭제하기
describeFriends - 플레이어의 친구 목록 가져오기
getFriend - 특정 친구의 정보 가져오기


---

### EzFriendRequest

친구 요청<br>

두 플레이어 간의 친구 요청을 나타냅니다. 발신자의 사용자 ID, 수신자의 사용자 ID, 그리고 표시용 발신자의 공개 프로필을 포함합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| userId | string |  | ✓ |  |  ~ 128자 | 친구 요청을 보낸 사용자 ID |
| targetUserId | string |  | ✓ |  |  ~ 128자 | 친구 요청을 받은 사용자 ID |
| publicProfile | string |  |  |  |  ~ 1024자 | 공개 프로필<br>친구 요청 발신자의 공개 프로필입니다. 수신자가 누가 친구 신청을 하고 있는지 식별할 수 있도록 표시용으로 포함됩니다. |

**관련 메서드:**
deleteRequest - 전송한 친구 요청 취소하기
describeSendRequests - 전송한 친구 요청 목록 가져오기
getSendRequest - 특정 전송한 친구 요청 가져오기
sendRequest - 다른 플레이어에게 친구 요청 보내기
accept - 친구 요청 승인하기
describeReceiveRequests - 받은 친구 요청 목록 가져오기
getReceiveRequest - 특정 받은 친구 요청 가져오기
reject - 친구 요청 거부하기


---

### EzPublicProfile

공개 프로필<br>

사용자의 공개 프로필 정보에 대한 읽기 전용 뷰입니다. 친구나 팔로우 관계를 필요로 하지 않으며, 임의의 사용자에 대해 조회할 수 있습니다. 검색 결과, 리더보드, 기타 공개적인 컨텍스트에서 플레이어 정보를 표시하는 데 사용됩니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| userId | string |  | ✓ |  |  ~ 128자 | 사용자ID |
| publicProfile | string |  |  |  |  ~ 1024자 | 공개되는 프로필<br>사용자의 공개 프로필 내용입니다. 친구나 팔로워 관계를 필요로 하지 않고 접근할 수 있습니다. |

**관련 메서드:**
getPublicProfile - 다른 플레이어의 공개 프로필 가져오기


---

## 메서드

### getProfile

플레이어 자신의 프로필 가져오기<br>

플레이어 자신의 프로필을 3가지 공개 수준 모두 포함하여 가져옵니다:<br>
- 공개 프로필: 누구나 볼 수 있는 정보(플레이어 이름, 아바타 등)<br>
- 팔로워 전용 프로필: 팔로우해 준 사람만 볼 수 있는 정보(플레이 스타일, 좋아하는 팀 등)<br>
- 친구 전용 프로필: 상호 친구만 볼 수 있는 정보(본명, 연락처 등)<br>
"내 프로필"이나 "프로필 편집" 화면에서 플레이어가 자신의 프로필 정보를 확인·관리할 수 있도록 하는 데 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzProfile](#ezprofile) | 프로필|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Profile(
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Profile(
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Profile(
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).profile(
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Profile(
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Profile(
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Profile(
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Friend::Model::FProfile> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).profile(
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getPublicProfile

다른 플레이어의 공개 프로필 가져오기<br>

지정한 플레이어의 프로필 중 공개 부분만 가져옵니다. 팔로우나 친구 관계와 무관하게 누구나 볼 수 있는 정보입니다.<br>
예를 들어 표시 이름, 아바타, 레벨 등이 반환되지만, 팔로워 전용이나 친구 전용 프로필 데이터는 포함되지 않습니다.<br>
랭킹, 채팅, 매칭 결과 등에서 다른 플레이어의 이름을 탭했을 때 플레이어 카드나 미니 프로필을 표시하는 데 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| userId | string |  | ✓|  |  ~ 128자 | 사용자ID |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzPublicProfile](#ezpublicprofile) | 공개 프로필|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: "user-0001"
    ).PublicProfile(
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: "user-0001"
    ).PublicProfile(
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->User(
        "user-0001" // userId
    )->PublicProfile(
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).user(
        "user-0001"
    ).public_profile(
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: "user-0001"
    ).PublicProfile(
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: "user-0001"
    ).PublicProfile(
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->User(
        "user-0001" // userId
    )->PublicProfile(
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Friend::Model::FPublicProfile> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).user(
        "user-0001"
    ).public_profile(
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### updateProfile

플레이어 자신의 프로필 업데이트하기<br>

플레이어의 프로필을 3가지 공개 수준으로 업데이트합니다:<br>
- publicProfile: 모든 플레이어에게 표시되는 정보(표시 이름, 레벨, 아바타 아이콘 등)<br>
- followerProfile: 팔로워에게만 표시되는 추가 정보("길드 멤버 모집 중!" 등)<br>
- friendProfile: 친구에게만 표시되는 프라이빗한 정보(Discord ID, 일정 등)<br>
각 필드는 자유 형식 문자열이므로 텍스트나 JSON 데이터 등 무엇이든 저장할 수 있습니다. 설정 화면이나 프로필 편집 화면에서 플레이어가 프로필을 편집할 때 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| publicProfile | string |  | |  |  ~ 1024자 | 공개되는 프로필<br>관계와 상관없이 모든 플레이어에게 표시되는 프로필 정보입니다. 일반적으로 표시 이름, 아바타, 기타 공개 가능한 정보에 사용됩니다. |
| followerProfile | string |  | |  |  ~ 1024자 | 팔로워에게 공개되는 프로필<br>이 사용자를 팔로우하고 있는 플레이어에게만 표시되는 프로필 정보입니다. 공개 프로필보다 상세한 정보(게임플레이 통계나 상태 메시지 등)를 포함할 수 있습니다. |
| friendProfile | string |  | |  |  ~ 1024자 | 친구에게 공개되는 프로필<br>상호 친구 관계가 성립된 플레이어에게만 표시되는 프로필 정보입니다. 가장 프라이빗한 프로필 수준으로, 연락처나 개인 메시지 등 개인 정보를 공유하기에 적합합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzProfile](#ezprofile) | 갱신한 프로필|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Profile(
    );
    var result = await domain.UpdateProfileAsync(
        publicProfile: "public",
        followerProfile: "follower",
        friendProfile: "friend"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Profile(
    );
    var future = domain.UpdateProfileFuture(
        publicProfile: "public",
        followerProfile: "follower",
        friendProfile: "friend"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Profile(
    );
    const auto Future = Domain->UpdateProfile(
        "public", // publicProfile
        "follower", // followerProfile
        "friend" // friendProfile
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).profile(
    )

var async_result = await domain.update_profile(
    "public", # public_profile
    "follower", # follower_profile
    "friend" # friend_profile
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### describeFollowUsers

플레이어가 팔로우하는 플레이어 목록 가져오기<br>

현재 플레이어가 팔로우하는 모든 플레이어를 가져옵니다.<br>
팔로우는 단방향 관계입니다. 상대방의 승인 없이 팔로우할 수 있는, SNS의 팔로우와 같은 방식입니다.<br>
withProfile을 true로 설정하면 팔로우 대상 플레이어의 팔로워 전용 프로필(팔로워에게 공개하는 추가 정보)도 함께 반환됩니다.<br>
"팔로우 중" 목록 화면을 구성하여 플레이어가 자신의 팔로우 목록을 확인할 수 있도록 하는 데 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| withProfile | bool |  | | false |  | 프로필 정보도 함께 조회할지 여부 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzFollowUser&gt;](#ezfollowuser) | 사용자가 팔로우하는 사용자 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Follow(
        withProfile: true
    );
    var items = await domain.FollowsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Follow(
        withProfile: true
    );
    var it = domain.Follows(
    );
    List<EzFollowUser> items = new List<EzFollowUser>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Follow(
        true // withProfile
    );
    const auto It = Domain->Follows(
    );
    TArray<Gs2::UE5::Friend::Model::FEzFollowUserPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


---

### follow

다른 플레이어 팔로우하기<br>

지정한 플레이어를 현재 플레이어의 팔로우 목록에 추가합니다.<br>
팔로우는 상대방의 승인이 필요 없는 단방향 액션입니다. SNS의 팔로우와 같은 방식입니다.<br>
팔로우 후에는 대상 플레이어의 팔로워 전용 프로필 정보(팔로워에게 공개하는 추가 정보)를 볼 수 있게 됩니다.<br>
다른 플레이어의 프로필 화면, 검색 결과, 랭킹 화면 등의 "팔로우" 버튼에 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| targetUserId | string |  | ✓|  |  ~ 128자 | 팔로우하고 싶은 상대의 사용자 ID |
| withProfile | bool | ✓ | false |  | 프로필도 함께 취득할지 여부 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFollowUser](#ezfollowuser) | 팔로우한 사용자|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Follow(
        withProfile: true
    );
    var result = await domain.FollowAsync(
        targetUserId: "user-0002"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Follow(
        withProfile: true
    );
    var future = domain.FollowFuture(
        targetUserId: "user-0002"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Follow(
        true // withProfile
    );
    const auto Future = Domain->Follow(
        "user-0002" // targetUserId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).follow(
        null
    )

var async_result = await domain.follow(
    "user-0002" # target_user_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### getFollowUser

특정 플레이어를 팔로우하고 있는지 확인하기<br>

현재 플레이어의 팔로우 목록에서 특정 플레이어를 가져옵니다.<br>
대상 플레이어가 팔로우 목록에 있으면 해당 정보가 반환됩니다. withProfile을 true로 설정하면 팔로워 전용 프로필도 포함됩니다.<br>
플레이어가 이미 상대방을 팔로우하고 있는지 확인하는 데 사용합니다. 예를 들어 다른 플레이어의 프로필 화면에서 "팔로우 중 / 팔로우하기" 버튼의 표시를 전환하는 데 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| withProfile | bool |  | | false |  | 프로필 정보도 함께 조회할지 여부 |
| targetUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFollowUser](#ezfollowuser) | 팔로우 중인 사용자|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Follow(
        withProfile: true
    ).FollowUser(
        targetUserId: "user-0002"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Follow(
        withProfile: true
    ).FollowUser(
        targetUserId: "user-0002"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Follow(
        true // withProfile
    )->FollowUser(
        "user-0002" // targetUserId
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).follow(
        true
    ).follow_user(
        "user-0002"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Follow(
        withProfile: true
    ).FollowUser(
        targetUserId: "user-0002"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Follow(
        withProfile: true
    ).FollowUser(
        targetUserId: "user-0002"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Follow(
        true // withProfile
    )->FollowUser(
        "user-0002" // targetUserId
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Friend::Model::FFollowUser> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).follow(
        true
    ).follow_user(
        "user-0002"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### unfollow

플레이어 팔로우 해제하기<br>

지정한 플레이어를 현재 플레이어의 팔로우 목록에서 삭제합니다.<br>
팔로우 해제 후에는 대상 플레이어의 팔로워 전용 프로필 정보를 볼 수 없게 됩니다.<br>
팔로우 중인 플레이어의 프로필 화면이나 "팔로우 중" 목록 화면의 "팔로우 해제" 버튼에 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| targetUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |
| withProfile | bool | ✓ | false |  | 프로필도 함께 취득할지 여부 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFollowUser](#ezfollowuser) | 언팔로우한 사용자|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Follow(
        withProfile: true
    ).FollowUser(
        targetUserId: "user-0002"
    );
    var result = await domain.UnfollowAsync(
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Follow(
        withProfile: true
    ).FollowUser(
        targetUserId: "user-0002"
    );
    var future = domain.UnfollowFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Follow(
        true // withProfile
    )->FollowUser(
        "user-0002" // targetUserId
    );
    const auto Future = Domain->Unfollow(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).follow(
        null
    ).follow_user(
        "user-0002"
    )

var async_result = await domain.unfollow(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### deleteFriend

친구 목록에서 플레이어 삭제하기<br>

지정한 플레이어를 현재 플레이어의 친구 목록에서 삭제하여 상호 친구 관계를 해제합니다.<br>
삭제 후에는 서로의 친구 전용 프로필 정보를 볼 수 없게 됩니다.<br>
친구의 프로필 화면이나 상세 화면의 "친구 삭제" 버튼에 사용합니다. 상대방 쪽도 친구 관계가 해제되므로 확인 대화상자를 표시하는 것을 권장합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| targetUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |
| withProfile | bool | ✓ | false |  | 프로필도 함께 취득할지 여부 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFriendUser](#ezfrienduser) | 삭제한 친구 사용자|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Friend(
        withProfile: true
    );
    var result = await domain.DeleteFriendAsync(
        targetUserId: "user-0002"
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Friend(
        withProfile: true
    );
    var future = domain.DeleteFriendFuture(
        targetUserId: "user-0002"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Friend(
        true // withProfile
    );
    const auto Future = Domain->DeleteFriend(
        "user-0002" // targetUserId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).friend(
        null
    )

var async_result = await domain.delete_friend(
    "user-0002" # target_user_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### describeFriends

플레이어의 친구 목록 가져오기<br>

현재 플레이어와 상호 친구 관계에 있는 모든 플레이어를 가져옵니다.<br>
팔로우(단방향)와 달리, 친구는 친구 요청이 승인되어 성립되는 양방향 관계입니다.<br>
withProfile을 true로 설정하면 각 친구의 친구 전용 프로필(가장 프라이빗한 수준의 프로필 정보)도 함께 반환됩니다.<br>
"친구" 목록 화면을 구성하는 데 사용합니다. 예를 들어 친구의 이름, 아바타, 온라인 상태 등을 표시할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| withProfile | bool |  | | false |  | 프로필 정보도 함께 조회할지 여부 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzFriendUser&gt;](#ezfrienduser) | 친구 사용자 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.FriendsAsync(
        withProfile: true
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.Friends(
        withProfile: true
    );
    List<EzFriendUser> items = new List<EzFriendUser>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->Friends(
        true // withProfile
    );
    TArray<Gs2::UE5::Friend::Model::FEzFriendUserPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeFriends(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeFriends(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeFriends(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeFriends(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeFriends(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeFriends(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getFriend

특정 친구의 정보 가져오기<br>

현재 플레이어의 친구 목록에서 특정 플레이어의 정보를 가져옵니다.<br>
withProfile을 true로 설정하면 친구의 친구 전용 프로필(가장 프라이빗한 수준의 프로필 정보)도 반환됩니다.<br>
친구 상세 화면을 표시할 때 사용합니다. 예를 들어 친구의 전체 프로필, 상태, "친구 삭제"나 "메시지 보내기" 등의 옵션을 표시할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| targetUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |
| withProfile | bool |  | | false |  | 프로필 정보도 함께 조회할지 여부 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFriendUser](#ezfrienduser) | 친구 사용자|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Friend(
        withProfile: true
    ).FriendUser(
        targetUserId: "user-0002"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Friend(
        withProfile: true
    ).FriendUser(
        targetUserId: "user-0002"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Friend(
        true // withProfile
    )->FriendUser(
        "user-0002" // targetUserId
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).friend(
        true
    ).friend_user(
        "user-0002"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Friend(
        withProfile: true
    ).FriendUser(
        targetUserId: "user-0002"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Friend(
        withProfile: true
    ).FriendUser(
        targetUserId: "user-0002"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Friend(
        true // withProfile
    )->FriendUser(
        "user-0002" // targetUserId
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Friend::Model::FFriendUser> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).friend(
        true
    ).friend_user(
        "user-0002"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### deleteRequest

전송한 친구 요청 취소하기<br>

플레이어가 전송한 친구 요청을 상대방이 응답하기 전에 취소합니다.<br>
요청은 발신자의 송신함과 수신자의 수신함 양쪽에서 삭제됩니다.<br>
전송한 요청 화면이나, 이미 요청을 전송한 플레이어의 프로필 화면의 "요청 취소" 버튼에 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| targetUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFriendRequest](#ezfriendrequest) | 삭제한 친구 요청|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SendFriendRequest(
        targetUserId: "user-0002"
    );
    var result = await domain.DeleteRequestAsync(
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SendFriendRequest(
        targetUserId: "user-0002"
    );
    var future = domain.DeleteRequestFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->SendFriendRequest(
        "user-0002" // targetUserId
    );
    const auto Future = Domain->DeleteRequest(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).send_friend_request(
        "user-0002"
    )

var async_result = await domain.delete_request(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### describeSendRequests

전송한 친구 요청 목록 가져오기<br>

현재 플레이어가 전송한, 아직 응답을 기다리고 있는 친구 요청을 모두 가져옵니다.<br>
각 요청에는 누구에게 언제 보냈는지가 표시됩니다. 플레이어는 마음이 바뀌면 전송한 요청을 취소할 수 있습니다.<br>
"전송한 요청" 화면을 구성하는 데 사용합니다. 예를 들어 "플레이어B의 응답을 기다리는 중… [취소]"와 같이 표시할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzFriendRequest&gt;](#ezfriendrequest) | 친구 요청 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.SendRequestsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.SendRequests(
    );
    List<EzFriendRequest> items = new List<EzFriendRequest>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->SendRequests(
    );
    TArray<Gs2::UE5::Friend::Model::FEzFriendRequestPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


---

### getSendRequest

특정 전송한 친구 요청 가져오기<br>

현재 플레이어가 특정 플레이어에게 전송한 친구 요청의 상세 정보를 가져옵니다.<br>
특정 요청의 상태를 표시할 때 사용합니다. 예를 들어 특정 플레이어에게 보낸 요청이 아직 보류 중인지 확인하거나, 플레이어 프로필 화면에서 요청 상세 정보를 표시하는 데 사용할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| targetUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFriendRequest](#ezfriendrequest) | 친구 요청|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SendFriendRequest(
        targetUserId: "user-0002"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SendFriendRequest(
        targetUserId: "user-0002"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->SendFriendRequest(
        "user-0002" // targetUserId
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).send_friend_request(
        "user-0002"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SendFriendRequest(
        targetUserId: "user-0002"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SendFriendRequest(
        targetUserId: "user-0002"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->SendFriendRequest(
        "user-0002" // targetUserId
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Friend::Model::FSendFriendRequest> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).send_friend_request(
        "user-0002"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### sendRequest

다른 플레이어에게 친구 요청 보내기<br>

지정한 플레이어에게 친구 요청을 보냅니다. 요청은 상대방의 수신함에 도착하며, 승인하거나 거부할 수 있습니다.<br>
승인되면 서로 상호 친구가 되어 친구 전용 프로필 정보를 볼 수 있게 됩니다.<br>
주의: 이미 친구가 1000명 있는 경우 요청을 보낼 수 없습니다. 또한 미승인 요청이 존재하는 경우, 가장 오래된 미승인 요청이 자동으로 취소되고 새 요청이 전송됩니다.<br>
다른 플레이어의 프로필 화면이나 검색 결과의 "친구 요청 보내기" 버튼에 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| targetUserId | string |  | ✓|  |  ~ 128자 | 친구가 되고 싶은 상대의 사용자 ID |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFriendRequest](#ezfriendrequest) | 송신한 친구 요청|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var result = await domain.SendRequestAsync(
        targetUserId: "user-0002"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var future = domain.SendRequestFuture(
        targetUserId: "user-0002"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto Future = Domain->SendRequest(
        "user-0002" // targetUserId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session)

var async_result = await domain.send_request(
    "user-0002" # target_user_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### accept

친구 요청 승인하기<br>

지정한 플레이어로부터 받은 친구 요청을 승인합니다.<br>
승인하면 상호 친구 관계가 성립되어 서로의 친구 목록에 추가되고, 친구 전용 프로필 정보를 볼 수 있게 됩니다.<br>
친구 요청 알림이나 수신함 화면의 "승인" 버튼에 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| fromUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFriendRequest](#ezfriendrequest) | 승낙한 친구 요청|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).ReceiveFriendRequest(
        fromUserId: "user-0002"
    );
    var result = await domain.AcceptAsync(
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).ReceiveFriendRequest(
        fromUserId: "user-0002"
    );
    var future = domain.AcceptFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->ReceiveFriendRequest(
        nullptr, // targetUserId
        "user-0002" // fromUserId
    );
    const auto Future = Domain->Accept(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).receive_friend_request(
        "user-0002"
    )

var async_result = await domain.accept(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### describeReceiveRequests

받은 친구 요청 목록 가져오기<br>

다른 플레이어가 현재 플레이어에게 보낸, 응답을 기다리고 있는 친구 요청을 모두 가져옵니다.<br>
각 요청에는 누가 언제 보냈는지가 표시됩니다. 플레이어는 각각 승인하거나 거부할 수 있습니다.<br>
"친구 요청" 수신함 화면을 구성하는 데 사용합니다. 예를 들어 "플레이어A님이 친구가 되고 싶어합니다! [승인] [거부]"와 같이 표시할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzFriendRequest&gt;](#ezfriendrequest) | 친구 요청 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.ReceiveRequestsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.ReceiveRequests(
    );
    List<EzFriendRequest> items = new List<EzFriendRequest>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->ReceiveRequests(
    );
    TArray<Gs2::UE5::Friend::Model::FEzFriendRequestPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


---

### getReceiveRequest

특정 받은 친구 요청 가져오기<br>

특정 발신자로부터 받은 친구 요청의 상세 정보를 가져옵니다.<br>
친구 요청 상세 화면을 표시할 때 사용합니다. 예를 들어 발신자의 프로필과 요청 전송 일시를 표시하고 "승인", "거부" 버튼을 배치하는 화면에 사용할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| fromUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFriendRequest](#ezfriendrequest) | 친구 요청|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).ReceiveFriendRequest(
        targetUserId: null,
        fromUserId: "user-0002"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).ReceiveFriendRequest(
        targetUserId: null,
        fromUserId: "user-0002"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->ReceiveFriendRequest(
        nullptr, // targetUserId
        "user-0002" // fromUserId
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).receive_friend_request(
        "user-0002"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).ReceiveFriendRequest(
        targetUserId: null,
        fromUserId: "user-0002"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).ReceiveFriendRequest(
        targetUserId: null,
        fromUserId: "user-0002"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->ReceiveFriendRequest(
        nullptr, // targetUserId
        "user-0002" // fromUserId
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Friend::Model::FReceiveFriendRequest> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).receive_friend_request(
        "user-0002"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### reject

친구 요청 거부하기<br>

지정한 플레이어로부터 받은 친구 요청을 거부합니다.<br>
요청은 삭제되며 친구 관계는 성립되지 않습니다. 거부되었다는 사실은 발신자에게 통지되지 않습니다.<br>
친구 요청 알림이나 수신함 화면의 "거부" 또는 "거절" 버튼에 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| fromUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzFriendRequest](#ezfriendrequest) | 거부한 친구 요청|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).ReceiveFriendRequest(
        fromUserId: "user-0002"
    );
    var result = await domain.RejectAsync(
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).ReceiveFriendRequest(
        fromUserId: "user-0002"
    );
    var future = domain.RejectFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->ReceiveFriendRequest(
        nullptr, // targetUserId
        "user-0002" // fromUserId
    );
    const auto Future = Domain->Reject(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).receive_friend_request(
        "user-0002"
    )

var async_result = await domain.reject(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### getBlackList

플레이어의 차단 목록 가져오기<br>

현재 플레이어가 차단한 사용자 ID 목록을 가져옵니다.<br>
차단된 플레이어는 현재 플레이어에게 친구 요청을 보내거나 팔로우할 수 없게 됩니다.<br>
"차단 중인 플레이어" 관리 화면을 구성하는 데 사용합니다. 이전에 차단한 상대를 확인하거나 차단을 해제할 수 있는 화면에 사용할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | List&lt;string&gt; | 블랙리스트에 등록된 사용자 ID 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.BlackListUsersAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.BlackListUsers(
    );

    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->BlackListUsers(
    );

    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


---

### registerBlackList

플레이어 차단하기<br>

지정한 플레이어를 현재 플레이어의 차단 목록에 추가합니다.<br>
차단하면 대상 플레이어는 현재 플레이어에게 친구 요청을 보내거나 팔로우할 수 없게 됩니다.<br>
다른 플레이어의 프로필 화면이나 신고·모더레이션 메뉴의 "차단" 버튼에 사용합니다. 플레이어가 원치 않는 상호작용으로부터 자신을 보호하는 데 도움이 됩니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| targetUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzBlackList](#ezblacklist) | 블랙리스트|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BlackList(
    );
    var result = await domain.RegisterBlackListAsync(
        targetUserId: "user-0002"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BlackList(
    );
    var future = domain.RegisterBlackListFuture(
        targetUserId: "user-0002"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->BlackList(
    );
    const auto Future = Domain->RegisterBlackList(
        "user-0002" // targetUserId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).black_list(
    )

var async_result = await domain.register_black_list(
    "user-0002" # target_user_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### unregisterBlackList

플레이어 차단 해제하기<br>

지정한 플레이어를 현재 플레이어의 차단 목록에서 삭제합니다.<br>
차단 해제 후에는 대상 플레이어가 다시 현재 플레이어에게 친구 요청을 보내거나 팔로우할 수 있게 됩니다.<br>
차단 중인 플레이어 관리 화면이나 차단 중인 플레이어의 프로필 화면의 "차단 해제" 버튼에 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| targetUserId | string |  | ✓|  |  ~ 128자 | 사용자ID |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzBlackList](#ezblacklist) | 블랙리스트|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BlackList(
    );
    var result = await domain.UnregisterBlackListAsync(
        targetUserId: "user-0002"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Friend.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BlackList(
    );
    var future = domain.UnregisterBlackListFuture(
        targetUserId: "user-0002"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Friend->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->BlackList(
    );
    const auto Future = Domain->UnregisterBlackList(
        "user-0002" // targetUserId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.friend.namespace_(
        "namespace-0001"
    ).me(game_session).black_list(
    )

var async_result = await domain.unregister_black_list(
    "user-0002" # target_user_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

## 이벤트 핸들러

### OnFollowNotification

팔로우되었을 때 사용하는 푸시 알림

 | 이름 | 타입 | 설명 |
| --- | --- | --- |
| namespaceName | string |네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.|
| userId | string |사용자ID|
| fromUserId | string |사용자ID|

#### 구현 예제





**Unity (UniTask)**
```csharp

    gs2.Friend.OnFollowNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var fromUserId = notification.FromUserId;
    };
```

**Unity (Vanilla)**
```cs

    gs2.Friend.OnFollowNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var fromUserId = notification.FromUserId;
    };
```

**Unreal Engine 5**
```cpp

    Gs2->Friend->OnFollowNotification().AddLambda([](const auto Notification)
    {
        const auto NamespaceName = Notification->NamespaceNameValue;
        const auto UserId = Notification->UserIdValue;
        const auto FromUserId = Notification->FromUserIdValue;
    });
```

**Godot**
```gdscript

    ez.friend.follow_notification.connect(func(notification):
        var namespace_name = notification.namespace_name
        var user_id = notification.user_id
        var from_user_id = notification.from_user_id
    )
```


---

### OnAcceptRequestNotification

친구 요청이 승인되었을 때 사용하는 푸시 알림

 | 이름 | 타입 | 설명 |
| --- | --- | --- |
| namespaceName | string |네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.|
| userId | string |사용자ID|
| targetUserId | string |사용자ID|

#### 구현 예제





**Unity (UniTask)**
```csharp

    gs2.Friend.OnAcceptRequestNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var targetUserId = notification.TargetUserId;
    };
```

**Unity (Vanilla)**
```cs

    gs2.Friend.OnAcceptRequestNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var targetUserId = notification.TargetUserId;
    };
```

**Unreal Engine 5**
```cpp

    Gs2->Friend->OnAcceptRequestNotification().AddLambda([](const auto Notification)
    {
        const auto NamespaceName = Notification->NamespaceNameValue;
        const auto UserId = Notification->UserIdValue;
        const auto TargetUserId = Notification->TargetUserIdValue;
    });
```

**Godot**
```gdscript

    ez.friend.accept_request_notification.connect(func(notification):
        var namespace_name = notification.namespace_name
        var user_id = notification.user_id
        var target_user_id = notification.target_user_id
    )
```


---

### OnRejectRequestNotification

친구 요청이 거절되었을 때 사용하는 푸시 알림

 | 이름 | 타입 | 설명 |
| --- | --- | --- |
| namespaceName | string |네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.|
| userId | string |사용자ID|
| targetUserId | string |사용자ID|

#### 구현 예제





**Unity (UniTask)**
```csharp

    gs2.Friend.OnRejectRequestNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var targetUserId = notification.TargetUserId;
    };
```

**Unity (Vanilla)**
```cs

    gs2.Friend.OnRejectRequestNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var targetUserId = notification.TargetUserId;
    };
```

**Unreal Engine 5**
```cpp

    Gs2->Friend->OnRejectRequestNotification().AddLambda([](const auto Notification)
    {
        const auto NamespaceName = Notification->NamespaceNameValue;
        const auto UserId = Notification->UserIdValue;
        const auto TargetUserId = Notification->TargetUserIdValue;
    });
```

**Godot**
```gdscript

    ez.friend.reject_request_notification.connect(func(notification):
        var namespace_name = notification.namespace_name
        var user_id = notification.user_id
        var target_user_id = notification.target_user_id
    )
```


---

### OnDeleteFriendNotification

친구가 삭제되었을 때 사용하는 푸시 알림

 | 이름 | 타입 | 설명 |
| --- | --- | --- |
| namespaceName | string |네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.|
| userId | string |사용자ID|
| fromUserId | string |사용자ID|

#### 구현 예제





**Unity (UniTask)**
```csharp

    gs2.Friend.OnDeleteFriendNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var fromUserId = notification.FromUserId;
    };
```

**Unity (Vanilla)**
```cs

    gs2.Friend.OnDeleteFriendNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var fromUserId = notification.FromUserId;
    };
```

**Unreal Engine 5**
```cpp

    Gs2->Friend->OnDeleteFriendNotification().AddLambda([](const auto Notification)
    {
        const auto NamespaceName = Notification->NamespaceNameValue;
        const auto UserId = Notification->UserIdValue;
        const auto FromUserId = Notification->FromUserIdValue;
    });
```

**Godot**
```gdscript

    ez.friend.delete_friend_notification.connect(func(notification):
        var namespace_name = notification.namespace_name
        var user_id = notification.user_id
        var from_user_id = notification.from_user_id
    )
```


---

### OnReceiveRequestNotification

친구 요청을 받았을 때 사용하는 푸시 알림

 | 이름 | 타입 | 설명 |
| --- | --- | --- |
| namespaceName | string |네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.|
| userId | string |사용자ID|
| fromUserId | string |사용자ID|

#### 구현 예제





**Unity (UniTask)**
```csharp

    gs2.Friend.OnReceiveRequestNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var fromUserId = notification.FromUserId;
    };
```

**Unity (Vanilla)**
```cs

    gs2.Friend.OnReceiveRequestNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var fromUserId = notification.FromUserId;
    };
```

**Unreal Engine 5**
```cpp

    Gs2->Friend->OnReceiveRequestNotification().AddLambda([](const auto Notification)
    {
        const auto NamespaceName = Notification->NamespaceNameValue;
        const auto UserId = Notification->UserIdValue;
        const auto FromUserId = Notification->FromUserIdValue;
    });
```

**Godot**
```gdscript

    ez.friend.receive_request_notification.connect(func(notification):
        var namespace_name = notification.namespace_name
        var user_id = notification.user_id
        var from_user_id = notification.from_user_id
    )
```


---

### OnCancelRequestNotification

받은 친구 요청이 취소되었을 때 사용하는 푸시 알림

 | 이름 | 타입 | 설명 |
| --- | --- | --- |
| namespaceName | string |네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.|
| userId | string |사용자ID|
| fromUserId | string |사용자ID|

#### 구현 예제





**Unity (UniTask)**
```csharp

    gs2.Friend.OnCancelRequestNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var fromUserId = notification.FromUserId;
    };
```

**Unity (Vanilla)**
```cs

    gs2.Friend.OnCancelRequestNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var userId = notification.UserId;
        var fromUserId = notification.FromUserId;
    };
```

**Unreal Engine 5**
```cpp

    Gs2->Friend->OnCancelRequestNotification().AddLambda([](const auto Notification)
    {
        const auto NamespaceName = Notification->NamespaceNameValue;
        const auto UserId = Notification->UserIdValue;
        const auto FromUserId = Notification->FromUserIdValue;
    });
```

**Godot**
```gdscript

    ez.friend.cancel_request_notification.connect(func(notification):
        var namespace_name = notification.namespace_name
        var user_id = notification.user_id
        var from_user_id = notification.from_user_id
    )
```


---



