툴과 개발 환경10 분 읽기

API가 200을 돌려주고 제 값을 버렸습니다

채널 열 개의 제목을 API로 바꿨습니다. 에러는 없었고 스크립트는 전부 성공을 찍었습니다. 다시 읽어 보니 제목은 하나도 안 바뀌어 있었습니다. 그날 하루에 밟은 조용한 실패 다섯 개를 정리했습니다.

#gotchas#youtube-api#automation#og-image#verification
개념 도식: 왼쪽은 200 OK와 '10개 채널 업데이트 완료', 오른쪽은 서버가 그대로 들고 있는 옛 제목
쓰기가 조용히 버려지면, 되읽기 전까지는 성공처럼 보입니다.

채널 열 개의 노출 설정을 한 번에 정리하기로 했습니다. 그중 여섯 개는 제목이 전부 똑같았습니다. 검색에서 서로를 잠식하고, 주제어는 한 글자도 없는 상태였습니다.

스크립트를 짜서 제목·설명·키워드를 한 번에 밀어 넣었습니다. 예외 없이 통과했고, 콘솔에는 열 줄의 성공 로그가 찍혔습니다.

그리고 확인차 값을 다시 읽었습니다. 제목은 하나도 안 바뀌어 있었습니다.

질문 하나 드립니다. 당신의 자동화는 쓰기가 끝난 뒤 되읽어서 확인합니까, 아니면 예외가 안 났으니 됐다고 넘어갑니까? 저는 후자였습니다. 그날 그 습관 때문에 다섯 번 넘어졌고, 다행히 전부 같은 방법으로 잡혔습니다.

1. 쓰기가 조용히 버려진다

플랫폼의 채널 업데이트 API에는 제목 필드가 분명히 존재합니다. 값을 넣어 보내면 400도, 403도, 경고도 없습니다. 200이 돌아옵니다. 그런데 서버는 그 필드를 읽기 전용으로 취급하고 조용히 버립니다. 제목 변경은 웹 스튜디오에서 사람이 해야 합니다.

에러를 안 주는 게 최악입니다. 스크립트 입장에서 이건 성공과 구분이 안 됩니다. 잡아낸 방법은 하나뿐이었습니다.

설정 후 다시 읽기 → 기대값과 문자열 비교 → 불일치면 사람이 할 일로 출력

지금 그 스크립트는 제목을 바꾸려 시도하지 않습니다. 대신 붙여넣을 문자열만 출력하고, 사람이 콘솔에서 입력합니다. 자동화가 못 하는 일을 못 한다고 말하게 만드는 게, 하는 척하게 두는 것보다 낫습니다.

덤으로 알게 된 것: 사람이 바꾼 뒤 되읽기를 한 번 더 돌렸더니 열 개 중 아홉 개만 일치했습니다. 하나는 제목 앞에 공백 한 칸이 붙어 있었습니다. 붙여넣기 사고입니다. 사람이 하는 단계도 되읽어야 합니다.

2. 어떤 필드는 혼자 보내야 한다

제목·설명·키워드는 브랜딩 설정 블록에, 로케일별 번역은 로컬라이제이션 블록에 들어갑니다. 한 번에 보내면 이렇게 거절당합니다.

400  'branding_settings cannot be used with other parts'

같은 리소스의 두 필드인데 한 요청에 못 담습니다. 호출을 둘로 쪼개면 끝나는 문제지만, 문서를 훑는 것만으로는 예측이 안 됐습니다.

3. 번역본이 원본을 이긴다

여기가 진짜 함정이었습니다. 채널에 한국어 로컬라이즈 제목이 등록돼 있으면, 한국어권 시청자에게는 그 번역본이 표시됩니다. 원본 제목만 고치고 로컬라이즈 값을 그대로 두면, 정작 주 시청자에게는 새 제목이 영원히 안 보입니다.

콘솔에서 확인하는 것만으로는 이걸 못 잡습니다. 관리자 화면은 원본을 보여주니까요. 되읽기 검사를 로컬라이즈 필드까지 확장한 뒤에야 드러났습니다.

