서버에서 채팅방으로 알림 보내기

내 서버에서 서버 API(v2)로 채팅방 채널에 데이터를 보내고, 페이지 스크립트나 플러그인이 서버가 보낸 것만 골라 표시하는 흐름을 설명해요.

마지막 수정 2026년 10월 19일

이 페이지

내 서버에서 일어난 일(결제 완료, 새 글, 방송 시작 등)을 서버 API로 채팅방 채널에 보내면, 페이지 스크립트가 받아 채팅방에 표시할 수 있어요. 요청 형식과 오류 코드 전체는 서버 REST API에 있어요.

코드를 쓰지 않고 띄우기만 하려면 이벤트 알림창 플러그인을 켜고 plugin을 alertBox로 보내면 돼요. 글 등록·후원·구독 알림을 채팅 목록 안에 색 칸으로 보여 줘요. 후원 목표·방송 상태·점수판·카운트다운·순위표 플러그인도 같은 방식이에요.

흐름

  1. 페이지 스크립트(또는 플러그인)가 채팅방에서 채널(예: notice-bot)을 열고 기다려요.
  2. 내 서버가 POST https://api.uchat.io/v2/rooms/{id}/events로 {"plugin":"notice-bot","data":[...]}를 보내요.
  3. 채팅방에 지금 접속한 사람들이 그 채널로 데이터를 받아요. 보낸 사람은 auth가 4인 서버 사용자예요.
  4. 페이지 스크립트가 auth를 확인하고 화면에 표시해요.

그냥 보내면 지금 접속한 사람에게만 가요. 아무도 없으면 받을 사람이 없을 뿐 오류는 아니에요. 나중에 들어온 사람에게도 보여야 하면 "save": true로 저장해요(아래 나중에 들어온 사람에게도).

API 키

관리 페이지 API 메뉴에서 API 키 발급을 눌러요. 이름을 정하고 권한에서 이벤트를 켜 두면 돼요. 키(uchat_…)는 발급할 때 한 번만 보이니 바로 복사해 둬요. 같은 화면에서 주소에 넣을 API 채팅방 아이디(room_…)도 복사해요.

API 키는 내 서버에만 둬요. 브라우저 자바스크립트에서 서버 API를 부르면 키가 드러나 누구나 서버 사용자로 데이터를 보낼 수 있어요. 키가 새면 API 메뉴에서 바로 폐기하거나 값을 다시 발급해요.

1. 받는 쪽 준비

<script>U=window.U=window.U||{},U.events=U.events||[],U.chat=function(n){return{on:function(e,t){U.events.push([n,e,t])},off:function(e){for(var t=U.events.length;t>0;)U.events[--t][0]==n&&U.events[t][1]==e&&U.events.splice(t,1)}}};</script>
<script async src="https://client.uchat.io/uchat.js"></script>
<u-chat room="my-room" style="display:inline-block; width:100%; max-width:500px; height:500px;"></u-chat>
<script>
function escapeHtml(text) {
	return String(text).replace(/[&<>"']/g, function (c) {
		return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
	});
}

U.chat('my-room').on('after.create', function (room) {
	room.plugin.add('notice-bot').onReceived(function (room, msg) {
		if (!msg.user || msg.user.auth !== 4) return; // 서버 API 또는 저장값만
		if (msg.type !== 0) return; // 서버 API로 모두에게 보낸 것만
		if (typeof msg.data[0] !== 'string') return;
		room.print('[알림] ' + escapeHtml(msg.data[0]));
	});
});
</script>
  • 채팅방 사람들도 같은 채널 이름으로 데이터를 보낼 수 있어요. 서버가 보낸 것만 믿으려면 msg.user.auth === 4를 확인해요. auth 4는 서버 API로 보낸 데이터 또는 부관리자 이상이 저장한 값이에요. 저장값은 입장할 때 type 1로 오므로, 모두에게 보낸 서버 API 데이터(type 0)만 받으려면 msg.type === 0도 확인해요. 닉네임을 지정해 보낸 서버 API 데이터도 type 1이라 저장값과 구분할 수 없어요. 서버 사용자는 닉네임이 없으므로 닉네임으로 확인하지 마세요.
  • room.print는 HTML로 해석하므로 받은 글자는 이스케이프해서 넣어요.

2. 서버에서 보내기

curl:

curl -X POST https://api.uchat.io/v2/rooms/room_xxxxxxxxxxxxxxxx/events \
  -H "Authorization: Bearer uchat_..." \
  -H "Content-Type: application/json" \
  -d '{"plugin":"notice-bot","data":["주문 #1024 결제가 완료되었습니다",12000]}'
  • data는 값 배열이에요. 문자열·숫자·불리언을 쓰고, 받는 쪽에는 모두 문자열로 가요.
  • 성공하면 HTTP 202와 {"data":{"sent":true}}, 실패하면 HTTP 상태와 {"error":{"code":…,"message":…}}가 와요.
  • 보내기 전에 API 메뉴의 시험하기에서 같은 본문으로 실행해 볼 수 있어요.

