개발 블로그
← 블로그 목록

Google Calendar API + 음력 생일 자동 등록 시스템 만들기


음력 생일이 있는 지인이 많으면 해마다 양력 날짜가 달라져서 관리가 번거롭습니다. 매년 음력→양력 변환을 찾아보고 캘린더에 수동으로 등록하는 게 귀찮아서, 음력 날짜를 한 번 등록해두면 매년 초에 자동으로 그 해 양력 날짜를 계산해 구글 캘린더에 이벤트를 등록해주는 시스템을 만들었습니다.

음력 → 양력 변환

Java에서 음력 변환은 java.util.CalendarKOREAN 달력 타입을 사용하거나, 전통 음력 데이터를 담은 라이브러리를 사용할 수 있습니다. 저는 직접 계산 로직을 구현했습니다.

public LocalDate lunarToSolar(int year, int month, int day) {
    // 한국 음력 데이터 테이블 기반 변환
    // 윤달 여부도 처리
    Calendar cal = Calendar.getInstance(new Locale("ko", "KR"));
    cal.set(Calendar.ERA, 0);
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.MONTH, month - 1);
    cal.set(Calendar.DAY_OF_MONTH, day);

    // 음력 → 양력 변환
    Calendar solarCal = Calendar.getInstance();
    solarCal.setTimeInMillis(cal.getTimeInMillis());

    return LocalDate.of(
        solarCal.get(Calendar.YEAR),
        solarCal.get(Calendar.MONTH) + 1,
        solarCal.get(Calendar.DAY_OF_MONTH)
    );
}

Google Calendar API 설정

Google Cloud Console에서 프로젝트를 만들고 Calendar API를 활성화합니다. 서비스 계정을 생성하고 JSON 키 파일을 다운받습니다. 이 키 파일로 서버에서 OAuth 인증 없이 캘린더에 접근할 수 있습니다.

// Google Calendar 클라이언트 초기화
@Configuration
public class GoogleCalendarConfig {
    @Bean
    public Calendar googleCalendar() throws Exception {
        GoogleCredentials credentials = GoogleCredentials
            .fromStream(new FileInputStream("service-account.json"))
            .createScoped(CalendarScopes.CALENDAR);

        return new Calendar.Builder(
            GoogleNetHttpTransport.newTrustedTransport(),
            GsonFactory.getDefaultInstance(),
            new HttpCredentialsAdapter(credentials)
        ).setApplicationName("birthday-reminder").build();
    }
}

이벤트 자동 등록

매년 1월 1일에 스케줄러가 실행되어 등록된 음력 생일들을 그 해 양력 날짜로 변환하고 구글 캘린더에 이벤트를 등록합니다.

@Scheduled(cron = "0 0 9 1 1 *")  // 매년 1월 1일 오전 9시
public void registerBirthdays() {
    int thisYear = LocalDate.now().getYear();

    for (LunarBirthday birthday : birthdayList) {
        LocalDate solarDate = lunarService.lunarToSolar(
            thisYear,
            birthday.getLunarMonth(),
            birthday.getLunarDay()
        );

        createCalendarEvent(
            birthday.getName() + " 생신",
            solarDate,
            "음력 " + birthday.getLunarMonth() + "월 " + birthday.getLunarDay() + "일"
        );
    }
}

private void createCalendarEvent(String title, LocalDate date, String description) {
    Event event = new Event()
        .setSummary(title)
        .setDescription(description);

    EventDateTime start = new EventDateTime()
        .setDate(new com.google.api.client.util.DateTime(date.toString()))
        .setTimeZone("Asia/Seoul");

    event.setStart(start).setEnd(start);  // 종일 이벤트

    // 3일 전 알림 추가
    EventReminder reminder = new EventReminder()
        .setMethod("popup")
        .setMinutes(3 * 24 * 60);  // 3일 전
    event.setReminders(new Event.Reminders()
        .setUseDefault(false)
        .setOverrides(List.of(reminder)));

    calendar.events().insert(calendarId, event).execute();
}

생일 목록 관리

생일 목록은 간단히 설정 파일이나 상수로 관리합니다. DB까지 필요한 규모는 아닙니다.

// application.yml
birthdays:
  - name: "홍길동"
    lunarMonth: 3
    lunarDay: 15
  - name: "김철수"
    lunarMonth: 7
    lunarDay: 20
  - name: "이영희"
    lunarMonth: 11
    lunarDay: 3

추가 기능: 중요 기념일 알림

양력 기념일도 같은 방식으로 등록할 수 있습니다. D-30, D-7, D-1 알림을 카카오톡으로 보내도록 연동하면 중요한 날을 놓치는 일이 없습니다.

Google Calendar API 할당량

무료 할당량이 하루 100만 건이라 개인 용도로는 전혀 걱정할 필요가 없습니다. 다만 서비스 계정으로 접근하려면 해당 캘린더를 서비스 계정 이메일과 공유해야 합니다.

팁: Google Cloud Console에서 Calendar API를 활성화하는 것을 잊으면 안 됩니다. 또 서비스 계정 JSON 키 파일은 절대 Git에 올리면 안 됩니다. .gitignore에 꼭 추가하세요.