4. 렌더러가 CSS를 다 아는 게 아니다

같은 날 공유 이미지(OG) 생성기도 손봤습니다. 카드가 뒤집힌 상태면 180도 회전시키는 코드였습니다.

transform: reversed ? 'rotate(180deg)' : 'none'

평범한 삼항 연산자입니다. 배포하고 확인했더니 뒤집힌 카드는 정상, 똑바른 카드는 전부 500이었습니다. 원인은 이랬습니다.

Unexpected token type: word
in CSS rule `transform: none`. Only absolute lengths such as `10px` are supported.

이미지 렌더러가 transform: none을 파싱하지 못합니다. 브라우저에선 아무 일도 안 하는 기본값인데, 여기선 예외를 던집니다. 해법은 값을 none으로 주는 게 아니라 속성 자체를 빼는 것입니다.

...(reversed ? { transform: 'rotate(180deg)' } : {})

무서운 부분은 따로 있습니다. 제가 이걸 처음에 못 잡은 이유는 뒤집힌 카드만 확인했기 때문입니다. 조건 분기를 하나만 테스트하면, 나머지 절반은 배포 후에 사용자가 발견합니다. 이 경우 "나머지 절반"이 전체 공유 이미지의 대부분이었습니다.

5. 없는 지표를 있다고 가정했다

채널 성과를 뽑으면서 노출수와 클릭률을 요청했습니다.

Unknown identifier (impressions) given in field parameters.metrics.

분석 API에 노출수 지표가 아예 없습니다. 웹 대시보드에만 있습니다. 즉 "노출은 되는데 안 눌리는가, 노출 자체가 없는가"를 자동화로는 구분할 수 없습니다. 이건 버그가 아니라 경계선이고, 알고 나면 진단 설계 자체가 달라집니다.

당신이라면?

여기서 하나 여쭙겠습니다. 쓰기 API를 호출하는 자동화를 짤 때, 되읽기 검증을 넣는 데 드는 비용은 보통 코드 세 줄과 요청 한 번입니다. 당신은 그 세 줄을 넣습니까, 아니면 예외가 안 났으니 됐다고 보십니까?

저는 이날 이전까지 안 넣었습니다. 그리고 이날 하루에 조용한 실패를 다섯 개 밟았습니다. 다섯 개 중 네 개는 예외를 던지지 않았습니다. 예외로 잡힌 건 두 번째(part 제약) 하나뿐이고, 나머지는 전부 "성공했는데 아무 일도 안 일어난" 종류였습니다.

자가진단 3개

  1. 쓰기 후 되읽고 비교합니까? 특히 외부 SaaS API라면, 필드가 읽기 전용으로 강등돼 있어도 알려주지 않습니다.
  2. 조건 분기의 양쪽을 다 실행해 봤습니까? 한쪽만 확인하면 나머지 절반은 사용자가 테스트합니다.
  3. 사람이 하는 수동 단계도 검증 대상에 넣었습니까? 공백 한 칸이 붙는 데는 한 번의 붙여넣기면 충분합니다.

솔직한 부분

이날 바꾼 설정 중 실제 성과에 큰 영향을 줄 만한 건 아마 없습니다. 채널 키워드와 설명은 노출당 클릭을 조금 올릴 뿐이고, 제 병목은 그 아래쪽에 있다는 걸 다른 글에서 숫자로 확인했습니다.

그래도 이 하루가 남긴 게 하나 있습니다. 제 자동화 스크립트 대부분이 "요청을 보냈다"를 "값이 바뀌었다"로 착각하고 있었다는 사실입니다. 되읽기 한 줄이 없으면, 설정이 반영됐다는 믿음은 그냥 믿음입니다.

비슷한 결의 이야기로, 검색 명령이 조용히 죽어 있었는데 제가 "결과 없음"으로 읽었던 일은 앱 유입의 63%는 내가 안 밀던 채널에서 왔다에 적어 뒀습니다.

지금 돌아가는 자동화 중에 쓰기만 하고 되읽지 않는 게 하나쯤 있을 겁니다. 그거 하나만 오늘 확인해 보시겠습니까?

관련 글