Glowb Dev Docs
SaaS API크리에이터 DM 인증

크리에이터 DM 인증

크리에이터의 인스타그램 계정을 ig.me 링크로 확인하고 알림 발송 주소를 확보하는 구조

크리에이터 DM 인증

캠페인 일정·독촉 알림을 인스타그램 DM 으로 보내기 위해, 크리에이터가 신고한 계정이 실제로 본인 것인지 확인하고 발송 주소를 확보합니다.

일본 캠페인에서 운영이 "독촉을 DM 으로 보내면 메일보다 훨씬 잘 본다"고 관찰한 것이 출발점입니다.

왜 인증이 필요한가

인스타그램에 DM 을 보내려면 상대의 IGSID(Instagram-scoped ID)가 필요한데, 이 값은 우리가 알아낼 방법이 없습니다. 크리에이터가 신청서에 적은 핸들(sns_account_link)은 본인 확인을 거치지 않은 자기 신고값이라, 그것만으로 DM 을 보내면 엉뚱한 사람에게 갈 수 있습니다.

IGSID 는 (사람 ↔ 우리 비즈니스 계정) 쌍에 부여됩니다. 다른 회사가 보는 같은 사람의 IGSID 는 다른 값입니다. 그래서 인스타 계정을 바꾸면 이미 인증된 IGSID 가 전부 무효가 되며, 발송 계정(glow.b_kor)은 갈아끼울 수 있는 값이 아닙니다.

핵심 아이디어 — 인증번호가 없다

ig.me/m/<핸들>?ref=<토큰> 링크를 열면, 인스타가 우리 DM 대화창을 열면서 그 ref 값을 웹훅에 실어 보냅니다. 같은 이벤트에 발신자의 IGSID 도 함께 옵니다.

"누구인가"(ref → 크리에이터)  +  "어디로 보내는가"(IGSID)   ← 한 이벤트에 동시 확보

그래서 크리에이터가 인증번호를 받아 적을 필요가 없습니다. 링크를 누르는 것만으로 끝납니다.

다만 링크를 거치지 않고 들어오면 ref 가 없어 누구인지 알 수 없습니다. 그 자리를 메우려고 6자리 코드를 한 쌍으로 함께 발급합니다 — 코드는 아무 메시지에나 실려 오는 IGSID 만 있으면 되므로 어떻게 들어왔든 통합니다. 어느 쪽으로 인증하든 나머지 하나도 같이 소모됩니다.

전체 흐름

[크리에이터]                [glowb-server]              [릴레이]            [메타]
     │                           │                        │                  │
     │  신청 폼에서 인증하기 클릭   │                        │                  │
     │──────────────────────────▶│                        │                  │
     │   POST /dm-link/token     │                        │                  │
     │◀──────────────────────────│  Redis 에 토큰 저장(1h) │                  │
     │   ig.me 링크 + 버튼문구     │                        │                  │
     │                                                    │                  │
     │  링크 열기 (모바일) / QR 스캔 (PC)                     │                  │
     │───────────────────────────────────────────────────────────────────────▶│
     │                                                    │◀─── 웹훅(ref+IGSID)│
     │                           │◀───────────────────────│                  │
     │                           │  POST /webhooks/ig-dm  │                  │
     │                           │  토큰 소모 → 인증 기록    │                  │
     │                           │───────────────────────▶│                  │
     │                           │   회신 문구(guidance)    │                  │
     │◀───────────────────────────────────────────────────────────────────────│
     │   "인증이 완료되었습니다" DM                            │                  │

두 서비스로 나뉜 이유

메타 웹훅은 릴레이(glowb-ig-dm-relay, Cloud Run)가 받습니다. test/prod 가 같은 메타 앱을 쓰기 때문에, 어느 한쪽 서버에 웹훅을 붙이면 다른 쪽이 못 받습니다. 그래서 서버 밖으로 뺐습니다.

메타 자격증명(시스템 유저 토큰·페이지 토큰 캐시)도 릴레이에만 있습니다. glowb-server 는 메타를 직접 부르지 않고 릴레이에 맡깁니다 — 같은 토큰이 두 군데에 살지 않게 하려는 것입니다.

인증 기록

TB_CREATOR_DM_LINK 에 남습니다. sns_account_link 는 덮어쓰지 않습니다 — 그 값을 읽는 곳이 열다섯 군데가 넘고 포맷에 의존하는 코드가 많아, 인증 결과는 별도로만 기록합니다.

컬럼의미
application_id인증 대상 신청 (TB_CAMPAIGN_APPLICATION.id)
influence_id크리에이터
igsidGraph API 발송 주소
usernameAutoDM 발송 주소(핸들). 판정에는 쓰지 않는다
statusVERIFIED / REVOKED
notify_opt_in수신 거부 기록. 인증되면 켜고, 그만 받겠다고 하면 내린다
applied_handle그 신청서에 적어낸 핸들(정규화)
handle_matched신청서 핸들과 같았는가. 다르면 애초에 인증이 안 되므로 true 또는 null

수신 동의를 따로 받지 않습니다. 여기서 나가는 것은 이미 우리 캠페인에 참여 중인 크리에이터에게 보내는 일정 공지이지 광고가 아니라, 별도 동의를 받을 성질이 아닙니다. 인증되면 notify_opt_in 을 켜두고, 나중에 "그만 보내라"는 사람만 내려 발송에서 뺍니다.

