메인 콘텐츠로 건너뛰기

V2 웹훅 API

개요

V2 Webhooks API는 개발자가 웹훅 기반 JSON 메시지를 통해 X 계정에서 발생하는 실시간 이벤트 알림을 수신할 수 있게 합니다. 이 API를 사용하면 웹훅을 등록·관리하고 이벤트 처리용 컨슈머 애플리케이션을 개발하며, 챌린지-응답 검사(CRC)와 서명 헤더를 통해 안전한 통신을 보장할 수 있습니다.

기능 요약

티어가격웹훅 수
셀프 서비스 Pro월 $5,0001
엔터프라이즈영업팀에 문의5개 이상

Webhook을 지원하는 제품

현재 webhook으로 이벤트 전송을 지원하는 제품은 다음과 같습니다:

웹후크 관리

Account Activity API는 귀하의 서비스에 구독된 X 계정에서 이벤트가 발생할 때마다 웹후크 기반 JSON 메시지를 제공합니다. X는 이러한 활동을 등록된 웹후크로 전달합니다. 다음 단계에서는 웹후크와 구독 사용자 관리 방법을 알아봅니다. 웹후크와 구독 사용자를 등록, 조회, 제거하는 방법을 배우게 됩니다. 다양한 API 엔드포인트에 요청을 보내기 위해 간단한 cURL 명령을 사용할 것입니다. cURL은 URL 문법을 사용해 요청을 보내거나 가져오는 명령줄 도구입니다. 이벤트 컨슈머 애플리케이션에서 웹후크 이벤트를 받기 전에 살펴봐야 할 사항이 몇 가지 있습니다. 아래 설명처럼 X 앱을 생성하고 Account Activity API 액세스를 획득하며, 웹후크 이벤트를 소비하는 웹 앱을 개발해야 합니다. 

1. Webhook Consumer 앱 개발

X 앱에 연결된 새로운 webhook을 등록하려면 X webhook 이벤트를 수신하고 당사의 보안 요청에 응답할 수 있는 웹 앱을 개발·배포·호스팅해야 합니다. 시작하기 전에 샘플 앱을 확인해 보시길 권장합니다!
  • 이벤트를 수신하는 webhook 엔드포인트로 동작할, 공개적으로 접근 가능한 HTTPS URL을 가진 웹 앱을 만드세요.
  • 첫 단계로 X Challenge Response Check(CRC) GET 요청을 수신하고 올바르게 형식화된 JSON으로 응답하는 코드를 작성하세요.
  • webhook URL을 등록하세요. JSON 본문에 URL을 포함하여 /2/webhooks 엔드포인트에 POST 요청을 보냅니다. 이 요청을 보내면 X가 CRC 요청을 웹 앱으로 전송합니다.
  • webhook이 성공적으로 등록되면 응답에 webhook id가 포함됩니다. 이 webhook id는 이후 webhook을 지원하는 제품에 요청할 때 필요합니다.
  • X는 등록한 URL로 이벤트가 포함된 POST 요청을 전송합니다. 이러한 이벤트는 JSON으로 인코딩됩니다. webhook JSON 페이로드 예시는 여기에서 확인하세요.

선택 사항: 테스트용 xurl 사용

테스트를 위해 xurl 도구에서 이제 임시 웹훅을 지원합니다! GitHub에서 xurl 프로젝트의 최신 버전을 설치하고 권한을 구성한 뒤, 다음을 실행하세요:
xurl webhook start
이 작업은 임시 공개 웹후크(URL)를 생성하고, CRC 검사도 자동으로 처리하며, 수신되는 구독 이벤트를 모두 기록합니다. 배포 전에 설정을 확인하기에 훌륭한 방법입니다. 출력 예:
ngrok으로 웹훅 서버를 시작 중...
ngrok authtoken을 입력하세요(NGROK_AUTHTOKEN 환경 변수를 사용하려면 비워 두세요):

NGROK_AUTHTOKEN 환경 변수를 사용하여 ngrok 인증을 시도합니다.
ngrok을 구성하여 로컬 포트로 포워딩: 8080
ngrok 터널이 설정되었습니다!
  포워딩 URL: https://<your-ngrok-subdomain>.ngrok-free.app -> localhost:8080

X API 웹훅 등록에 이 URL을 사용하세요: https://<your-ngrok-subdomain>.ngrok-free.app/webhook

