Java Discord WebHook 사용

Minu·2023년 10월 15일
1

Discord Webhook

목록 보기
1/1

팀원들과 프로젝트를 하던도중 서버에서 500 에러 즉, 서버 내 오류가 아닌 예상하지 못한 오류가 발생하면 Discord 에 해당 오류 내용을 프로젝트 팀 Discord 에 오류 로그를 보내는 기능을 구현하기로 했는데 생각보다 구현하기가 간단하고 나중에 사용하기에도 유용할 것 같아서 기록하기로 했습니다.

| 실제 사용 결과

오류 발생

로컬 서버 테스트

(실제 서버 오류 발생 시 디스코드 채팅)

이런식으로 오류 메세지를 확인 할 수 있음


우선 하기전에 참고

Discord 채널 Webhook url

Discord Webhook JSON 예제

Discord Webhook Class


순수 JAVA만 사용해서 간단하게 보내는 예제

1. DiscordWebhook 클래스 설명

/**
 * Class used to execute Discord Webhooks with low effort
 */
public class DiscordWebHook {

    private final String url;
    private String content;
    private String username;
    private String avatarUrl;
    private boolean tts;
    private List<EmbedObject> embeds = new ArrayList<>();
	
    /**
		나머지 코드...
	**/

해당 클래스 생성자를 보면

 public DiscordWebHook(String url) {
        this.url = url;
    }

url 에 우리 채널의 webhook url 을 넣어주면

public void execute() throws IOException {
 // 다른 코드들...
    	URL url = new URL(this.url);
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.addRequestProperty("Content-Type", "application/json");
        connection.addRequestProperty("User-Agent", "Java-DiscordWebhook-BY-Gelox_");
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");

        OutputStream stream = connection.getOutputStream();
        stream.write(json.toString().getBytes());
        stream.flush();
        stream.close();

        connection.getInputStream().close(); //I'm not sure why but it doesn't work without getting the InputStream
        connection.disconnect();
        }

POST 형식으로 요청을 보내는 걸 알 수 있고

public void execute() throws IOException {


        JSONObject json = new JSONObject();

		// 필드 값
        json.put("content", this.content);
        json.put("username", this.username);
        json.put("avatar_url", this.avatarUrl);
        json.put("tts", this.tts);
         
         // inncer class 인 embeds 클래스 (추후 설명)
          if (!this.embeds.isEmpty()) {
            List<JSONObject> embedObjects = new ArrayList<>();

            for (EmbedObject embed : this.embeds) {
                JSONObject jsonEmbed = new JSONObject();

                jsonEmbed.put("title", embed.getTitle());
                jsonEmbed.put("description", embed.getDescription());
                jsonEmbed.put("url", embed.getUrl());
		}
	}
}

execute() 메서드를 사용하면 JSON 형태로 우리가 Setter 로 설정한 필드 값들을 JSON으로 변환하는 것을 확인 할 수 있다.

즉 사용자는 DiscordWebHook 클래스를 사용할 때 생성자에 우리 채널 웹훅 url 을 넣고, setter 를 사용해 원하는 값들을 설정한다음에 execute() 메서드를 사용하면 끝!


1-1 embeds 객체 사용하지 않고 기본 필드값들만 사용할 때

기본 필드값으로

    private final String url;
    private String content;
    private String username;
    private String avatarUrl;
    private boolean tts;
    

해당 값들이 있는데 우선 embeds 객체를 사용하지않고 해당 값들로만 사용해서 메세지를 보내보자

public class DiscordResponseMessage {

    private static final String discordUrl = "https://discord.com/api/webhooks/디스코드 channel webhook url";


