롤플레잉 서버에서 신고 접수 시 자동으로 경찰/소방 역할을 호출하고 전용 티켓 채널을 생성해 처리하는 방법을 정리한다. 이 글에서는 요구사항, 발생 원인, 그리고 Discord 봇(디스코드 봇) 기반으로 티켓 시스템을 구현하는 단계별 절차와 호스팅(디스호스트 포함) 운영 팁을 다룬다.
증상
사용자가 RP 신고를 제출하면 해당 신고에 맞는 역할(예: 경찰, 소방)을 자동으로 멘션하고, 신고자와 담당자만 접근 가능한 전용 채널(티켓)을 생성해 대화·처리를 진행하고자 한다. 수동 멘션·관리로는 속도와 개인정보 관리에 한계가 있다.
원인
이런 기능이 필요한 이유는 다음과 같다.
- 공개 채널에서 모든 신고를 처리하면 개인정보 노출 및 노이즈가 발생한다.
- 담당 역할에게만 알림을 보내고, 별도 채널에서 증거·대응 기록을 남겨야 추적이 쉽다.
- Discord 권한 모델과 API 제약(채널 생성·권한 덮어쓰기 필요, 역할 멘션 권한 등)을 잘 설정하지 않으면 자동화가 불가능하거나 알림이 누락된다.
해결 방법
1단계: 봇 준비 및 권한 설정
- 디스코드 애플리케이션 생성, Bot 토큰 확보.
- OAuth 스코프:
bot+applications.commands. - 필요한 권한:
Manage Channels,Send Messages,View Channels,Manage Messages(옵션),Mention Everyone(역할 멘션 권한 설정 시 필요할 수 있음). - 역할 멘션을 허용하려면 서버 설정에서 해당 역할의 멘션 권한 허용 또는 봇에게
Mention Everyone권한 부여 고려.
예시 초대 URL 템플릿: https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&permissions=MANAGER_PERMISSIONS&scope=applications.commands%20bot
2단계: 기본 티켓 생성 로직 (discord.js v14 예시)
아래 코드는 슬래시 커맨드 /report를 사용해 티켓 채널을 만들고, 신고자와 지정 역할만 접근하도록 권한을 설정한 뒤 역할을 멘션하는 최소 구현 예시다.
// Node.js + discord.js v14
const { Client, GatewayIntentBits, PermissionsBitField } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] });
client.once('ready', () => console.log('Ready'));
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'report') {
const type = interaction.options.getString('type'); // 'police' or 'fire'
const reason = interaction.options.getString('reason') || '신고 접수';
const guild = interaction.guild;
const reporter = interaction.user;
// 역할 ID를 설정(서버별로 바꿀 것)
const ROLE_IDS = { police: 'ROLE_ID_POLICE', fire: 'ROLE_ID_FIRE' };
const roleId = ROLE_IDS[type];
if (!roleId) return interaction.reply({ content: '유효한 신고 유형이 아닙니다.', ephemeral: true });
const category = guild.channels.cache.find(c => c.name === 'Tickets' && c.type === 4); // 카테고리
const channel = await guild.channels.create({
name: `ticket-${reporter.username.toLowerCase()}`,
type: 0, // GUILD_TEXT
parent: category ? category.id : undefined,
permissionOverwrites: [
{ id: guild.roles.everyone.id, deny: [PermissionsBitField.Flags.ViewChannel] },
{ id: reporter.id, allow: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages] },
{ id: roleId, allow: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages] },
],
});
await channel.send({ content: `<@&${roleId}> 신고 접수: ${reason}\n신고자: <@${reporter.id}>` });
await interaction.reply({ content: `티켓 생성됨: ${channel}`, ephemeral: true });
}
});
client.login(process.env.BOT_TOKEN);
- 서버별로
ROLE_ID와 카테고리 이름을 설정해야 한다. - 멘션이 작동하지 않으면 서버 설정에서 해당 역할의 멘션 허용을 확인한다.
3단계: 데이터 추적 및 동시성 처리
- 티켓 ID, 채널 ID, 상태(open/closed), 생성자 등을 DB에 저장. 간단한 구현은 SQLite, 규모가 크면 PostgreSQL 사용.
- 여러 신고 동시 처리 시 동일 사용자 중복 티켓 생성 방지 로직 필요(예: 열려있는 티켓 체크).
- 티켓 종료 시 권한 롤백 및 로그 채널에 처리 기록 저장.
예시 DB 스키마(간단):
tickets(id INTEGER PRIMARY KEY, guild_id TEXT, channel_id TEXT, user_id TEXT, role TEXT, status TEXT, created_at DATETIME)
4단계: 기존 앱 활용 또는 커스텀 선택
- 이미 검증된 티켓 봇(예: Ticket Tool 등)을 사용하면 설정으로 빠르게 도입 가능하다.
- 자체 구현은 커스터마이징(역할 자동분배, 증거 첨부 처리, 신고 분류 등)에 유리하다.
5단계: 호스팅(디스호스트 포함) 및 운영
- 디스호스트에서 Node.js 앱으로 배포 가능. 환경변수로
BOT_TOKEN관리. - 프로세스 매니저(PM2) 또는 Docker 사용 권장. 예시 Dockerfile:
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
CMD ["node", "index.js"]
- 로그·모니터링, 자동 재시작 설정, 정기 백업(DB) 구성.
마무리
신고 접수 자동화는 역할 멘션과 채널 권한 제어가 핵심이다. 기존 티켓 앱을 활용하거나 위 절차대로 커스텀 디스코드 봇을 구현해 디스코드 서버 운영을 효율화하고, 디스호스트 같은 호스팅으로 안정적으로 배포·운영하라.