Node.js(18 이상):

const ROOM = 'room_xxxxxxxxxxxxxxxx';

async function sendToRoom(plugin, data, options = {}) {
	const res = await fetch(`https://api.uchat.io/v2/rooms/${ROOM}/events`, {
		method: 'POST',
		headers: {
			Authorization: `Bearer ${process.env.UCHAT_API_KEY}`,
			'Content-Type': 'application/json'
		},
		body: JSON.stringify({ plugin, data, ...options })
	});
	const result = await res.json();
	if (!res.ok) console.warn('uchat api error', res.status, result.error);
	return result;
}

await sendToRoom('notice-bot', ['주문 #1024 결제가 완료되었습니다', 12000]);

PHP:

<?php
function uchat_send($plugin, array $data, array $options = []) {
	$ch = curl_init('https://api.uchat.io/v2/rooms/room_xxxxxxxxxxxxxxxx/events');
	curl_setopt_array($ch, [
		CURLOPT_POST => true,
		CURLOPT_HTTPHEADER => [
			'Authorization: Bearer ' . getenv('UCHAT_API_KEY'),
			'Content-Type: application/json',
		],
		CURLOPT_POSTFIELDS => json_encode(['plugin' => $plugin, 'data' => $data] + $options),
		CURLOPT_RETURNTRANSFER => true,
	]);
	$result = json_decode(curl_exec($ch), true);
	curl_close($ch);
	return $result;
}

uchat_send('notice-bot', ['주문 #1024 결제가 완료되었습니다', 12000]);

한 사람에게만 보내기

본문에 "to"로 닉네임을 넣으면 그 사람에게만 보내요. 받는 쪽 msg.type은 1이에요. 한글 닉네임도 그대로 쓸 수 있어요.

curl -X POST https://api.uchat.io/v2/rooms/room_xxxxxxxxxxxxxxxx/events \
  -H "Authorization: Bearer uchat_..." \
  -H "Content-Type: application/json" \
  -d '{"plugin":"notice-bot","to":"민지","data":["민지님, 쿠폰이 발급되었습니다"]}'

그 닉네임이 지금 채팅방에 없으면 HTTP 404 target_not_found가 와요.

나중에 들어온 사람에게도

"save": true를 붙이면 그 채널의 마지막 값으로 저장돼요. 지금 있는 사람에게 보내고, 나중에 들어오는 사람은 입장할 때 받아요(msg.type 1). 채팅방에 아무도 없을 때 보내도 저장돼요.

curl -X POST https://api.uchat.io/v2/rooms/room_xxxxxxxxxxxxxxxx/events \
  -H "Authorization: Bearer uchat_..." \
  -H "Content-Type: application/json" \
  -d '{"plugin":"notice-bot","save":true,"data":["오늘 밤 12시 점검이 있어요"]}'
  • 지우려면 "data":[]로 저장해요. 받는 쪽에는 빈 값이 가요.
  • 한도는 채널 저장과 같아요(무료 채팅방은 채널 하나·1KB). → 채널 API와 한도
  • 저장값은 채팅방이 비거나 서버가 다시 시작돼도 남아요.
  • 위 받는 쪽 예제는 msg.type !== 0을 버리므로, 저장값까지 받으려면 그 줄을 빼요.

자주 나는 오류

오류 뜻 할 일
401 missing_key, invalid_key 키가 없거나 이 채팅방의 키가 아님 Authorization: Bearer 헤더와 API 채팅방 아이디를 확인해요. 회원 연동 토큰이 아니라 API 키를 넣어요
403 insufficient_scope 키에 이벤트 권한이 없음 API 메뉴에서 그 키의 권한을 고쳐요
400 invalid_data data가 배열이 아니거나 줄바꿈 같은 제어 문자가 있음 [...] 모양으로, 줄바꿈 없이 보내요
404 target_not_found to의 닉네임이 채팅방에 없음 닉네임을 확인해요
429 rate_limited, chat_rate_limited 호출·채널 전송 한도 초과 보내는 횟수를 줄여요. → 서버 REST API

요청 본문 앞부분과 요청 IP는 API 메뉴의 호출 기록에 30일 동안 남아요. 개인정보나 결제 정보는 보내지 말고, 표시할 문구만 보내세요. 완성된 예제는 결제 완료 알림에 있어요. 예전 v1 방식(/rooms/{채팅방}/plugin/...)은 서버 REST API에 정리해 두었어요.

봐도 잘 이해가 되지 않나요? 문의 게시판에 질문을 남겨 주세요.

상호 UCHAT · 대표 김경욱 · 사업자등록번호 141-05-32832
사업장소재지 경기도 파주시 와석순환로 61 · 통신판매업신고번호 2013-경기파주-4485호
대표번호 010-8677-8633 · 이메일 support@uchat.io

ⓒ 2013–2026 UCHAT. All rights reserved.