    public static void main(String[] args) {
        send();
    }
   public static void sendMessage(){
               DiscordWebHook webhook = new DiscordWebHook(discordUrl);
            webhook.setUsername("봇 닉네임");
            // webhook.setTts(true);  // 음성 출력 사용할 것인지
            webhook.setContent("메세지 내용");
            webhook.setAvatarUrl("https://i.imgur.com/oBPXx0D.png"); // 이미지 설정 안해줘도 됨
        try {
            webhook.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

1-1 결과

벌써 끝이다.

하지만 embed 객체를 사용하면 좀 더 멋있게 꾸밀 수 있다.


1-2 embeds 객체 사용

public class DiscordWebHook {

    private final String url;
    private String content;
    private String username;
    private String avatarUrl;
    private boolean tts;
    private List<EmbedObject> embeds = new ArrayList<>();
    
     public void addEmbed(EmbedObject embed) {
        this.embeds.add(embed);
    }
    
     public static class EmbedObject {

        private String title;
        private String description;
        private String url;
        private Color color;

        private Footer footer;
        private Thumbnail thumbnail;
        private Image image;
        private Author author;
        private List<Field> fields = new ArrayList<>();

		// getters,setters...
        }
}

embeds 객체를 사용하기 위해선

  public void addEmbed(EmbedObject embed) {
        this.embeds.add(embed);
    }

addEmbed 메소드에 EmbedObject 객체를 넣으면 된다.
간단하게 몇개의 필드만 설정한 예시코드를 보면 금방 알 수 있다.

public class DiscordResponseMessage {

    private static final String discordUrl = "https://discord.com/api/webhooks/디코 채널 Url";


    public static void main(String[] args) {
        sendMessage();
    }
    public static void sendMessage(){
        DiscordWebHook webhook = new DiscordWebHook(discordUrl);

        webhook.setUsername("디스코드 봇");
        webhook.setAvatarUrl("https://i.imgur.com/oBPXx0D.png");
        webhook.addEmbed(
            new EmbedObject()
                .setTitle("title")
                .setDescription("description")
                .setColor(Color.RED)
                .addField("Field1", "value1", false)
                .addField("Field1", "value2", true)
        );
        try {
            webhook.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

addEmbed 메소드에 EmbedObject 객체를 생성하여 setter 메소드를 사용 해 해당 값들을 설정해 줬다.

1-2 embeds 객체 사용 결과


1-3 embeds 객체 사용 및 더 꾸미기


 public static void main(String[] args) {
        sendDetailMessage();
    }
    
  public static void sendDetailMessage() {
        try {
            DiscordWebHook webhook = new DiscordWebHook(discordUrl);

            webhook.setUsername("디스코드 봇2");

            // Embed 객체 생성
            DiscordWebHook.EmbedObject embed = new DiscordWebHook.EmbedObject()
                .setAuthor("난 새벽에 왜 이걸 하고있는거지", "https://velog.io/@minu1117", "https://i.imgur.com/oBPXx0D.png") // 작성자,링크,이미지
                .setTitle("제목")
                .setDescription("설명 부분 [Markdown](https://velog.io/@minu1117/)!") // []를 사용하면 링크 설정 가능
                .setColor(Color.GREEN)
                .setFooter("여기는 footer 입니다 ", "https://i.imgur.com/Hv0xNBm.jpeg") //  푸터
                .setThumbnail("https://i.imgur.com/oBPXx0D.png") //  썸네일 이미지
                .setImage("https://i.imgur.com/8nLFCVP.png") //  메인 이미지
                .addField("인라인필드 true (Inline)", "인라인필드 true value (Inline)", true) // 인라인 필드 추가
                .addField("Field Name", "Field Value", false); // 일반 필드 추가

            // Embed 추가
            webhook.addEmbed(embed);

            webhook.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

결과

링크도 가능하고 사진도 여기저기 붙일 수 있고 나름 쓸만한 것 같다.


전체코드

package com.example.discordwebhook.discord;

import com.example.discordwebhook.discord.DiscordWebHook.EmbedObject;
import java.awt.Color;
import java.io.IOException;

public class DiscordResponseMessage {

    private static final String discordUrl = "https://discord.com/api/webhooks/디스코드 채널 웹훅 Url";


    public static void main(String[] args) {
        sendMessage();4
        sendDetailMessage();
    }
    public static void sendMessage(){
        DiscordWebHook webhook = new DiscordWebHook(discordUrl);

        webhook.setUsername("디스코드 봇");
        webhook.setAvatarUrl("https://i.imgur.com/oBPXx0D.png");
        webhook.addEmbed(
            new EmbedObject()
                .setTitle("title")
                .setDescription("description")
                .setColor(Color.RED)
                .addField("Field1", "value1", false)
                .addField("Field1", "value2", true)
        );
        try {
            webhook.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void sendDetailMessage() {
        try {
            DiscordWebHook webhook = new DiscordWebHook(discordUrl);

            webhook.setUsername("디스코드 봇2");

            // Embed 객체 생성
            DiscordWebHook.EmbedObject embed = new DiscordWebHook.EmbedObject()
                .setAuthor("난 새벽에 왜 이걸 하고있는거지", "https://velog.io/@minu1117", "https://i.imgur.com/oBPXx0D.png") // 작성자,링크,이미지
                .setTitle("제목")
                .setDescription("설명 부분 [Markdown](https://velog.io/@minu1117/)!") // []를 사용하면 링크 설정 가능
                .setColor(Color.GREEN)
                .setFooter("여기는 footer 입니다 ", "https://i.imgur.com/Hv0xNBm.jpeg") //  푸터
                .setThumbnail("https://i.imgur.com/oBPXx0D.png") //  썸네일 이미지
                .setImage("https://i.imgur.com/8nLFCVP.png") //  메인 이미지
                .addField("인라인필드 true (Inline)", "인라인필드 true value (Inline)", true) // 인라인 필드 추가
                .addField("Field Name", "Field Value", false); // 일반 필드 추가

            // Embed 추가
            webhook.addEmbed(embed);

            webhook.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

0개의 댓글