홍보성 내용(신규 캠페인 모집 안내 등)을 DM 으로 보내게 되면 이 값으로는 부족합니다 — 그때는 TB_INFLUENCE.marketing_agreed 를 봐야 합니다.

인증 단위는 신청입니다. 같은 사람이 캠페인마다 다른 인스타 계정으로 신청하는 경우가 실제로 있습니다 — prod 기준 크리에이터 2,074명 중 138명(6.7%) 이 서로 다른 핸들로 신청했고 한 사람이 최대 6개까지 썼습니다. 크리에이터 단위로 잡으면 그분들은 신청서에 적은 계정이 아닌 곳으로 DM 을 받게 됩니다.

UNIQUE (application_id, status) 로 한 신청에 계정 하나를 보장합니다.

신청서 핸들과 다른 계정으로는 인증되지 않습니다

인증이 끝나면 그 신청의 sns_account_link 를 정규화해 실제 인증한 계정과 비교하고, 다르면 거절합니다. 신청한 계정이 아닌 곳으로 캠페인 공지가 가면 안 되기 때문입니다.

신청서: https://www.instagram.com/glowb.tester3/  →  정규화: glowb.tester3
인증:   glowb.tester3                             →  일치 → 통과
인증:   danielseo_test                            →  불일치 → 409 HANDLE_MISMATCH

URL 에서 핸들만 뽑아 비교합니다 — 프로토콜·도메인·뒤쪽 경로·쿼리를 걷어내고 첫 경로 조각만 남긴 뒤, @ 를 지우고 소문자로 맞춥니다. 트레일링 슬래시 하나로 매칭이 깨진 전례가 있어 끝의 슬래시도 지웁니다.

거절해도 토큰은 소모하지 않습니다. 잘못된 계정으로 한 번 눌렀다고 링크와 코드가 죽으면 재발급을 받아야 합니다. 크리에이터는 회신으로 어느 계정인지 안내받고 그대로 다시 시도하면 됩니다.

둘 다 있을 때만 판정합니다. 신청서 핸들이 비어 있거나(대조할 것이 없습니다) Graph 조회가 실패해 핸들을 못 얻은 경우(우리 쪽 사정입니다)는 통과시키고 handle_matched 를 null 로 남깁니다. 그것까지 막으면 크리에이터가 아무것도 할 수 없게 됩니다.

발송 주소가 둘이다

Graph API (릴레이)AutoDM (VM 엔진)
주소igsidusername (핸들)
결과동기, 즉시비동기, 콜백
속도즉시건당 40~90초, 인스턴스당 직렬
24시간 창걸림안 걸림

인증 기록에 IGSID 와 핸들을 둘 다 남기는 이유가 이것입니다. 핸들이 비어 있는 옛 기록은 AutoDM 으로 보낼 수 없습니다.

24시간 창

Graph API 는 상대가 마지막으로 말을 건 시점부터 24시간 안에서만 보낼 수 있습니다. 창 밖 발송 수단(One-Time Notification, Sponsored/Marketing Messages, message tag)은 인스타그램에서 폐기됐거나 제공되지 않습니다.

예약 알림은 인증하고 며칠~몇 주 뒤에 나가므로 창이 닫혀 있는 것이 정상입니다. 그래서 AutoDM 이 폴백이 아니라 사실상 주 경로입니다.

창이 열려 있는지는 서버가 계산하지 않습니다. 그냥 보내고 메타가 거절하면 그 사유를 그대로 올립니다 — 창을 따로 추적하면 실제와 어긋나는 순간 조용히 틀린 판정을 하게 됩니다.

알아둘 함정

새 계정은 아이스브레이커를 눌러도 ref 가 안 옵니다. 한 번도 우리에게 말을 건 적 없는 계정이 대화창의 버튼을 탭하면 메타가 그 postback 에 referral 을 싣지 않습니다(2026-09-07 서로 다른 계정 3회 실측). 게다가 그 탭으로 스레드가 이미 만들어져서 뒤이어 보내는 메시지에도 ref 가 붙지 않습니다. 링크를 다시 여는 것만이 복구 경로이고, 서버가 그렇게 안내합니다.

이미 스레드가 있으면 링크를 열 때마다 ref 가 옵니다. 같은 계정이 하루에 세 번 반복해서 받은 것을 확인했습니다. 24시간 창도 이때 리셋됩니다.

같은 인증에 이벤트가 두 번 옵니다. 링크를 열고 이어서 메시지를 보내면 같은 ref 로 referral 과 message 가 각각 옵니다. 두 번째는 토큰이 이미 소모돼 있으므로, IGSID 로 먼저 확인해 후속 이벤트를 가려냅니다. 안 그러면 방금 성공한 사람에게 "링크가 만료됐다"고 답하게 됩니다.

엔드포인트

메서드경로설명
POST/ai/influence/dm-link/token인증 링크 발급 (크리에이터 본인)
GET/ai/influence/dm-link/status인증 상태 조회 (크리에이터 본인)

릴레이가 인증 이벤트를 넘기는 내부 웹훅(/ai/webhooks/ig-dm/{secret}/verify)이 하나 더 있지만, 외부에서 부르는 자리가 아니라 문서로 두지 않습니다.

프론트 연동 방법은 연동 가이드를 보세요. 어드민 수동 발송은 DM 발송에 있습니다.

기능 플래그

Flagsmith ig_dm_verify_enabled 로 토큰 발급을 막을 수 있습니다. 꺼져 있으면 발급 요청이 거절되고, 이미 인증된 기록은 그대로 남습니다.

On this page