지난 시간에 아래 코드를 통해 촐랑이가 TV를 보게 만들었다.
public static void main(String[] args) {
JDABuilder builder = JDABuilder.createDefault(TOKEN)
.disableCache(CacheFlag.MEMBER_OVERRIDES, CacheFlag.VOICE_STATE)
.setBulkDeleteSplittingEnabled(false)
.setActivity(Activity.watching("TV"));
builder.build();
}
Github에서 PR이 Approve되었을 때 촐랑이가 뭔가 메시지를 보낼 수 있게 만드는게 목적이다.
다음과 같은 단계를 위 목적을 달성하기 위해 다음과 같은 요구사항을 정의할 수 있겠다.
이번에는 촐랑이가 서버에 메시지를 보낼 수 있도록 구성해보자.
이제 공식문서를 보면서 촐랑이가 메시지를 보내게 해보자.
우선 메시지를 전송하기 위한 예제를 긁어서 실행해보려고했다.
public static void main(String[] args) {
JDA jda = JDABuilder.createDefault(TOKEN)
.enableIntents(GatewayIntent.MESSAGE_CONTENT) // enables explicit access to message.getContentDisplay()
.build();
//You can also add event listeners to the already built JDA instance
// Note that some events may not be received if the listener is added after calling build()
// This includes events such as the ReadyEvent
jda.addEventListener(new MyListener());
}
public class MyListener extends ListenerAdapter {
@Override
public void onMessageReceived(MessageReceivedEvent event) {
if (event.isFromType(ChannelType.PRIVATE))
{
System.out.printf("[PM] %s: %s\n", event.getAuthor().getName(),
event.getMessage().getContentDisplay());
}
else
{
System.out.printf("[%s][%s] %s: %s\n", event.getGuild().getName(),
event.getChannel().getName(), event.getMember().getEffectiveName(),
event.getMessage().getContentDisplay());
}
}
}
[JDA MainWS-WriteThread] INFO WebSocketClient - Connected to WebSocket
[JDA MainWS-WriteThread] ERROR WebSocketClient - WebSocket connection was closed and cannot be recovered due to identification issues
CloseCode[DISALLOWED_INTENTS](code=4014, meaning=Disallowed intents. Your bot might not be eligible to request a privileged intent such as GUILD_PRESENCES, MESSAGE_CONTENT, or GUILD_MEMBERS.)
위와 같이 오류가 발생한다.
대락적으로 아래와 같은 형태로 통신이 이뤄지는데 App이 discord Gateway로부터 요청을 받고, 보내는 과정에서 몇몇 권한이 필요하다.
디스코드 개발자 도구로 들어가서 다음 옵션들을 활성화시켜줘야한다.
설정 후 봇을 다시 실행하니 잘 동작하는것을 확인할 수 있다.
위 예제코드로 메시지를 수신하여 확인할 수 있다.
MyListener 클래스를 다음과 같이 수정해보자.
public class MyListener extends ListenerAdapter {
@Override
public void onMessageReceived(MessageReceivedEvent event) {
if (event.getAuthor().isBot()) {
return;
}
Message message = event.getMessage();
String content = message.getContentRaw();
if (content.contains("촐랑아 안녕") && event.getMember() != null) {
MessageChannel channel = event.getChannel();
channel.sendMessage("안녕하세요! " + event.getMember().getEffectiveName() + "님!").queue();
}
}
}
촐랑이가 잘 답장해준다. (귀여워..)
다양한 웹훅 설정이 필요하기 때문에 하나씩 차근차근 만들어보자.
디스코드에서 웹훅 채널을 추가한다.
웹후크 추가 후 웹 후크 URL을 복사한다.
https://discord.com/api/webhooks/123/WDF123_f12fs..
웹훅 URL은 대략적으로 이렇게 생겼다.
이때 payload URL은 위에서 복사한
웹 후크 URL
을 사용한다.
Github Repositoy에 들어가서 webhook 설정을 추가해준다.
설정을 완료하면 추가한 이벤트에 따라 채널에 메시지가 오는 것을 확인할 수 있다.
여기서 봇 배포 및 webhook 등록에 대한 결정에 따라 구현 방식이 결정되기 때문에 잠시 고민하는 시간을 가져본다.
Github에서는 Webhook을 이용하여 PR, Issue 등 다양한 이벤트에 대한 내용을 제공한다.
webhook을 어떤 방식으로 활용할 수 있을까?
위와 같은 흐름으로 동작하길 기대하는 방향이다.
위와 같이 리뷰를 남기면 github는 아래와 같은 payload를 전송한다.
{
"action": "submitted",
"review": {
...
"user": {
"login": "Choi-JJunho",
...
},
"body": "승인 안할건데?",
"commit_id": "ce58b92df8f608807e85f69110c6429412c1511f",
"submitted_at": "2023-12-04T07:26:21Z",
"state": "changes_requested",
...
"author_association": "OWNER",
"_links": {
...
"pull_request": {
"href": "https://api.github.com/repos/Choi-JJunho/koin_temp/pulls/5"
}
}
}
이를 활용할 경우 해당 payload를 수신하여 분석하고 동작하는 bot을 만드는 방법이 생각난다.
위와 같은 흐름으로 동작하길 기대하는 방향이다.
github webhook을 discord가 받아서 출력하는 값은 다음과 같다.
// Request Change 요청 시 discord가 출력하는 값
{
...
"d": {
...
"author": {
"bot": true,
"id": "1181107313243869225",
"avatar": "df91181b3f1cf0ef1592fbe18e0962d7",
"username": "GitHub",
"discriminator": "0000"
},
...
"embeds": [
{
"color": 16525609,
"author": {
...
"name": "Choi-JJunho",
...
},
"description": "RC 드립니다.",
"type": "rich",
"title": "[Choi-JJunho/koin_temp] Pull request review submitted: #5 Create README.md",
"url": "https://github.com/Choi-JJunho/koin_temp/pull/5#pullrequestreview-1761705005"
}
],
"channel_id": "1181125289787523072",
"timestamp": "2023-12-04T06:58:41.949000+00:00"
}
}
// Approve 시 discord가 출력하는 값
{
...
"d": {
...
"author": {
"bot": true,
"id": "1181107313243869225",
"avatar": "df91181b3f1cf0ef1592fbe18e0962d7",
"username": "GitHub",
"discriminator": "0000"
},
...
"embeds": [
{
"color": 38912,
"author": {
...
"name": "Choi-JJunho",
...
},
"description": "승인합니다.",
"type": "rich",
"title": "[Choi-JJunho/koin_temp] Pull request review submitted: #5 Create README.md",
"url": "https://github.com/Choi-JJunho/koin_temp/pull/5#pullrequestreview-1761705005"
}
],
"channel_id": "1181125289787523072",
"timestamp": "2023-12-04T06:58:41.949000+00:00"
}
}
두번 꼬아서 생각해봤을 때 discord 상에서 Github Bot이 출력하는 메시지 형태를 촐랑이가 읽고 분석해서 적절한 행동을 취하게 만들 수도 있을 것 같다.
배포를 어떻게 할까..? 고민이다.
위에서 말한 1번을 택한다면 webhook 수신에 대한 개발을 추가로 해야할 것이다.
이를 위해 Github에서 보내는 Post 요청 수신, SSL 처리 (선택) 등을 고민해봐야 할 것 같다. 또한 이 데이터를 JDA를 통해 bot이 메시지를 전송하도록 핸들링도 해야한다.
해당 방법으로 개발하기에는 모르는 우발적 요소가 많아보인다.
반대로 2번을 택한다면 메시지의 색깔(color)로 해당 메시지가 Approve임을 구분할 수 있을 것이고 이에 대한 촐랑이의 행동을 제어할 수 있을 것 같다.
추가로 배포는 어디에 할 것인지 고민되기도한다. 만약 AWS를 이용한다면 프리티어로 1년정도 운영 가능해보이긴 한다만...
뭔가 더 비용을 걱정하지 않아도되는 방법이 없을까? 고민되는 부분이다.
이 부분은 조금 더 이야기를 나눠봐야할 부분같다.
+) 이런저런 자료를 찾다보니 유튜브에 JDA 튜토리얼이 정말 잘 되어있었다.
만약 처음 시도해보는 사람들은 해당 영상을 보고 시작하면 좋을 것 같다.
https://www.youtube.com/watch?v=dOmyJhB_feM&list=PLWnw41ah3I4YxBetY8iCa-b9t1JwV2jsW&index=1
초록 스터디 화이팅!