화면 자동화의 벽과 우회
윈도 PC와 메신저에서 부딪힌 것들
품앗이가 AI와 함께 업무 자동화를 하며 남긴 실패 기록을 다른 조직이 다시 쓸 수 있게 옮긴 글입니다. 묶음 전체는 API 없는 업무 프로그램 자동화에서 볼 수 있습니다.
요지
화면 자동화는 증상이 층층이 나옵니다. 원격으로 띄운 프로그램은 사람이 보지 않는 화면에 뜨고, 메신저는 불러오기에서 멈추고, 봇은 순서가 엉킵니다. 증상마다 땜질을 얹으면 끝이 없습니다. 이 노드는 우리가 부딪힌 벽과, 그 앞에서 바꾼 방법을 적습니다.
1. 원격으로 띄운 윈도 프로그램은 아무도 못 보는 화면에 있다
한 협동조합 사무실의 윈도 POS PC에서 원격으로 가격표를 인쇄하려 했습니다. 인쇄 프로그램은 분명히 떴는데 인쇄 대기열은 30초 동안 비어 있었습니다. 원격 접속 세션은 그 PC에 로그온한 사람의 화면과 다른 세션입니다. 거기서 띄운 화면 프로그램은 아무도 보지 않는 데스크톱에 떠서, 처음 실행할 때 나오는 동의 화면 같은 데서 멈추는데, 죽지도 않아서 더 헷갈립니다.
해법은 윈도 작업 스케줄러에 「대화형 로그온」으로 작업을 걸어 로그온한 사람의 세션에서 실행하는 것이었습니다. 일이 끝나면 그 작업과 남은 프로세스를 지워 남의 PC에 흔적을 남기지 않습니다. 다른 현장에서 진료실 PC의 통계 프로그램을 무인으로 다룰 때도 같은 방법이 통했고, 그때 익힌 것을 덧붙입니다.
- 실행 계정은 「PC 이름\계정」 전체 형식으로 적습니다. 줄여 쓰면 계정을 못 찾거나 엉뚱한 세션에서 돕니다.
- 파이썬 3.8 이후로는 확장 모듈의 DLL 경로를 스크립트 맨 위에서 직접 추가해야 합니다.
- 메뉴가 늦게 불러와지는 프로그램은 상위 메뉴를 먼저 펼친 뒤 하위 메뉴를 찾습니다.
- 결과와 화면 캡처는 파일로 남겨 거두어 옵니다.
- 로그온 세션은 사람이 쓰는 화면입니다. 낮에 돌리면 창이 그 사람 앞에 뜹니다. 시험은 사람 없는 시간에 하고, 끝나면 창을 닫아 화면을 돌려놓습니다.
세션이 다르면 「없는」 게 아니라 「안 보이는」 것입니다. 같은 POS PC에서 기본 프린터가 원격 세션에서는 비어 보였는데, 실제로는 사용자 설정에 처음부터 지정돼 있었습니다. 그걸 「설정이 안 돼 있다」로 읽고 하마터면 남의 매장 PC의 기본 프린터를 바꿀 뻔했습니다. 설정을 바꾸지 않고 인쇄할 때 프린터를 직접 지정하는 쪽으로 갔고, 그것으로 충분했습니다. 남의 기계는 설정을 바꾸지 말고 그때그때 지정합니다.
인쇄 대기열이 빈 것은 인쇄가 끝났다는 뜻이 아닙니다. 같은 프린터에 5쪽짜리 문서를 보냈을 때 대기열이 14초 만에 비어 끝난 줄 알고 프로그램을 닫았는데, 그게 인쇄를 취소시켰습니다. 손대지 않고 두니 32초 동안 0쪽이다가 36초에 5쪽이 모두 찍혔습니다. 대기열은 끝나도 비고 취소돼도 빕니다. 판정은 찍힌 쪽수가 전체 쪽수에 닿았는지로 합니다.
2. 화면 자동화는 땜질 루프에 빠지기 쉽다
PC용 메신저로 자동 발송을 만들 때였습니다. 막힐 때마다 좌표 수정, 창 닫기, 재시작, 화면 판정을 하나씩 얹으며 같은 실패를 10번 넘게 돌렸고, 실제로 나간 메시지는 0건이었습니다. 원인은 첫 발송 직후부터 대화창이 「불러오는 중」에서 멈추는 데 있었는데, 그건 전날 남긴 화면 기록에 이미 찍혀 있었습니다. 이 발송 경로는 아직 안정화되지 않았습니다.
- 착수 전에 이미 가진 기록(지난 캡처, 로그)부터 다시 봅니다.
- 「원인 가설 하나와 그것을 판가름할 시험 하나」로 쪼갭니다. 결과에 따라 갈 길을 미리 적어 둡니다. 되면 이렇게, 안 되면 「안 된다」로 정리합니다.
- 같은 경로로 세 번 실패하면 땜질을 얹지 말고 멈추고 보고합니다.
- 실제로 쓸 경로 하나를 먼저 굳히고 넓힙니다. 옵션, 판정, 재시작 설계를 한꺼번에 벌이지 않습니다.
- 다른 사람 이름으로 나가는 메시지는 그 사람이 준 문장만 보냅니다.
3. 메신저와 채널 실무
알림톡 검수
- 반복해서 보내는 템플릿은 「수신자가 요청하거나 동의했다」와 「얼마나 자주 보낸다」를 변수가 아닌 고정 문구로 적어야 통과합니다. 검수자가 준 예시 문구를 그대로 쓰는 편이 안전합니다.
- 할인율이나 가격 혜택을 변수로 넣으면 광고로 보고 반려합니다. 그런 내용은 링크한 페이지로 옮깁니다.
- 검수 결과는 아무도 알려 주지 않습니다. 제출하고 1~3영업일 뒤에 직접 조회합니다. 우리는 나온 결과를 나흘 묵힌 적이 있습니다.
네이버 밴드 API
우리가 직접 시험해 보니 밴드 공개 API는 살아 있어서 글과 댓글을 읽고 쓰고, 글을 올리며 알림을 보낼 수 있습니다. 다만 새로 등록한 앱이 클라이언트 ID를 받기까지 약 1주의 심사가 있고, 반려돼도 사유를 알려 주지 않습니다. 여러 안내 글에 적힌 「연동하면 바로 토큰」은 이미 승인된 앱의 이야기였습니다.
텔레그램 봇
- 앨범으로 보낸 사진은 파일마다 따로 메시지로 오고, 답장은 그중 하나만 가리킵니다.
- 지나간 메시지를 다시 조회하는 API가 없습니다. 봇이 듣지 않던 때 올라온 파일은 어떤 코드로도 되살릴 수 없고, 사용자가 다시 전달해 줘야 들어옵니다.
- 낱개로 연달아 보낸 파일은 묶는 표지가 없어 시간 간격으로만 묶을 수 있습니다.
- 「올려 줘」라는 말과 파일 중 어느 쪽이 먼저 도착할지 모릅니다. 말이 먼저 오면 잠시 기다렸다 뒤따라온 파일을 모아 처리합니다. 사용자에게 「다시 올려 주세요」라고 행동을 바꾸라고 안내하기보다, 봇이 어떤 순서든 받게 만드는 것이 먼저입니다. 우리는 세 번 안내했다가 그게 패착이었다는 걸 알았습니다.
봇의 의도 분기는 순서가 곧 기능입니다. 「올려」 같은 넓은 동사로 잡는 분기가 앞에 있으면 「자료실에 올려 줘」 같은 구체적인 요청은 영영 그 분기에 닿지 않습니다. 파일은 다른 곳으로 가고 봇은 「올렸다」고 답하니 실패조차 눈에 띄지 않습니다. 그래서 넓은 그물은 맨 뒤에 두고, 시험도 「이 문장이 걸리나」가 아니라 「이 문장이 어느 분기로 가나」로 합니다. 사람은 「캘린더」를 카렌더, 켈린더로도 씁니다.
확인 명령과 발신 명령을 섞지 마라
지난번에 보낸 파일이 무엇이었는지 확인하려던 명령 묶음 안에 메시지 전달 호출이 들어가 있었습니다. 그 결과 안내 글보다 첨부 파일이 먼저 방에 올라갔습니다. 발신 결과는 버리게 짜 놓았고, 바로 뒤에 「전달 시험은 건너뜀」이라는 문구를 찍어 두어 우리 스스로 속았습니다.
- 읽는 명령과 보내는 명령은 따로 실행합니다.
- 보내는 명령의 응답은 버리지 않고 메시지 번호를 기록합니다.
- 실행해 놓고 「건너뜀」이라고 적지 않습니다. 기록 문구는 실제로 그 길을 탔을 때만 나와야 합니다.
폼은 조용히 실패한다
신청 폼의 한 칸에 글자 수 상한을 넘긴 글을 넣고 제출을 눌렀더니 아무 일도 일어나지 않았습니다. 오류 문구도, 빨간 테두리도 없었습니다. 칸 옆에 작게 「1203/1000」이 떠 있었고, 글을 줄이자 바로 접수됐습니다. 「눌렀다」가 곧 「제출됐다」는 아니므로 성공 화면의 문구를 확인하고, 접수 확인 메일까지 봅니다.
4. AI 명령줄 도구를 상시 서비스로 돌릴 때
메신저 방에서 부르면 답하도록 AI 명령줄 도구를 상시 서비스로 띄웠더니, 인증이 만료된 상태에서 「인증 실패」 문구가 사람 방에 답으로 두 번 나갔습니다. 도구는 인증 실패를 종료 코드 0과 일반 출력으로 내보냈고, 코드는 그걸 실패로 보지 않았습니다. 상시 서비스에는 사람이 로그인한 셸의 상태가 이어지지 않습니다.
- 서비스에는 인증 토큰을 직접 넣어 줍니다.
- 출력이 짧고 오류 문구처럼 생겼으면 사람에게 내보내지 않습니다. 침묵이 오답보다 낫습니다. 엉뚱한 답이 가면 받는 사람은 그게 답인 줄 알고 기다림을 접지만, 답이 없으면 다시 묻습니다.
- AI가 작업 중에 뒤로 돌려 둔 프로세스는 그 작업이 끝나면 함께 죽을 수 있습니다. 늘 떠 있어야 하는 것은 서비스로 등록합니다.
5. 영상과 음성
- 자막 없는 영상도 전사할 수 있습니다. 음성만 뽑아(모노, 16kHz) 멀티모달 모델의 파일 업로드 기능에 넣으면 시간표까지 붙여 옮겨 줍니다. 「전사 도구 키가 없어서 못 한다」는 이미 가진 도구를 안 본 말입니다.
- 원고, 음성 합성, 사진이나 단색 배경에 자막, 이어 붙이기만으로 편집 없이 해설 영상 시제품을 만들 수 있습니다. AI가 1인칭으로 해설하는 형식이 차별점이 될 수 있습니다.
도구 메모
- 대화형 세션 실행:
schtasks /create ... /ru "PC이름\계정" /it로 만들고schtasks /run으로 발사, 끝나면 작업 삭제. - 인쇄 완료 판정: 인쇄 작업의 찍힌 쪽수가 전체 쪽수와 같아지고 상태가 「완료」일 때로 하고, 「삭제 중」은 취소로 읽는다.
- 음성 추출:
ffmpeg -i 영상 -vn -ac 1 -ar 16000 음성.m4a
관련 노드
- API 없는 업무 프로그램 자동화 (허브)
- 사람 방식대로, 그러나 떠넘기지 말고
- 남의 서버를 두드릴 때
- 알림과 타이머가 소음이 되지 않게
- 텔레그램 봇 만드는 법과 활용법
- 조직 기계에 원격으로 닿기에서 윈도 PC 원격 접속 자체를 다룹니다