Perplexity 검색봇을 이용해서 예약 날씨 알림봇 (실패)

소개

단체톡방에서 매일 일정시간에 날씨 알림을 보내고 싶었어요

진행 방법

항상 Perplexity api를 이용해서 봇을 쓰는 법을 알려주셔서 활용해봤습니다

// 스케줄링 설정
MORNING_HOUR: 22,  // 날씨 검색 시간 (24시간 형식)
MORNING_QUERY: "내일 서울 날씨"  // 저녁에 자동 검색할 내용
// ===== 라인 47-50 =====
var Scheduler = {
    lastExecutedDate: "",  // 메모리 캐시 (YYYY-MM-DD-HH 형식)
    isRunning: false,      // Thread 중복 방지 플래그
    STATE_FILE: "/storage/emulated/0/msgbot/weatherbot_last_exec.txt",
// ===== 라인 53-67 =====
loadLastExecutedDate: function() {
    try {
        var file = new java.io.File(this.STATE_FILE);
        if (!file.exists()) {
            return "";
        }
        var reader = new java.io.BufferedReader(new java.io.FileReader(file));
        var dateStr = reader.readLine();  // "2025-11-16-05" 형식
        reader.close();
        return dateStr || "";
    } catch (e) {
        Log.e("파일 읽기 오류: " + e.message);
        return "";
    }
}
// ===== 라인 70-94 =====
saveLastExecutedDate: function(dateStr) {
    try {
        var file = new java.io.File(this.STATE_FILE);
        var parent = file.getParentFile();
        if (parent && !parent.exists()) {
            parent.mkdirs();  // 디렉토리 생성
        }

        // ⚡ Atomic write 패턴
        var tempFile = new java.io.File(this.STATE_FILE + ".tmp");
        var writer = new java.io.FileWriter(tempFile);
        writer.write(dateStr);  // 임시 파일에 쓰기
        writer.close();

        // 원자적 rename (기존 파일 덮어쓰기)
        if (file.exists()) {
            file.delete();
        }
        tempFile.renameTo(file);  // 순간적으로 교체

        Log.d("✅ 실행 날짜 저장: " + dateStr);
    } catch (e) {
        Log.e("파일 저장 오류: " + e.message);
    }
}
// ===== 라인 97-143 =====
checkSchedule: function() {
    var now = new Date();
    var currentHour = now.getHours();
    var currentMinute = now.getMinutes();

    // ===== 1. 현재 날짜+시간을 YYYY-MM-DD-HH 형식으로 생성 =====
    var year = now.getFullYear();
    var month = (now.getMonth() + 1).toString();
    var day = now.getDate().toString();
    var hour = currentHour.toString();
    if (month.length === 1) month = "0" + month;
    if (day.length === 1) day = "0" + day;
    if (hour.length === 1) hour = "0" + hour;
    var currentDateHour = year + "-" + month + "-" + day + "-" + hour;
    // 예: "2025-11-16-05"

    // ===== 2. 시간 윈도우 체크 (20분 범위) =====
    if (currentHour < CONFIG.MORNING_HOUR) return;      // 설정 시간 전
    if (currentHour > CONFIG.MORNING_HOUR) return;      // 설정 시간 지남
    if (currentMinute > 20) return;                     // 20분 이후
    // → 5:00 ~ 5:20 사이에만 실행

    // ===== 3. 파일 기반 중복 체크 (글로벌 락) =====
    var savedDateHour = this.loadLastExecutedDate();
    if (savedDateHour === currentDateHour) {
        // 이미 이 시간에 실행됨 (다른 Thread 포함)
        return;
    }

    // ===== 4. 메모리 캐시 체크 (추가 보호) =====
    if (this.lastExecutedDate === currentDateHour) return;

    // ===== 5. 실행 조건 만족! =====
    Log.i("🔍 스케줄 체크: " + currentHour + ":" + currentMinute + 
          " 날짜+시간:" + currentDateHour + " 마지막:" + savedDateHour);

    // ===== 6. 즉시 파일 저장 (다른 Thread 차단) =====
    this.saveLastExecutedDate(currentDateHour);
    this.lastExecutedDate = currentDateHour;

    Log.i("⏰ 예약된 날씨 검색 실행 (날짜+시간: " + currentDateHour + 
          ", 설정: " + CONFIG.MORNING_HOUR + "시)");

    // ===== 7. 모든 대상 방에서 검색 실행 =====
    for (var i = 0; i < CONFIG.TARGET_ROOMS.length; i++) {
        var room = CONFIG.TARGET_ROOMS[i];
        this.executeScheduledSearch(room, CONFIG.MORNING_QUERY);
    }
}
// ===== 라인 146-160 =====
executeScheduledSearch: function(room, query) {
    Log.i("예약 검색: '" + query + "' in '" + room + "'");

    // 가짜 메시지 객체 생성 (스케줄러가 사용자인 척)
    var fakeMsg = {
        room: room,
        content: CONFIG.TRIGGER_PREFIX + " " + query,  // "!검색 내일 서울 날씨"
        author: {
            name: "스케줄러"
        }
    };

    // onMessage 직접 호출
    onMessage(fakeMsg);
}
// ===== 라인 163-206 =====
start: function() {
    // ===== Thread 중복 생성 방지 =====
    if (this.isRunning) {
        Log.i("⚠️ 스케줄러가 이미 실행 중입니다. 중복 실행 방지.");
        return;
    }

    this.isRunning = true;
    Log.i("✅ 스케줄러 Thread 시작");

    new java.lang.Thread(function() {
        while (true) {  // 무한 루프
            try {
                Scheduler.checkSchedule();  // 스케줄 체크

                // 1분마다 체크 (60초 = 60000ms)
                java.lang.Thread.sleep(60000);

            } catch(e) {
                Log.e("❌ 스케줄러 오류: " + e.message);
                if (e.stack) {
                    Log.e("스택: " + e.stack);
                }

                // InterruptedException 발생 시 Thread 종료
                if (e.toString().indexOf("InterruptedException") !== -1) {
                    Log.d("스케줄러 Thread 인터럽트");
                    Scheduler.isRunning = false;
                    break;
                }

                // 오류 시 5초 대기 후 재시도
                try {
                    java.lang.Thread.sleep(5000);
                } catch(se) {
                    Log.e("재시도 실패, Thread 종료");
                    Scheduler.isRunning = false;
                    break;
                }
            }
        }
        Log.i("🛑 스케줄러 Thread 종료");
        Scheduler.isRunning = false;
    }).start();
}
// ===== 라인 318-339 =====
if (content === "!스케줄확인") {
    var now = new Date();
    var year = now.getFullYear();
    var month = (now.getMonth() + 1).toString();
    var day = now.getDate().toString();
    if (month.length === 1) month = "0" + month;
    if (day.length === 1) day = "0" + day;
    var currentDate = year + "-" + month + "-" + day;

    // 파일에서 실제 마지막 실행 날짜 읽기
    var savedDate = Scheduler.loadLastExecutedDate();

    var statusMsg = "📅 스케줄러 상태\n\n";
    statusMsg += "현재 시간: " + now.getHours() + ":" + now.getMinutes() + "\n";
    statusMsg += "현재 날짜: " + currentDate + "\n";
    statusMsg += "마지막 실행 날짜: " + (savedDate || "없음") + "\n";
    statusMsg += "설정 시간: " + CONFIG.MORNING_HOUR + "시\n";
    statusMsg += "검색 쿼리: " + CONFIG.MORNING_QUERY;

    bot.send(msg.room, statusMsg);
    return;

매일 22시에 내일 서울 날씨 검색이 되도록 클로드코드에게 코드작성을 해달라고 한 코드입니다

그런데 컴파일을 하면 22시에 되지만 다음 날이 되면 되지가 않아요

비개발자라 보니 왜 안되는지 이유는 모르겠고

이거 이후에 계속 수정을 해달라고 했지만 더 이상하게 꼬이기만하고 결국 실패를 했습니다

결과와 배운 점

수정을 해달라고 하면 안될 것 같고 아예 처음부터 해보는 방법도 좋을 것 같아요

도움 받은 글 (옵션)

예시로 받은 카톡봇

1
1개의 답글

뉴스레터 무료 구독

👉 이 게시글도 읽어보세요