Telegram 봇 Inline Keyboard 버튼이 무반응인 버그 — UUID Regex + Solid Cache 디버깅

Telegram 봇에서 자연어 입력 → AI 분석 → Inline Keyboard 확인 버튼 방식으로 할 일을 추가하는 기능을 운영하던 중, 버튼을 눌러도 아무 반응이 없는 증상이 발생했다. 증상 사용자가 자연어로 일정을 입력하면 봇이 다음처럼 확인 메시지를 보낸다. 📝 할 일을 추가할까요? (개인일정) "부장님 점심식사" [📅03/24 ⏰12:00] [✅ 추가] [❌ 취소] 그런데 [✅ 추가] 버튼을 눌러도 응답이 없었다. Telegram 클라이언트에는 “알 수 없는 요청입니다.” 라는 토스트 메시지만 표시됐다. 서버 로그 확인 서버 쪽 webhook 로그를 보면 버튼 클릭은 정상적으로 서버에 도달하고 있었다. ...

2026-03-11 · 3분 소요 · Seunghan
Rails8 Cross Project Patterns And Improvements

Rails 8 프로젝트 간 패턴 교차 적용 — rack-attack, PWA 배너, Sentry, FCM 멀티디바이스

두 개의 Rails 8 프로젝트를 병렬로 운영하다 보면 한쪽에서 공들여 만든 패턴이 다른 쪽에는 빠져있는 경우가 자주 생긴다. 기능을 구현할 때는 당장의 요구사항에 집중하다 보니 다른 프로젝트의 좋은 구현을 챙기지 못하는 것이다. 시간이 지날수록 두 프로젝트 사이의 품질 격차가 벌어지고, 한쪽에서는 해결된 문제를 다른 쪽에서 다시 삽질하는 상황이 생긴다. 이번에 두 프로젝트를 나란히 놓고 비교하면서 빠진 부분을 서로 채워주는 작업을 했다. 주로 보안, PWA 경험, 에러 추적, 푸시 알림 인프라에 관한 내용이다. 여섯 가지 항목 모두 “한번 제대로 만들면 모든 프로젝트에 적용해야 하는” 기반 인프라 성격의 것들이다. ...

2026-02-20 · 10분 소요 · Seunghan
Rails Sso Turbo Drive Debugging

Rails SSO 구현 중 Turbo Drive가 유발한 두 가지 버그 디버깅

Rails 앱 간 SSO(Single Sign-On)를 HMAC 기반으로 구현하던 중 예상치 못한 두 가지 버그를 만났다. 둘 다 Turbo Drive와 ERB의 동작 방식에서 비롯된 문제였다. 에러 메시지는 동일하게 “state mismatch"였지만 원인은 전혀 달랐고, 첫 번째 버그를 고쳐도 두 번째가 남아 있어 디버깅이 꽤 번거로웠다. 구현 개요 구조 두 개의 독립적인 Rails 앱이 SSO로 연결된다. IdP (Identity Provider): 사용자 인증을 담당하는 Rails 앱. OTP 로그인을 처리하고 One-Time Token을 발급한다. SP (Service Provider): IdP에서 발급받은 토큰으로 로그인하는 Rails 앱. 직접 사용자 자격증명을 다루지 않고 IdP를 신뢰한다. 이 구조는 소규모 멀티 앱 환경에서 공통 인증을 구현할 때 자주 쓰이는 패턴이다. OAuth 2.0보다 단순하지만 CSRF 방지와 토큰 검증은 동일하게 필요하다. ...

2026-02-13 · 7분 소요 · Seunghan
Rails Rfc3161 Tsa Blockchain Merkle Debugging

RFC 3161 TSA 타임스탬프 + 블록체인 Merkle 앵커링: Rails에서 삽질 기록

전자계약 보관 시스템에 법적 증거력을 부여하기 위해 두 가지를 동시에 구현해야 했다: 블록체인 Merkle Tree 앵커링 — 계약 해시들을 모아 Merkle Root를 L2 체인에 기록 RFC 3161 TSA 타임스탬프 — 신뢰할 수 있는 제3자 시간 증명 간단해 보였는데, 삽질의 연속이었다. 각 문제를 해결하는 데 예상보다 훨씬 많은 시간이 걸렸고, 특히 Ruby 4.0의 API 변경과 Rails 8의 멀티 데이터베이스 동작이 예상치 못한 방식으로 얽혔다. 1. RFC 3161 TSA란? RFC 3161은 Time-Stamp Authority(TSA) 프로토콜로, 특정 데이터가 특정 시점에 존재했음을 제3자가 증명해주는 국제 표준(RFC 3161, RFC 5816로 업데이트)이다. 법적 맥락에서는 “이 문서가 이 날짜에 존재했음"을 공인 제3자가 서명으로 보증한다는 의미다. ...

2026-02-06 · 8분 소요 · Seunghan
Rails Turbo Actioncable 500 Debug

