Java Github Api와 Gist를 이용한 Steam 뉴스 갱신 및 메일링

김효민·2021년 2월 2일
0

구현한 코드 전체는 여기에서 볼 수 있습니다.

저번 글에 이어서 코딩하면서 고려한 점을 적어보겠습니다.

3. Steam 뉴스 갱신 확인

3-1. Gist를 이용한 Steam 뉴스 저장

Steam 뉴스를 받아올 수 있게 되었습니다. 하지만 새로운 뉴스가 나올 때마다 확인하려면 최근에 봤던 뉴스를 어딘가에 저장해 놓고 하루에 한번 최근 뉴스와 저장해 놓은 뉴스를 비교해야 합니다.
그러기 위해선 저장해 놓을 공간이 필요한데 저는 github gist를 활용하여 비교하려 합니다.

당연하겠지만 Steam News에는 뉴스마다 고유 id가 있습니다. 저는 게임마다 최근 뉴스의 id를 JSON형식으로 github gist에 저장해놓았습니다. 아래는 그 예시입니다.

{"362490":"2978509755343068871","394360":"4050393736334203613","590380":"3887130640396430298","457140":"4050393736339017538"}

3-2. Java Github Api를 이용한 gist 업데이트

github api를 이용해서 gist에 올린 JSON파일을 비교하고 갱신하는 코드를 작성했습니다.

// https://github.com/hyoputer/steam-follow-game-newsletter/blob/master/src/main/java/me/hyoputer/GithubClient.java
public class GithubClient {

    private GitHub gitHub;

    public GithubClient(String accessToken) throws IOException {
        gitHub = GitHub.connectUsingOAuth(accessToken);
    }

    public String getGistId(String description) throws IOException {

        GHGist[] gists = gitHub.getMyself().listGists().toArray();

        for (GHGist gist : gists) {
            if (gist.getDescription().equals(description)) {
                return gist.getGistId();
            }
        }

        return null;
    }

    public JsonObject getGistContent(String id, String fileName) throws JsonSyntaxException, IOException {

        GHGist targetGist = gitHub.getGist(id);
        return JsonParser.parseString(targetGist.getFile(fileName).getContent()).getAsJsonObject();
    }

    public void updateGist(String id, String fileName, JsonObject content) throws IOException {
        
        gitHub.getGist(id).update().updateFile(fileName, content.toString()).update();
    }
    
}
  • accessToken을 이용해서 로그인을 하려면 github 공식 문서를 참조해주세요.
  • github.getMyself 메소드를 통해야만 본인의 계정에 접속 가능합니다.
  • listGist메소드의 리턴 값에는 contents가 없으니 원하는 gist의 id를 찾아서 getGist 메소드를 불러야 합니다.
  • gist의 description을 이용해서 해당 gist를 찾았습니다.

4. 메일 보내기

이 블로그를 참조해서 Java로 메일을 보내는 코드를 작성 했습니다.

// https://github.com/hyoputer/steam-follow-game-newsletter/blob/master/src/main/java/me/hyoputer/Mail.java
public class Mail {

    private String EMAIL_ID;
    private String EMAIL_PASSWORD;

    private static final String SMTP_SERVER = "smtp.gmail.com";
    private static final int SMTP_PORT = 465;

    public Mail(String id, String password) {
        EMAIL_ID = id;
        EMAIL_PASSWORD = password;
    }

    public void sendMail(String title, String content) {
        
        Properties prop = new Properties();
        prop.put("mail.smtp.host", SMTP_SERVER); 
        prop.put("mail.smtp.port", SMTP_PORT); 
        prop.put("mail.smtp.auth", "true"); 
        prop.put("mail.smtp.ssl.enable", "true"); 
        prop.put("mail.smtp.ssl.trust", SMTP_SERVER);
        
        Session session = Session.getDefaultInstance(prop, new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(EMAIL_ID, EMAIL_PASSWORD);
            }
        });

        try {
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(EMAIL_ID));

            //수신자메일주소
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(EMAIL_ID)); 

            // Subject
            message.setSubject(title); //메일 제목을 입력

            // Text
            message.setText(content);    //메일 내용을 입력

            // send the message
            Transport.send(message); ////전송
        } catch (AddressException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

}

5. 메인 함수 작성

지금까지 작성한 class들을 이용하여 Steam 뉴스를 확인하고 갱신하고 메일링까지 해주는 프로그램을 작성했습니다.

public class SteamFollowedGameNewsLetter {
    public static void main(String[] args) throws Exception {

        Steam steamClient = new Steam(Configs.STEAM_USER_ID);
        GithubClient githubClient = new GithubClient(Configs.GIST_ACCESS_KEY);
        Mail mailClient = new Mail(Configs.EMAIL_ID, Configs.EMAIL_PASSWORD);

        //get AppIds by parsing html
        List<String> appIds = steamClient.getFollowedAppIds();

        String gistId = githubClient.getGistId(Configs.GIST_DESCRIPTION);

        if (gistId != null) {

            JsonObject gistContent = githubClient.getGistContent(gistId, Configs.GIST_FILE_NAME);
            JsonObject newGistContent = new JsonObject();

            appIds.forEach(appId -> {
                try {

                    JsonObject appNews = steamClient.getAppNews(appId);
                    String newsIdLatest = appNews.get("gid").getAsString();

                    JsonElement newsIdInGist = gistContent.get(appId);

                    if (newsIdInGist == null || !(newsIdInGist.getAsString().equals(newsIdLatest))) {
                        // System.out.println(appNews.get("title").getAsString() + " not equal! " + appNews.get("url")
                        //         .getAsString());
                        mailClient.sendMail(appNews.get("title").getAsString(), appNews.get("url").getAsString());
                    }
                    
                    newGistContent.addProperty(appId, newsIdLatest);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            
            if (!gistContent.equals(newGistContent))
                githubClient.updateGist(gistId, Configs.GIST_FILE_NAME, newGistContent);
        }
    }
}
  • 개인정보들은 linux의 환경변수에 등록시키고 Configs 클래스에서 불러옵니다.
  • gist에 들어있는 뉴스의 ID와 최근 뉴스의 ID와 비교해서 만약에 새로운 뉴스가 나왔으면 해당 뉴스만 메일로 보내줍니다.

다음 게시물에는 github actions를 이용하여 이 프로그램을 주기적으로 실행시켜 보겠습니다.

Reference

Creating a personal access token
자바 SMTP와 Mail 발송하기
앱 비밀번호 사용하기

profile
귀찮음에 민감한 개발자

0개의 댓글