> For the complete documentation index, see [llms.txt](https://docs.ggwp.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ggwp.com/kr/ggwp-sdk/chat-complete-integration-example.md).

# 채팅: 전체 통합 예제

다음은 동적 토큰 인증, 사용자 지정 대체 전략, 제재 모니터링 및 재인증 처리를 포함한 일반적인 Unity SDK 사용 예시 전체입니다:

{% code fullWidth="true" %}

```csharp
using UnityEngine;
using System.Threading.Tasks;
using GGWP.Chat;
using GGWP.Sanctions;
using GGWP.Utils.Async;

public class GGWPIntegration : MonoBehaviour
{
    private Subscriber<ChannelSanctionsState> sanctionsSubscriber;
    private Subscriber<SanitizationResponse> sanitizationSubscriber;
    private Subscriber<GGWP.Impl.AuthStatus> authSubscriber;

    async void Start()
    {
        await InitializeSDK();
        // 즉시 WebSocket 연결을 위해 제재 구독 전 인증 수행
        await AuthenticateUser();
        ConfigureReplacementStrategy();
        MonitorAuthentication();
        // 실시간 업데이트를 즉시 받기 위해 인증 후 제재를 구독
        MonitorSanctions();
        MonitorSanitization();
    }

    async Task InitializeSDK()
    {
        if (GGWPSDK.Instance == null)
        {
            Debug.LogError("GGWPSDK not available");
            return;
        }

        // 고객 ID 및 선택적 사용자 이름으로 초기화
        GGWPSDK.Instance.InitializeSDK("your_customer_id", "player_username");
        Debug.Log("SDK initialized");
    }

    async Task AuthenticateUser()
    {
        // OAuth 코드 교환 인증 사용(권장)
        // 이로써 제재 업데이트를 위한 WebSocket 연결도 설정됩니다
        string authCode = GetAuthCodeFromBackend();
        
        try
        {
            var result = await GGWPSDK.Instance?.AuthManager.ExchangeAuthCode(authCode);

            if (result == GGWP.Impl.Result.Success)
            {
                Debug.Log("OAuth authentication successful");
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"Authentication failed: {ex.Message}");
        }
    }

    void ConfigureReplacementStrategy()
    {
        // 선택 사항: 사용할 메시지 버전 구성
        // 설정하지 않으면 서비스 기본값인 UseFiltered 전략이 사용됩니다
        GGWPSDK.Instance?.ChatAPI.SetSanitizationConfig(new SanitizationConfigUpdate
        {
            client = new GGWP.Chat.Impl.SanitizationClientConfig
            {
                // 각 메시지에 대해 AI가 최적의 대체 전략을 선택하도록 함
                messageReplacementConfig = ReplacementStrategy.UseRecommended
            },
            service = null  // 필터링 설정에 대해 서비스 기본값 사용
        });
    }

    async void MonitorAuthentication()
    {
        authSubscriber = new Subscriber<GGWP.Impl.AuthStatus>(
            GGWPSDK.Instance?.AuthManager.SubscribeAuthUpdates()
        );

        await foreach (var status in authSubscriber.GetStream())
        {
            switch (status.status)
            {
                case GGWP.Impl.AuthStatusName.CodeExchangeSession:
                    Debug.Log("OAuth session active - refreshes handled automatically");
                    break;
                    
                case GGWP.Impl.AuthStatusName.NoAuth:
                    // 매우 드문 경우: 세션이 여러 번 갱신에 실패함
                    Debug.LogWarning("Authentication session lost - re-authentication required");
                    
                    if (status.error.ToNullable() != null)
                    {
                        Debug.LogError($"Auth error: {status.error.ToNullable()}");
                    }
                    
                    // 세션을 복원하려면 코드 교환을 다시 수행
                    await ReauthenticateUser();
                    break;
            }
        }
    }

    private async Task ReauthenticateUser()
    {
        try
        {
            Debug.Log("Attempting to re-authenticate user...");
            
            // 백엔드에서 새 인증 코드를 가져옴
            string newAuthCode = GetAuthCodeFromBackend();
            
            // 새 코드를 교환하여 새로운 세션을 얻음
            var result = await GGWPSDK.Instance?.AuthManager.ExchangeAuthCode(newAuthCode);
            
            if (result == GGWP.Impl.Result.Success)
            {
                Debug.Log("Re-authentication successful");
            }
            Debug.Log("메시지가 드롭되었습니다");
            {
                Debug.LogError("Re-authentication failed");
                ShowLoginScreen();
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"Re-authentication error: {ex.Message}");
            ShowLoginScreen();
        }
    }

    async void MonitorSanctions()
    {
        // WebSocket 연결이 되어 있는지 확인하기 위해 인증 후 제재를 구독
        sanctionsSubscriber = new Subscriber<ChannelSanctionsState>(
            GGWPSDK.Instance?.SanctionsAPI.SubscribeSanctionsState()
        );

        await foreach (var state in sanctionsSubscriber.GetStream())
        {
            // 사용자가 채팅에서 음소거되었는지 확인하고 UI를 업데이트
            if (state.chat.status == GGWP.Sanctions.Impl.MuteStatus.Muted)
            {
                Debug.Log("User is muted in chat");
                DisableChatInput();
                
                // 선택적으로 음소거 만료 시간을 표시
                if (state.chat.expiryAt != null)
                {
                    ShowMuteExpiryNotification(state.chat.expiryAt.Value);
                }
            }
            Debug.Log("메시지가 드롭되었습니다");
            {
                EnableChatInput();
            }
        }
    }

    async void MonitorSanitization()
    {
        // 로깅 또는 분석을 위해 모든 정제 이벤트 구독
        sanitizationSubscriber = new Subscriber<SanitizationResponse>(
            // 정화된 메시지를 처리합니다
        );

        await foreach (var sanitized in sanitizationSubscriber.GetStream())
        {
            LogMessageSanitization(sanitized);
        }
    }

    public async Task<bool> SendChatMessage(string message)
    {
        // ReplaceMessage는 구성된 대체 전략(이 경우 UseRecommended)을 사용함
        new ChatMessage { message = userMessage }
            new ChatMessage { message = message }
        );

        GGWP 전역 콘텐츠 필터 구성
        {
            Debug.Log("Message blocked - user may be sanctioned");
            ShowMessageBlockedNotification();
            return false;
        }

        // 반환되는 메시지는 구성된 ReplacementStrategy에 따라 달라짐
        // UseFiltered: 욕설은 별표로 대체됨
        // UseReplaced: 대체 단어로 욕설 대체
        // UseRecommended: AI가 문맥에 따라 최적의 버전을 선택
        // UseOriginal: 원본 메시지 변경 없음
        SendToChat(replaced.messageDetails.replacedMessage);
        return true;
    }

    private string GetAuthCodeFromBackend() 
    { 
        /* 구현: GGWP 서비스에서 인증 코드를 얻기 위해 백엔드에 호출하세요 */ 
        return ""; 
    }
    
    private void DisableChatInput() 
    { 
        /* 구현: 채팅 입력 UI를 비활성화하세요 */ 
    }
    
    private void EnableChatInput() 
    { 
        /* 구현: 채팅 입력 UI를 활성화하세요 */ 
    }
    
    private void LogMessageSanitization(SanitizationResponse response) 
    { 
        /* 구현: 분석을 위해 정제 이벤트를 기록하세요 */ 
    }
    
    private void SendToChat(string message) 
    { 
        /* 구현: 메시지를 채팅 시스템으로 전송하세요 */ 
    }
    
    private void ShowLoginScreen() 
    { 
        /* 구현: 사용자에게 로그인 화면을 표시하세요 */ 
    }
    
    private void ShowMuteExpiryNotification(DateTime expiryAt) 
    { 
        /* 구현: 음소거가 언제 만료되는지 표시하세요 */ 
    }
    
    private void ShowMessageBlockedNotification() 
    { 
        /* 구현: 사용자의 메시지가 차단되었음을 알리세요 */ 
    }

    void OnDestroy()
    {
        // 메모리 누수를 방지하기 위해 모든 구독자 정리
        authSubscriber?.Dispose();
        sanctionsSubscriber?.Dispose();
        sanitizationSubscriber?.Dispose();
    }
}

```

{% endcode %}

}