ngrok 터널(https://<your-ngrok-subdomain>.ngrok-free.app에서 포워딩)을 통해 들어오는 요청을 처리하기 위해 로컬 HTTP 서버를 시작하는 중...
중요 안내 사항
  • 웹훅 URL을 등록할 때 웹 앱은 CRC 검사 암호화를 위해 앱의 consumer secret을 사용해야 합니다.
  • 수신되는 모든 다이렉트 메시지는 웹훅으로 전달됩니다. POST /2/dm_conversations/with/:participant_id/messages로 전송된 다이렉트 메시지도 웹훅으로 전달됩니다. 이는 다른 클라이언트를 통해 전송된 다이렉트 메시지도 웹 앱이 파악할 수 있도록 하기 위함입니다.
  • 동일한 웹훅 URL을 공유하는 웹 앱이 둘 이상이고 각 앱에 동일한 사용자가 매핑되어 있는 경우, 동일한 이벤트가 웹 앱별로 한 번씩 웹훅에 여러 차례 전송됩니다.
  • 일부 경우 웹훅이 중복 이벤트를 수신할 수 있습니다. 웹훅 앱은 이를 허용하도록 설계되어야 하며 이벤트 ID를 기준으로 중복을 제거해야 합니다.
  • 예제 코드:
    • Account Activity API 설정: Account Activity API의 엔터프라이즈 티어를 사용해 웹훅 이벤트를 표시하는 Node 웹 앱.

2. 웹후크 보안

X의 웹후크 기반 API는 웹후크 서버의 보안을 확인하는 두 가지 방법을 제공합니다:
  1. 챌린지-응답 검사를 통해 웹후크 이벤트를 수신하는 웹 앱의 소유권을 X가 확인할 수 있습니다.
  2. 각 POST 요청의 서명 헤더를 통해 수신된 웹후크의 출처가 X임을 확인할 수 있습니다.
구현 요구 사항은 CRC 검사 섹션을 참조하세요.

3. Webhooks API

웹후크는 Webhook Management API를 통해 관리됩니다. 모든 엔드포인트에는 OAuth2 앱 전용 베어러 토큰 인증이 필요합니다. POST /2/webhooks 설명: 웹훅 구성을 생성합니다. 공개적으로 액세스 가능한 https 콜백 URL을 JSON 본문에 포함해 전달해야 합니다.
지정된 애플리케이션 컨텍스트에 대해 새 웹훅 URL을 등록하는 것부터 시작하겠습니다.
인증: OAuth2 앱 전용 베어러 토큰
  • 베어러 토큰 <BEARER_TOKEN> 예: AAAAAAAAAAAA0%2EUifi76ZC9Ub0wn...
매개변수 (JSON 본문):
{
    "url": "<공개적으로 접근 가능한 HTTPS 콜백 URL>"
}
  • URL <URL> 예: https://yourdomain.com/webhooks/twitter/
요청: 다음 항목을 수정한 후 아래 cURL 요청을 명령줄에 복사하세요:
  ```
  curl --request POST --url 'https://api.twitter.com/2/webhooks?url=<URL>' --header 'authorization: Bearer <BEARER_TOKEN>'
  --data '{
"url": "https://yourdomain.com/webhooks/twitter"
          }'
  ```
응답: 성공(200 OK) 성공적인 응답은 웹훅이 생성되었고 초기 CRC 검사에 통과했음을 의미합니다.
{
  "data": {
    "id": "<webhook_id>",
    "url": "<콜백 URL>",
    "valid": true,
    "created_at": "YYYY-mm-DDTHH:MM:ss.000Z"
  }
}
오류(400 Bad Request) 실패 시 표준 오류 객체를 반환합니다.
{
    "errors": [
      {
        "message": "<사유>: <세부사항>"
      }
    ],
    "title": "유효하지 않은 요청"
    "detail": "요청에 포함된 하나 이상의 매개변수가 유효하지 않습니다."
    "type": "https://api.twitter.com/2/problems/invalid-request"
}
실패의 일반적인 원인은 다음과 같습니다:
이유설명
CrcValidationFailed콜백 URL이 CRC 검사에 올바르게 응답하지 않았습니다(예: 타임아웃, 잘못된 응답).
UrlValidationFailed제공된 콜백 URL이 요건을 충족하지 않습니다(예: https가 아님, 형식이 올바르지 않음).
DuplicateUrlFailed해당 콜백 URL에 대해 애플리케이션에 이미 웹훅이 등록되어 있습니다.
WebhookLimitExceeded애플리케이션이 허용된 웹훅 구성의 최대 개수에 도달했습니다.
GET /2/webhooks 설명: 애플리케이션(개발자 계정)과 연관된 모든 웹훅 구성을 조회합니다. 인증: OAuth2 앱 전용 베어러 토큰
  • 베어러 토큰 <BEARER_TOKEN> 예: AAAAAAAAAAAA0%2EUifi76ZC9Ub0wn...
  • URL <URL> 예: https://yourdomain.com/webhooks/twitter/
요청: 다음 명령을 실행하여 해당 애플리케이션에 등록된 모든 웹훅 URL과 상태를 조회합니다. 아래 cURL 요청에서 필요한 값을 수정한 후 명령줄에 복사해 실행하세요:
  ```
  curl --request GET --url 'https://api.twitter.com/2/webhooks' --header 'authorization: Bearer <BEARER_TOKEN>'
  ```
성공(200 OK) Webhook 구성 목록을 반환합니다. 구성된 webhook이 없으면 목록은 비어 있습니다. 예시(웹훅 1개가 구성된 경우):
{
  "data": [
    {
      "created_at": "YYYY-mm-DDTHH:MM:ss.000Z",
      "id": "<webhook_id>",
      "url": "<콜백 URL>",
      "valid": true
    }
  ],
  "meta": {
    "result_count": 1
  }
}
예시(웹훅을 구성하지 않은 경우):
{
  "data": [],
  "meta": {
    "result_count": 0
  }
}
DELETE /2/webhooks/:webhook_id 설명: 특정 webhook_id를 사용해 웹훅 구성을 삭제합니다. ID는 POST /2/webhooks 생성 응답이나 GET /2/webhooks 목록 응답에서 확인할 수 있습니다. 인증: OAuth2 앱 전용 베어러 토큰
  • 베어러 토큰 <BEARER_TOKEN> 예: AAAAAAAAAAAA0%2EUifi76ZC9Ub0wn...
경로 매개변수:
매개변수설명
webhook_id삭제할 웹훅의 ID입니다.
요청: 다음 명령을 실행하여 지정한 애플리케이션의 구성에서 웹훅을 제거합니다. 아래 cURL 요청에서 필요한 값을 수정한 뒤 명령줄에 복사해 실행하세요:
  ```
  curl --request DELETE --url 'https://api.twitter.com/2/webhooks/:WEBHOOK_ID' --header 'authorization: Bearer <BEARER_TOKEN>'
  ```

  **응답**
성공 (200 OK) 삭제에 성공하면 “deleted” 상태가 true인 JSON 응답을 반환합니다. 예시(웹훅 삭제 성공 시):
{
  "data": {
    "deleted": true
  }
}
실패(400 Bad Request)
이유설명
WebhookIdInvalid제공된 webhook_id를 찾을 수 없거나 앱과 연결되어 있지 않습니다.
PUT /2/webhooks/:webhook_id 설명: 지정된 웹훅의 URL에 대해 CRC(Challenge Response Check)를 실행합니다. 검사에 성공하면 200을 반환하고 상태를 valid로 설정하여 웹훅을 재활성화합니다. 인증: OAuth2 앱 전용 베어러 토큰
  • 베어러 토큰 <BEARER_TOKEN> 예: AAAAAAAAAAAA0%2EUifi76ZC9Ub0wn...
경로 매개변수:
매개변수설명
webhook_id검증할 웹훅의 ID입니다.
요청: 제공된 애플리케이션 구성에서 웹훅을 검증하려면 다음 명령을 실행하세요. 아래 cURL 요청을 명령줄에 붙여넣기 전에 다음 항목을 변경하세요:
  ```
  curl --request PUT --url 'https://api.twitter.com/2/webhooks/:WEBHOOK_ID' --header 'authorization: Bearer <BEARER_TOKEN>'
  ```

  **응답**
성공(200 OK) 200 OK 응답은 CRC 검사 요청이 시작되었음을 나타냅니다. 이는 CRC 검사가 통과되었음을 보장하지 않습니다. 응답의 valid 필드는 검사 시도 이후의 상태를 반영합니다. CRC 검사가 성공하면 webhook의 상태가 valid로 업데이트됩니다. 현재 상태는 GET /2/webhooks로 확인할 수 있습니다.
{
  "data": {
    "valid": true // CRC 검사 시도 완료 후의 상태를 나타냅니다
  }
}
실패 (400 Bad Request)
이유설명
WebhookIdInvalid제공된 webhook_id를 찾을 수 없거나 앱과 연결되어 있지 않습니다.
CrcValidationFailed콜백 URL이 CRC 확인 요청에 올바르게 응답하지 않았습니다.

4. CRC 검사

Challenge Response Check(CRC)는 X가 제공하신 콜백 URL이 유효하며 해당 URL에 대한 제어 권한이 있음을 검증하는 방식입니다. CRC가 실행되는 시점:
  • 웹훅을 처음 등록할 때 (POST /2/webhooks)
  • X에서 매시간 유효성 검사를 수행할 때
  • PUT /2/webhooks/:id로 수동 검증을 실행할 때
예시:
GET https://your-webhook-url.com/webhook?crc_token=challenge_string
JSON 응답 본문 예시:
{
  "response_token": "sha256=<base64로_인코딩된_hmac_해시>"
}
응답을 구성하는 방법:
  • 메시지로 crc_token을 사용합니다.
  • 키로 앱의 consumer secret을 사용합니다.
  • HMAC-SHA-256 해시를 생성합니다.
  • 결과를 Base64로 인코딩합니다.

샘플 앱