학부모 앱에 쌓인 알림장과 앨범 사진을 한 장씩 저장하는 대신, 원하는 기간을 골라 내 PC의 월별 폴더로 정리하는 도구를 만들었다. 브라우저 사용자 스크립트와 로컬 Node.js 서버를 연결한 개인용 제작 기록이다. AI는 설계와 코드 작성·검토를 돕는 개발 도구였고, 완성된 프로그램이 사진을 AI로 분석하거나 외부 AI API에 보내지는 않는다.
앞서 만든 다운로드 폴더 분류 도구는 이미 PC에 받은 파일을 정리했다. 이번 도구는 로그인한 화면에서 내가 열람할 수 있는 기록의 첨부파일을 선택한 기간만큼 로컬에 보관하는 단계까지 다룬다.
2026년 9월 앨범을 선택해 실행한 화면에 사진 116개·영상 0개 저장 완료가 표시됐다. 해당 월의 로컬 저장 폴더에서도 이미지 파일 116개를 확인했다. 아이 이름, 화면 주소, 파일명, 사진은 공개하지 않는다.
왜 두 프로그램으로 나눴을까
처음에는 별도 웹페이지에서 로그인 정보를 직접 입력받아 내려받는 방식도 생각할 수 있다. 하지만 로그인 정보나 세션 쿠키를 또 다른 입력창에 복사하는 과정은 번거롭고, 잘못 기록되거나 노출될 위험도 있다. 그래서 로그인한 브라우저 안에서 필요한 목록을 읽는 부분과 선택한 파일을 PC에 저장하는 부분을 분리했다.
아이·메뉴·기간을 선택
선택한 월의 첨부 목록을 수집
파일을 받아 월별 폴더에 보관
서버는 127.0.0.1에만 연결되도록 설정했다. 사용자 스크립트는 이미 로그인된 브라우저의 세션을 이용하므로, 별도의 쿠키 입력칸을 만들지 않았다. 단, 이는 내 계정에서 볼 권한이 있는 자료를 개인적으로 보관하는 구조를 설명한 것이며, 다른 사람의 자료에 접근하거나 서비스를 우회하는 방법이 아니다.
설계에서 먼저 정한 네 가지
| 결정 | 구현 기준 | 이유 |
|---|---|---|
| 기간 선택 | 시작 월부터 종료 월까지 한 달씩 처리 | 오래된 기록을 한 번에 요청하지 않고 진행 상황을 구분 |
| 자료 구분 | 알림장과 앨범을 별도 폴더에 저장 | 나중에 월과 자료 종류로 찾기 쉽도록 |
| 파일 선택 | 첨부 목록에서 사진·영상 URL을 모아 중복 URL을 제거 | 같은 실행에서 같은 첨부를 두 번 요청하지 않도록 |
| 진행 표시 | 전체 파일 수와 저장 완료 수를 계속 표시 | 오래 걸리는 작업이 멈춘 것처럼 보이지 않도록 |
구현 흐름: 목록 수집에서 파일 저장까지
브라우저 패널에서 자료 종류, 시작·종료 월, 저장 폴더를 선택한다. 사용자 스크립트가 월별 목록을 페이지 끝까지 읽고 첨부파일을 추출한다. 같은 실행에서 이미 본 URL은 건너뛰고, 로컬 서버에는 저장할 파일의 URL과 상대 폴더 이름만 보낸다. 서버는 파일을 내려받아 앨범/연도-월/파일처럼 분류한다. 파일명에 사용할 수 없는 문자는 바꾸고, 같은 이름이 이미 있으면 번호를 붙여 덮어쓰지 않는다.
핵심 로직을 가상 데이터로 확인하기
아래 코드는 실제 서비스 연결 부분을 제외하고, 월별 폴더 지정과 같은 URL의 중복 제거만 떼어 낸 실행 가능한 축약 예시다. 주소는 가상 도메인이며 다운로드를 실행하지 않는다. Node.js에서 실행하면 동일한 첨부가 두 번 들어와도 작업 수는 1로 나온다.
// 실제 서비스 응답이 아닌 가상 데이터만 사용한다.
function prepareFiles(records) {
const seen = new Set();
const tasks = [];
for (const record of records) {
if (!/^\d{4}-(0[1-9]|1[0-2])$/.test(record.month)) continue;
const folder = record.kind === 'album' ? '앨범' : '알림장';
for (const file of record.attachments ?? []) {
if (!file.url?.startsWith('https://') || seen.has(file.url)) continue;
seen.add(file.url);
const name = String(file.name || 'file.jpg')
.replace(/[<>:"/\\|?*\x00-\x1f]/g, '_').slice(0, 120);
tasks.push({ folder: `${folder}/${record.month}`, name, url: file.url });
}
}
return tasks;
}
const sample = [{
kind: 'album', month: '2026-09',
attachments: [
{ name: 'sample.jpg', url: 'https://example.invalid/sample.jpg' },
{ name: 'sample.jpg', url: 'https://example.invalid/sample.jpg' },
],
}];
console.log(prepareFiles(sample).length); // 1
실제 서비스에서 목록을 읽는 부분과 로컬 파일을 저장하는 부분은 별도로 구현해야 한다. 이 예시는 특정 서비스의 내부 주소, 로그인 정보, 아이 식별자를 공개하지 않으면서 목록 정리 단계의 판단 기준을 재현하기 위한 것이다.
이 과정에서 가장 주의한 부분은 “목록을 찾았다”와 “파일을 저장했다”를 다른 단계로 취급하는 것이다. 첨부 URL을 116개 찾았더라도 네트워크 오류로 실제 저장 수가 적을 수 있다. 그래서 화면에는 파일별 진행률과 마지막 완료 수를 남기고, 실행 뒤 해당 월의 폴더에서도 개수를 확인한다.
① 자신이 열람할 수 있는 한 달을 선택한다. ② 화면의 첨부 수와 완료 수를 기록한다. ③ 저장 폴더의 파일 수를 센다. ④ 파일 몇 개를 직접 열어 정상 저장됐는지 확인한다. ⑤ 같은 기간을 다시 실행하기 전에 중복 파일이 생길 수 있다는 점을 확인한다.
AI는 어디에 쓰이고, 어디에는 쓰이지 않았나
이 작업에서 AI의 역할은 여러 단계로 나뉜 코드를 작성하고 검토할 때 도움을 받는 것이다. 예를 들어 “월별 순회”, “첨부 URL 중복 제거”, “파일명 정리”, “진행률 표시”를 작은 기능으로 나누고 각 단계의 실패 조건을 점검할 수 있다. 반면 프로그램 실행 중에 LLM이 사진 내용을 판별하거나 기록을 요약하지는 않는다. 자동화된 파일 처리와 AI 추론은 서로 다른 기술이기 때문이다.
AI가 제안한 코드라도 내 계정의 로그인 처리, 저장 위치, 중복 실행 결과는 실제 환경에서 확인해야 했다. 특히 개인 사진을 다루는 프로그램에서는 “코드가 실행된다”보다 “의도한 파일만 저장하고 개인 정보가 다른 곳으로 가지 않는다”가 더 중요한 검증 기준이다.
개인용으로 동작했어도 공개 배포 전에는 부족한 점
이번 확인은 개인 PC에서 한 달 앨범을 저장한 결과다. 현재 구현은 한 번의 실행 안에서 URL 중복을 거르지만, 날짜를 바꿔 다시 실행할 때 기존 파일과 내용까지 비교하지는 않는다. 같은 기간을 재실행하면 파일명 뒤에 번호가 붙은 중복 파일이 생길 수 있다. 다음 개선에는 파일 크기나 해시를 이용한 중복 검사를 넣는 편이 좋다.
로컬 서버는 외부 컴퓨터에 열지 않도록 설정했지만, 전달받은 다운로드 URL의 허용 도메인과 저장 대상 폴더를 더 엄격히 제한해야 공개 배포에 적합하다. 초기 설정에 개인 식별값이 들어갈 수 있는 부분도 제거해야 한다. 서비스 화면과 자료 구조가 바뀌면 수집 방식이 작동하지 않을 수 있으며, 사용 범위와 서비스 정책도 각자 확인해야 한다. 이 글은 실행 코드를 배포하는 사용 설명서가 아니라, 실제로 만든 개인용 도구의 설계·검증·남은 과제를 기록한 글이다.
한 달치 사진 116개가 월별 폴더에 들어간 결과는 유용했다. 동시에 AI로 코드를 빠르게 만드는 것과, 그 코드를 누구나 안전하게 다시 쓸 수 있게 만드는 일 사이에는 큰 차이가 있다는 것도 확인했다. 다음 단계는 중복 실행, 부분 실패 후 재개, 허용 URL 제한을 보강하고 가상 데이터로 반복 시험하는 것이다.
