본문 바로가기

Dev Log

채널톡 연동 과정 정리

728x90

사이드 프로젝트에서 재무 설계 관련 채팅 기능에 대한 수요가 있는지 검증하기 위해 채널톡을 연동해보기로 했다. 이번 글에서는 연동 과정에서 헷갈렸던 개념들과 실제 개발 단계에서 고려했던 부분들을 정리했다.

 

개발 과정에서의 요구사항은 비교적 단순했다.(항상 시작은 자신만만^_^ 변수는 존재하기 마련,,,)

  1. 사용자가 푸시 알림을 클릭했을 때 채널톡 대화 페이지로 이동한다.
  2. 채널톡 메시지를 일정 이상 주고받았을 때 자동으로 종료시킨다.

이를 위해 다음과 같은 작업(Task)을 정의했다.

  1. 푸시 알림 클릭 시 페이지 이동 (API 통신을 통한 이동 로직 구현)
  2. SDK 세팅 (설치, 코드 셋업, 동작 테스트)
  3. 채팅 액션 처리 (시작, 종료, 메시지 입력 API 연동)
  4. 채널톡 서비스 이용 시 오류 처리 및 대응

1️⃣ 연동

채널톡 연동은 생각보다 간단했다.

채널톡 페이지에 제공되는 JavaScript 스니펫을 삽입하고 실행하면 자동으로 채팅방이 생성되고, 화면에 채팅룸이 노출된다.

아래 코드는 채팅 초기 세팅 로직이다.

loadScript 함수는 initChannelTalk 내부의 즉시 실행 함수(IIFE) 안에서 호출되어, 페이지 로드 시 자동으로 실행되도록 구성되어있다.

      function loadScript() {
        if (w.ChannelIOInitialized) return;
        w.ChannelIOInitialized = true;
  
        const s = document.createElement("script");
        s.type = "text/javascript";
        s.async = true;
        s.src = "<https://cdn.channel.io/plugin/ch-plugin-web.js>";
        const x = document.getElementsByTagName("script")[0];
        x?.parentNode?.insertBefore(s, x);
      }
  
      if (document.readyState === "complete") loadScript();
      else {
        window.addEventListener("DOMContentLoaded", loadScript);
        window.addEventListener("load", loadScript);
      }

초기화 시에는 pluginKey를 지정하고, 사용자 구분을 위한 userId, name, email을 전달한다. 채널톡에서는 MemberId라는 고유 식별자를 별도로 관리하고 있어서, 이를 서비스의 userId로 대체할 수는 없었고 추가해야했다.

    window.ChannelIO?.("boot", {
      pluginKey: process.env.NEXT_PUBLIC_CHANNEL_PLUGIN_KEY, 
      profile: {
        userId: user.userId,
        name: user.name,
        email: user.email,
      },
    });

2. 푸시 알림 클릭 시 페이지 이동

리엑트 네이티브에서 푸시 메세지를 불러오는 것은 아래 messaging이라는 메서드를 통해 구현이 가능했다.

React Native 단에서는 푸시 메시지 전체 payload를 웹뷰 브릿지를 통해 웹으로 전달하도록 구현했다.

이때 인증 상태에 따라 분기 처리가 필요했다.

  • 자동 로그인이 되어 있는 사용자는 바로 채팅방으로 이동하고,
  • 그렇지 않은 사용자는 로그인 페이지로 이동하도록 했다.

푸시 메시지를 가져오는 부분은 Firebase의 messaging() 메서드를 사용했다.

import messaging from '@react-native-firebase/messaging';

export const getNotificationPayload = async() => {
  const message = await messaging().getInitialNotification();
  if(!message) return null;
 
  return message;
}

//실제 출력했을 때 메세지
{
  "message": {
    "messageId": 123,
    "data": {
      "url": "www.service.io/",
      "key2": "VALUE2"
    },
    "notification": {
      "title": "VDUS"
    },
    "from": "1231"
  }
}

3️⃣ 채팅방 상태 전송

처음에는 채팅 생성 및 종료 시점에 백엔드로 채팅 정보를 전송하는 API를 직접 개발하려고 했다. 하지만 채널톡 공식 문서를 살펴보니 웹훅(Webhook) 기능을 이용하면 동일한 동작을 구현할 수 있었다. API를 직접 붙이는 것도 어렵진 않았지만, 채널톡의 내장 기능을 활용하는 것이 훨씬 빠르고 효율적이라고 판단했다. 푸시 알림을 보낼 때는 기존 채팅룸 ID를 함께 전달하여, 클릭 시 바로 해당 채팅방으로 진입할 수 있도록 했다.

🧠 개념 정리

✅ 웹훅(Webhook)

채팅이 생성되거나 종료될 때 POST 요청으로 채팅 정보를 외부 서버에 전달할 수 있는 기능이다.

이를 활용하면 서버에서 별도의 폴링 없이 채팅 이벤트를 실시간으로 감지할 수 있다.

✅ 워크플로우(Workflow)

채널톡에서 제공하는 자동화 기능으로,

예를 들어 “사용자가 채팅을 시작했을 때”, “특정 메시지를 입력했을 때” 등의 조건에 따라 특정 액션을 트리거할 수 있다.

✅ 태스크(Tasks)

워크플로우 안에서 특정 조건에 맞는 코드 실행 단위를 의미한다.

예를 들어 사용자가 특정 단어를 입력하면, 자동으로 서버에 POST 요청을 보내는 로직을 작성할 수 있다.

아래는 실제 태스크 코드 예시이다.

export const handler = async (memory, context) => {
	try {
	    console.log("triggered");
	    const user = context.user;
	    const userChat = context.userChat;
	
	    const payload = {
	      userId: user.id,
	      userName: user.name,
	      channelId: user.channelId,
	      chatId: userChat.id,
	      chatState: userChat.state,
	      chatDescription: userChat.description,
	      country: user.country,
	      language: user.language,
	      tags: user.tags,
	      timestamp: new Date().toISOString(),
	    };
			
			//POST API 추가
	
	    console.log("✅ Data sent successfully:", response.status);
	    console.log("📦 Payload:", payload);
	
	    return { success: true };
	  } catch (error) {
	    console.log("❌ Failed to send data:", error.message);
	    return { success: false, error: error.message };
	  }
}

마무리

채널톡은 SDK를 통해 빠르게 채팅 기능을 붙일 수 있을 뿐 아니라, Webhook과 Workflow를 활용하면 별도 서버 개발 없이도 이벤트 기반 처리를 유연하게 구성할 수 있다. 엄청 세분화된 기능들을 제공하고 있어 다양한 사용자 행동 기반 테스트를 구성할 수 있을 것 같다.

728x90