Rails Turbo Stream 500 에러 3종 세트 디버깅 — broadcast, SolidCable, Telegram Markdown

Rails 8 + Hotwire(Turbo) 기반 앱을 운영하다 보면 broadcast_append_to 계열 콜백이 조용히 500을 내뱉는 경우가 있다. 거기에 SolidCable 초기 설정 문제와 Telegram Bot 메시지 파싱 오류가 겹치면 로그 해석도 헷갈린다. 이번에 세 가지가 한꺼번에 터져서 순서대로 해결한 과정을 정리한다. 이 글에서 다루는 세 문제는 서로 독립적이지만, 실제 운영 환경에서는 이렇게 한꺼번에 맞닥뜨리는 경우가 많다. 각 문제를 격리해서 하나씩 해결하는 접근이 중요하다. 문제 1: No unique index found for id — broadcast 콜백 500 현상 메시지나 알림을 생성할 때 컨트롤러에서 500이 발생한다. 로그를 보면: ...

2026-01-09 · 7분 소요 · Seunghan
Rails Ruby3 Kwargs Dispatch Integration Debug

하루 종일 삽질한 것들 — Ruby 3.0 kwargs, Docker env, NAS 크론, SSH 특수문자

AI 에이전트가 Rails API 서버를 호출해서 티켓을 자동 배정하는 디스패처를 만들었다. 로직 자체는 간단한데 붙이는 과정에서 예상치 못한 곳에서 계속 막혔다. 하루 동안 7개의 서로 다른 버그를 순서대로 만났고, 각각은 사소하지만 연속으로 터지니 꽤 피로했다. 비슷한 스택을 쓰는 사람에게 도움이 됐으면 해서 기록해 둔다. 1. Ruby 3.0 kwargs 분리 — render_success(key: val) 가 왜 터지나 가장 오래 고생한 것. Rails 컨트롤러에서 응답 헬퍼를 이렇게 호출했다: render_success(tickets: tickets_list, pagination: pagination_data) 서버 로그에 찍힌 에러: ...

2026-01-02 · 7분 소요 · Seunghan
Crypto Exchange Api Integration Lessons

Binance·Bybit·OKX 5개 거래소 API — 공식 문서가 틀렸을 때 Rails에서 살아남기

Ruby on Rails로 여러 암호화폐 거래소의 펀딩레이트(funding rate)를 수집하는 기능을 만들면서 겪은 문제들을 정리한다. 5개 거래소를 붙이면서 각 거래소마다 API 동작 방식이 달랐고, 공식 문서와 실제 동작이 다른 경우도 있었다. 거래소 API의 공통 기반 클라이언트 만들기 여러 거래소를 붙이기 전에 공통 HTTP 클라이언트를 먼저 만들었다. Faraday를 사용했고, 재시도와 Circuit Breaker를 여기에 몰아 넣었다. Faraday + faraday-retry 설정 # Gemfile gem "faraday" gem "faraday-retry" def connection @connection ||= Faraday.new(url: base_url) do |f| f.request :retry, { max: 3, interval: 0.5, backoff_factor: 2, interval_randomness: 0.5, # jitter retry_statuses: [429, 503, 504], retry_block: -> (env, options, retries, exc) { Rails.logger.warn("[#{exchange_name}] Retrying... #{retries} left. Status: #{env.status}") } } f.adapter Faraday.default_adapter f.options.timeout = 10 f.options.open_timeout = 5 end end backoff_factor: 2와 interval_randomness: 0.5(jitter)를 조합하면 재시도 간격이 0.5초 → 1초 → 2초로 지수 증가하면서 약간의 무작위성이 붙는다. 거래소 API가 Rate Limit(429)을 돌려줄 때 모든 클라이언트가 동시에 재시도하는 “thundering herd” 문제를 막아준다. ...

2025-12-06 · 6분 소요 · Seunghan
Telegram Bot Intent Classification Bugs

Telegram 봇 의도 분류 버그 3가지와 Inline Keyboard 확인 플로우 구현

Telegram 봇에 자연어로 할 일을 추가하는 기능을 운영하던 중 발생한 버그 3가지와, 사용자 경험 개선을 위한 inline keyboard 확인 플로우 구현 내용을 정리한다. 이 봇의 기본 동작 방식은 다음과 같다. 사용자가 자유 형식 문자열을 입력하면, Rails 백엔드가 먼저 정규식 기반 사전 필터를 거쳐 의도를 추측하고, 이후 Gemini AI를 호출해 최종 intent와 파라미터(날짜, 시간, 내용 등)를 추출한다. 이 2단계 구조에서 각 단계에 버그가 하나씩 숨어 있었고, 그 결과가 예상치 못한 방식으로 결합되어 사용자가 의도하지 않은 동작을 일으켰다. ...

2025-06-25 · 9분 소요 · Seunghan
개인정보처리방침 이용약관 면책조항 문의