구현한 코드 전체는 여기에서 볼 수 있습니다.
저번 글에 이어서 코딩하면서 고려한 점을 적어보겠습니다.
Steam 뉴스를 받아올 수 있게 되었습니다. 하지만 새로운 뉴스가 나올 때마다 확인하려면 최근에 봤던 뉴스를 어딘가에 저장해 놓고 하루에 한번 최근 뉴스와 저장해 놓은 뉴스를 비교해야 합니다.
그러기 위해선 저장해 놓을 공간이 필요한데 저는 github gist를 활용하여 비교하려 합니다.
당연하겠지만 Steam News에는 뉴스마다 고유 id가 있습니다. 저는 게임마다 최근 뉴스의 id를 JSON형식으로 github gist에 저장해놓았습니다. 아래는 그 예시입니다.
{"362490":"2978509755343068871","394360":"4050393736334203613","590380":"3887130640396430298","457140":"4050393736339017538"}
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();
}
}
이 블로그를 참조해서 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();
}
}
}
지금까지 작성한 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);
}
}
}
다음 게시물에는 github actions를 이용하여 이 프로그램을 주기적으로 실행시켜 보겠습니다.
Creating a personal access token
자바 SMTP와 Mail 발송하기
앱 비밀번호 사용하기