메인 콘텐츠로 건너뛰기
이 엔드포인트는 게시물 수정 메타데이터가 포함되도록 업데이트되었습니다. 이러한 메타데이터에 대해 더 알아보려면 “Edit Posts” 기본 사항 페이지를 참고하세요. 이 엔드포인트는 Direct Messages 엔드포인트와 함께 자주 사용됩니다. 새로운 v2 Direct Messages 엔드포인트를 출시했습니다. Enterprise 및 Premium Account Activity API는 v2 일대일 Direct Message는 지원하지만, 아직 그룹 대화는 지원하지 않습니다.   
개요 Enterprise Account Activity API를 사용하면 웹훅(webhook)을 통해 사용자 계정과 관련된 실시간 활동을 구독할 수 있습니다. 이를 통해 소유하거나 구독 중인 하나 이상의 계정에서 단일 연결을 통해 실시간 게시물, Direct Message 및 기타 계정 이벤트를 수신할 수 있습니다. 웹훅 등록에서 각 사용자 구독에 대해 아래의 모든 관련 활동을 수신하게 됩니다:
Activity types
* 게시물(사용자 작성)

* 게시물 삭제(사용자 수행)
* @언급(사용자 대상)
* 답글(사용자가 보내거나 받는 경우)
* 리트윗(사용자가 하거나, 사용자를 대상으로 하는 경우)
* 인용 Tweet(사용자가 하거나, 사용자를 대상으로 하는 경우)
* 인용 Tweet의 리트윗(사용자가 하거나, 사용자를 대상으로 하는 경우)
* 좋아요(사용자가 하거나, 사용자를 대상으로 하는 경우)
* 팔로우(사용자가 하거나, 사용자를 대상으로 하는 경우)

* 언팔로우(사용자 수행)
* 차단(사용자 수행)
* 차단 해제(사용자 수행)
* 뮤트(사용자 수행)
* 뮤트 해제(사용자 수행)
* Direct Message 전송(사용자 발신)
* Direct Message 수신(사용자 수신)
* 입력 표시기(사용자 대상)
* 읽음 확인(사용자 대상)
* 구독 해지(사용자 수행)
참고 - Account Activity API를 통해 홈 타임라인 데이터를 제공하지 않습니다. 이 데이터를 가져오려면 GET statuses/home_timeline을 사용하세요.  

동영상 시리즈

Account Activity API를 빠르게 파악하려면 4부작 동영상 시리즈를 시청해 보세요!

기능 요약

티어가격고유 구독 수웹훅 개수신뢰성 및 Activity Recovery
Enterprise영업팀에 문의500개 이상3개 이상재시도 및 Replay

웹훅 및 구독 사용자 관리

⏱ 읽는 데 10분 Enterprise Account Activity API는 귀하의 서비스에 구독된 X 계정과 관련된 이벤트가 발생할 때마다 웹훅 기반 JSON 메시지를 제공합니다. X는 이러한 활동을 귀하가 등록한 웹훅으로 전달합니다. 다음 단계에서는 웹훅과 구독 사용자를 관리하는 방법을 알아봅니다. 웹훅과 구독 사용자를 등록, 조회, 삭제하는 방법을 배우게 됩니다. 다양한 API 엔드포인트에 요청을 보내기 위해 간단한 cURL 명령을 사용할 것입니다. cURL은 URL 구문을 사용해 요청을 보내거나 가져오는 명령줄 도구입니다. 다음이 필요합니다: 시작하기 전에 X의 Account Activity API를 시작하는 데 도움이 되는 샘플 웹 앱과 헬퍼 스크립트를 제공하는 Github 리포지토리를 확인할 것을 권장합니다.

웹훅 관리하기

웹훅을 사용하면 단일 연결을 통해 특정 사용자 계정과 관련된 실시간 활동을 구독할 수 있습니다. 
주어진 애플리케이션 컨텍스트에 대해 새 웹훅 URL을 등록하는 것부터 시작하겠습니다.저장 전에 CRC 요청을 통해 URL이 검증됩니다. 웹훅을 등록한 후에는 나중에 필요하므로 웹훅 ID를 반드시 기록해 두세요.아래 cURL 요청에서 다음 값을 수정한 뒤, 명령줄에 복사해 실행하세요.
  • URL <URL> 예: https://yourdomain.com/webhooks/twitter/
  • Consumer key <CONSUMER_KEY> 예: xvz1evFS4wEEPTGEFPHBog
  • Access token <ACCESS_TOKEN> 예:  370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb
    curl --request POST --url 'https://api.x.com/1.1/account_activity/webhooks.json?url=<URL>' --header 'authorization: OAuth oauth_consumer_key="<CONSUMER_KEY>", oauth_nonce="GENERATED", oauth_signature="GENERATED", oauth_signature_method="HMAC-SHA1", oauth_timestamp="GENERATED", oauth_token="<ACCESS_TOKEN>", oauth_version="1.0"'
    

구독된 사용자 관리:

Webhook을 등록한 후 해당 사용자의 계정 활동을 수신하려면 Account Activity API에 구독된 사용자를 추가할 수 있습니다.
모든 이벤트 유형을 수신할 수 있도록 사용자를 구독시키는 것부터 시작하겠습니다.다음 항목을 변경한 뒤 아래 cURL 요청을 명령줄에 복사해 실행하세요:
  • Webhook ID <:WEBHOOK_ID> 예: 1234567890
  • Consumer key 이름 <CONSUMER_KEY> 예: xvz1evFS4wEEPTGEFPHBog
  • 구독 중인 사용자의 access token <SUBSCRIBING_USER'S_ACCESS_TOKEN> 예: 370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb
    curl --request POST --url https://api.x.com/1.1/account_activity/webhooks/<:WEBHOOK_ID>/subscriptions/all.json --header 'authorization: OAuth oauth_consumer_key="<CONSUMER_KEY>", oauth_nonce="GENERATED", oauth_signature="GENERATED", oauth_signature_method="HMAC-SHA1", oauth_timestamp="GENERATED", oauth_token="<SUBSCRIBING_USER'S_ACCESS_TOKEN>", oauth_version="1.0"'
    
이제 webhook과 구독된 사용자를 관리할 수 있습니다.

참고 문서

Account Activity API 동영상 가이드

이 동영상 가이드에서는 Account Activity API의 프리미엄 및 엔터프라이즈 티어에서 제공하는 기능을 살펴봅니다. 이 동영상을 모두 시청하면 다음 기능을 익히게 됩니다.
  • 웹훅 등록
  • 사용자 구독 추가
  • 사용자 구독 제거
  • 계정 활동 수신
  • 계정 활동 재생
Enterprise

웹훅 시작하기

Account Activity API는 여러분이 직접 개발·배포·호스팅하는 웹 앱으로 계정 이벤트를 전송하는 웹훅 기반 API입니다.  이벤트 consumer 애플리케이션에서 웹훅 이벤트를 수신하기 전에 먼저 설정해야 할 ‘기초(plumbing)’ 관련 세부 사항이 몇 가지 있습니다. 아래에 설명된 것처럼, X App을 생성하고 Account Activity API 액세스 권한을 얻은 다음, 웹훅 이벤트를 처리하는 웹 앱을 개발해야 합니다. 

1. X 앱을 생성합니다.

  • 개발자 콘솔에서 승인된 개발자 계정으로 X app을 생성합니다. 회사를 대신해 앱을 만드는 경우에는 회사용 X 계정으로 앱을 생성하는 것을 권장합니다. 개발자 계정을 신청하려면 여기를 클릭하세요.
  • 앱 페이지의 permissions 탭에서 “Read, Write and Access direct messages” 권한을 활성화합니다.
  • “Keys and Access Tokens” 탭에서 앱의 Consumer Key(API Key)와 Consumer Token(API Secret)을 기록해 둡니다.
  • 같은 탭에서 앱의 Access Token 및 Access Token Secret을 생성합니다. 이 Access Token은 X가 계정 이벤트를 전송하는 webhook URL을 등록할 때 필요합니다.
  • X Sign-in 및 X API에서 사용자 컨텍스트가 어떻게 동작하는지 잘 모른다면, Access Tokens 획득을 확인하세요. 이벤트를 수신할 계정을 추가할 때, 해당 계정의 Access Token을 사용해 구독하게 됩니다.
  • 개발자 콘솔“Apps” 페이지에 표시되는 앱의 숫자형 ID를 기록해 둡니다. Account Activity API 액세스를 신청할 때 이 앱 ID가 필요합니다.  

2. Account Activity API 접근 권한 받기

X App을 생성한 후 다음 단계는 Account Activity API 접근 권한을 신청하는 것입니다.  Account Activity API는 Enterprise에서만 사용할 수 있으므로, 아래 링크를 통해 신청서를 제출해야 합니다.

3. 웹훅 컨슈머 앱 개발

Account Activity API 액세스 권한을 받으면, X 웹훅 이벤트를 수신할 웹 앱을 개발·배포·호스팅해야 합니다. 
  • 이벤트를 수신하기 위한 웹훅 엔드포인트로 사용할 URL을 가진 웹 앱을 만듭니다. 이는 서버에 배포되어 들어오는 X 웹훅 이벤트를 수신(listen)하는 엔드포인트입니다. 
  • Securing Webhooks 가이드에서 설명한 것처럼, 첫 단계는 X Challenge Response Check(CRC) GET 요청을 수신하고, 올바르게 포맷된 JSON 응답을 반환하는 코드를 작성하는 것입니다. 
  • 웹훅 URL을 등록하세요. /webhooks.json?url= 엔드포인트에 POST 요청을 보내게 됩니다. 이 요청을 보내면 X가 웹 앱으로 CRC 요청을 전송합니다. 웹훅이 성공적으로 등록되면 응답에 웹훅 id가 포함됩니다. 이 웹훅 id는 이후 Account Activity API에 일부 요청을 보낼 때 필요합니다. 
  • X는 등록한 URL로 계정 웹훅 이벤트를 전송합니다. 웹 앱이 수신 이벤트에 대한 POST 요청을 지원하는지 확인하세요. 이 이벤트는 JSON으로 인코딩되어 전달됩니다. 예제 웹훅 JSON 페이로드는 여기를 참고하세요.
  • 웹 앱이 준비되면, 다음 단계는 활동을 수신할 계정을 추가하는 것입니다. 계정을 추가(또는 삭제)할 때는 계정 id를 참조하는 POST 요청을 보내게 됩니다. 자세한 내용은 구독 추가 가이드를 참고하세요.

4. 설정 검증

  • 앱과 webhook이 올바르게 구성되었는지 확인하려면, 앱이 구독하고 있는 X 계정 중 하나가 작성한 게시물에 마음에 들어요 표시를 하세요. 구독 중인 계정이 받은 각 즐겨찾기(Favorite)에 대해 webhook URL로 전송되는 POST 요청을 통해 favorite_events를 수신해야 합니다.
  • 구독이 추가된 후 이벤트가 전달되기 시작하기까지 최대 10초 정도 소요될 수 있습니다.
중요 참고 사항
  • webhook URL을 등록할 때, 웹 앱은 consumer token과 secret, 그리고 앱 소유자의 사용자 액세스 토큰과 시크릿 으로 인증해야 합니다. 
  • 수신되는 모든 다이렉트 메시지는 webhook을 통해 전달됩니다. 또한 POST direct_messages/events/new (message_create)를 통해 전송된 모든 다이렉트 메시지도 webhook을 통해 전달됩니다. 이는 웹 앱이 다른 클라이언트를 통해 전송된 다이렉트 메시지도 인지할 수 있도록 하기 위함입니다.
  • 모든 webhook 이벤트에는 해당 이벤트가 어떤 구독에 대해 전달되었는지를 나타내는 for_user_id 사용자 ID가 포함되어 있다는 점에 유의하세요.
  • 동일한 대화에서 두 사용자가 다이렉트 메시지용으로 웹 앱을 사용하고 있는 경우, webhook은 두 개의 중복 이벤트(각 사용자당 하나씩)를 받게 됩니다. 웹 앱은 이를 고려해야 합니다. 
  • 동일한 webhook URL을 공유하는 둘 이상의 웹 앱이 있고 동일한 사용자가 각 앱에 매핑되어 있는 경우, 동일한 이벤트가 webhook으로 여러 번(웹 앱당 한 번씩) 전송됩니다.
  • 일부 경우에는 webhook이 중복 이벤트를 수신할 수 있습니다. webhook 앱은 이에 대해 허용적이어야 하며 이벤트 ID를 기준으로 중복을 제거해야 합니다.
  • 퀵 리플라이(Quick Reply) 응답이 요청 직후에 바로 이어질 것이라고 가정하지 마세요. 사용자는 퀵 리플라이 요청을 무시하고 일반 다이렉트 메시지로 응답할 수 있습니다. 또한 사용자는 메시지 스레드에서 이전에 응답하지 않았던 요청에 대해 나중에 퀵 리플라이 응답을 제공할 수도 있습니다.
  • 예제 코드를 참고하세요:
    • Enterprise Account Activity API dashboard는 Account Activity API의 엔터프라이즈 티어를 사용해 webhook 이벤트를 표시하고, Replay 기능을 포함하는 Node 기반 웹 앱입니다.
    • SnowBot chatbot은 Account Activity API와 다이렉트 메시지 API를 기반으로 구축된 Ruby 웹 앱입니다. 이 코드베이스에는 Account Activity API webhook 설정을 돕기 위한 스크립트가 포함되어 있습니다.

웹훅 보안 확보

X의 웹훅 기반 API는 웹훅 서버의 보안을 확인하기 위한 두 가지 방법을 제공합니다.
  1. 챌린지-응답 검사를 통해 웹훅 이벤트를 수신하는 웹 앱의 소유권을 X가 확인할 수 있습니다. 
  2. 각 POST 요청의 서명 헤더를 통해 수신된 웹훅의 발신자가 X인지 확인할 수 있습니다.  

Challenge-Response Checks

앱과 webhook URL의 소유자가 모두 여러분임을 검증하기 위해 X는 Challenge-Response Check(CRC)를 수행합니다. 이는 순환 중복 검사(cyclic redundancy check)와 혼동하면 안 됩니다. CRC가 전송되면 X는 ;crc_token 파라미터를 포함하여 웹 앱에 GET 요청을 보냅니다. 해당 요청을 수신하면 웹 앱은 crc_token 파라미터와 앱의 Consumer Secret(아래 상세 참고)을 기반으로 암호화된 response_token을 생성해야 합니다. response_token은 JSON으로 인코딩되어야 하며(아래 예시 참고), 3초 이내에 반환되어야 합니다. 성공하면 webhook id가 반환됩니다.  webhook URL을 등록할 때 CRC가 전송되므로, CRC 응답 코드를 구현하는 것은 필수적인 첫 단계입니다. webhook이 설정된 이후에는 마지막으로 성공적인 응답을 받은 시점으로부터 대략 24시간마다 X가 CRC를 트리거합니다. 또한, 필요한 경우 webhook id를 사용해 PUT 요청을 보내 CRC를 트리거할 수도 있습니다. CRC를 트리거하는 것은 webhook 애플리케이션을 개발하는 동안이나 새 코드를 배포한 후, 서비스를 재시작한 후에 유용합니다.  _crc_token_은 들어오는 각 CRC 요청마다 변경될 것으로 예상해야 하며, Consumer Secret을 키로 사용하는 계산에서 메시지로 사용되어야 합니다. 응답이 3초 이내에 전송되지 않거나 유효하지 않게 되는 경우, 등록된 webhook으로 이벤트 전송이 중단됩니다.

CRC 요청은 다음과 같은 경우에 발생합니다:

  • webhook URL이 등록될 때.
  • webhook URL을 검증하기 위해 대략 매시간 한 번씩.
  • PUT 요청을 보내 CRC를 수동으로 발생시킬 수 있습니다. webhook 클라이언트를 개발할 때는 CRC 응답을 구현하는 동안 CRC를 수동으로 발생시키는 방식을 함께 계획해야 합니다.   

응답 요구 사항:

  • crc_token과 App Consumer Secret에서 생성된 base64 인코딩 HMAC-SHA-256 해시
  • 유효한 response_token 값과 JSON 형식
  • 3초 미만의 지연 시간
  • HTTP 200 응답 코드  

각 언어별 HMAC 라이브러리:

Python에서의 응답 토큰 생성 예제:

다음은 Python 2.7과 Flask로 작성된 웹앱에서 챌린지-응답 검증(challenge-response check)에 올바르게 응답하는 라우트를 정의한 예시입니다.
import base64
import hashlib
import hmac
import json


\# Defines a route for the GET request
@app.route('/webhooks/twitter', methods=\['GET'\])
def webhook_challenge():

  # 수신 토큰과 컨슈머 시크릿으로 HMAC SHA-256 해시를 생성합니다
  sha256\_hash\_digest = hmac.new(TWITTER\_CONSUMER\_SECRET, msg=request.args.get('crc_token'), digestmod=hashlib.sha256).digest()

  # base64 인코딩된 해시로 응답 데이터를 구성합니다
  response = {
    'response\_token': 'sha256=' + base64.b64encode(sha256\_hash_digest)
  }

  # 올바른 형식의 JSON 응답을 반환합니다
  return json.dumps(response)

예시 JSON 응답:

위와 같이 라우트를 정의했다면, 웹 브라우저에서 https://your-app-domain/webhooks/twitter?crc&#95;token=foo 로 접속할 때 웹 앱은 아래와 유사한 응답을 반환해야 합니다.
{
  "response_token": "sha256=x0mYd8hz2goCTfcNAaMqENy2BFgJJfJOb4PdvTffpwg="
}

다른 예시:

  • 여기는 Node/JS로 작성된 CRC 응답 메서드 예시입니다.
  • 여기는 Ruby로 작성된 CRC 응답 메서드 예시입니다(generate_crc_response 및 CRC 이벤트를 수신하는 /GET 라우트를 참고하세요).

선택적 시그니처 헤더 유효성 검증

X에서 POST 요청을 수신하거나, 웹훅을 생성하기 위해 GET 요청을 보내거나, 수동 CRC를 수행하기 위해 GET 요청을 보낼 때, 헤더의 x-twitter-webhooks-signature 로 해시 시그니처가 전달됩니다. 이 시그니처를 사용하여 데이터의 출처가 X인지 검증할 수 있습니다. POST 해시 시그니처는 sha256=로 시작하며, 이는 HMAC SHA-256을 사용해 X App의 Consumer Secret과 페이로드를 암호화했음을 의미합니다. GET 해시는 쿼리 파라미터 문자열 crc_token=$token&nonce=$nonce 를 기반으로 계산됩니다.  요청을 검증하는 단계
  1. consumer secret과 수신한 페이로드 본문을 사용하여 해시를 생성합니다.
  2. 생성한 해시를 base64로 인코딩된 x-twitter-webhooks-signature 값과 비교합니다. 타이밍 공격에 대한 취약성을 줄이기 위해 compare_digest와 같은 메서드를 사용하세요.

추가 보안 지침

다음은 웹 애플리케이션을 위해 고려해야 할 추가 보안 지침입니다. 이러한 지침을 적용하지 않았더라도 webhook이 동작하지 않는 것은 아니지만, X 정보보안팀에서 강력히 권장하는 사항입니다. 아래 권장 사항에 익숙하지 않다면 서버 관리자에게 문의하세요.

X 집계 네트워크 블록

보안을 강화하기 위해 다음 집계 네트워크 블록을 허용 목록(allowlist)에 추가하는 것을 고려하시기 바랍니다:
  • 199.59.148.0/22
  • 199.16.156.0/22
  • 192.133.77.0/26
  • 64.63.15.0/24
  • 64.63.31.0/24
  • 64.63.47.0/24
  • 202.160.128.0/24
  • 202.160.129.0/24
  • 202.160.130.0/24
  • ssllabs.com 테스트에서 “A” 등급
  • TLS 1.2 활성화
  • Forward Secrecy 활성화
  • SSLv2 비활성화
  • SSLv3 비활성화 (POODLE 취약점 때문에)
  • TLS 1.0 비활성화
  • TLS 1.1 비활성화
  • TLS 압축 비활성화
  • 세션 티켓 키를 주기적으로 교체하지 않는 한 Session Tickets 비활성화
  • SSL 구성에서 “ssl_prefer_server_ciphers” 또는 “SSLHonorCipherOrder” 옵션을 “on”으로 설정
  • 암호 스위트 목록이 다음과 같은 최신 목록인지 확인: ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:DES-CBC3-SHA

웹훅 및 구독 관리

웹훅 생성 및 변경

웹훅 URL을 변경하려면 기존 웹훅을 삭제한 다음 새 웹훅을 생성해야 합니다. 이때 새 웹훅에 사용자 구독을 다시 추가해야 합니다.

Webhook 구성 관리 엔드포인트:

MethodEnterprise
webhook URL을 등록하고 webhook_id를 생성POST webhooks
모든 webhook URL과 해당 상태를 반환GET webhooks
App의 현재 webhook 구성을 삭제DELETE webhooks/:webhook_id
CRC 요청을 수동으로 실행PUT webhooks/:webhook_id

웹훅 URL만 업데이트하면 안 되나요?

왜 웹훅 구성은 한 번 생성하면 변경할 수 없게(immutable) 되어 있나요? X는 보안을 매우 중요하게 생각합니다. 웹훅 URL이 변경되었다면, 애플리케이션의 consumer key와 consumer secret이 유출되었을 가능성이 있습니다. 새 웹훅 구성을 만들도록 요구하는 것은, 동시에 사용자 이벤트를 다시 구독하도록 요구하는 것입니다. 이 과정에는 악의적인 제3자가 보유하고 있을 가능성이 낮은 access token을 사용해야 합니다. 그 결과, 다른 사람이 사용자의 비공개 정보를 받아볼 가능성이 줄어듭니다.  

사용자 구독 추가 및 제거

수천 개의 구독을 지원하는 기능은 Enterprise 티어에서 제공됩니다. 이미 계정 매니저가 있다면, 문의 사항이 있을 때 해당 매니저에게 연락하시기 바랍니다. Enterprise API 액세스를 신청하려면 여기를 클릭하세요. 

구독 관리 엔드포인트

메서드Enterprise
새 사용자 구독 추가POST webhooks/:webhook_id/subscriptions/all
사용자 구독 조회GET webhooks/:webhook_id/subscriptions/all
모든 활성 구독 목록을 반환GET webhooks/:webhook_id/subscriptions/all/list
애플리케이션 전용 OAuth를 사용하여 사용자 구독 비활성화DELETE webhooks/:webhook_id/subscriptions/:user_id/all.json
Account Activity API: Enterprise
주의API를 사용하기 전에 X가 개발자 App에 대해 Account Activity API 액세스를 먼저 활성화해야 합니다. 이를 위해, 인증에 사용할 예정인 App ID를 계정 관리자 또는 기술 지원팀과 반드시 공유해 주세요.
Account Activity API는 단일 연결을 통해 구독된 모든 계정에 대한 실시간 계정 활동을 수신할 수 있도록, 사용자 구독을 생성하고 관리하는 일련의 엔드포인트로 구성됩니다.  Account Activity API에서는 두 가지 인증 방법(OAuth 1.0aOAuth 2.0 Bearer Token)을 사용할 수 있습니다. 어떤 인증 방법을 사용해야 하는지는 사용하는 엔드포인트에 따라 달라집니다.
Description**Endpoint **OAuth 1.0a
(user context)
OAuth 2.0 Bearer Token (application-only)
지정된 애플리케이션 컨텍스트에 대해 새로운 webhook URL을 등록합니다POST account_activity/webhooks
지정된 애플리케이션에 대한 모든 URL과 해당 상태를 반환합니다GET account_activity/webhooks
지정된 webhook URL에 대해 챌린지 응답 검사(CRC)를 트리거합니다PUT account_activity/webhooks/:webhook_id
애플리케이션을 사용자의 계정 이벤트에 구독하도록 합니다POST account_activity/webhooks/:webhook_id/subscriptions/all✓ *
현재 활성 구독 수를 반환합니다GET account_activity/subscriptions/count
webhook 구성이 사용자의 이벤트를 구독하고 있는지 확인합니다GET account_activity/webhooks/:webhook_id/subscriptions/all✓ *
현재 활성 구독 목록을 반환합니다GET account_activity/webhooks/:webhook_id/subscriptions/all/list
webhook을 삭제합니다DELETE account_activity/webhooks/:webhook_id
[DEPRECATED] 제공된 사용자 컨텍스트와 애플리케이션에 대한 구독을 비활성화합니다DELETE account_activity/webhooks/:webhook_id/subscriptions/all✓ *
애플리케이션 전용 OAuth(application-only OAuth)를 사용해 구독을 비활성화합니다DELETE /account_activity/webhooks/:webhook_id/subscriptions/:user_id/all.json
활동을 webhook으로 다시 전달합니다POST /1.1/account_activity/replay/webhooks/:webhook_id/subscriptions/all.json
*_ 인증에는 구독하는 사용자의 액세스 토큰이 필요합니다. _ OAuth 1.0a 사용자 컨텍스트 인증이 필요한 엔드포인트의 경우, 요청을 인증하기 위해 다음 자격 증명을 제공해야 합니다. 
  • Consumer Key (API Key 및 Secret)
  • Access Token (Access Token 및 Secret)
다음 세 가지 엔드포인트의 경우, 애플리케이션 컨텍스트 내에서 쓰기 작업을 수행합니다(X 사용자는 관여하지 않습니다). 따라서 제공해야 하는 Access Token은 개발자 App에 속한 토큰입니다. 이는 Developer Console에서 해당 App의 “Keys and tokens” 탭을 통해 직접 생성할 수 있습니다.   반면, 다음의 세 엔드포인트의 경우에는 애플리케이션이 X 사용자(예: 다이렉트 메시지)의 보호된 데이터에 그 사용자를 대신하여 액세스할 수 있도록 요청하게 됩니다. 따라서 해당 구독 사용자에게 속한 Access Token을 제공해야 합니다. 필요한 Access Token은 3-legged OAuth 플로우를 사용하여 얻을 수 있습니다(OAuth 1.0a: how to obtain a user’s Access Tokens 참조). 이 엔드포인트들은 위의 표에서 별표(*)로 표시되어 있습니다.
유의하세요개발자 App이 “Read, Write, and Direct Messages”에 대해 활성화되어 있는지 확인하세요. 이 설정은 개발자 계정의 Projects & Apps 섹션에서 선택한 개발자 App의 “App permissions” 아래에서 변경할 수 있습니다. 권한 설정을 변경한 후에는 App 자격 증명을 다시 생성해야 합니다.
Account Activity API로 사용할 수 있는 모든 엔드포인트의 목록은 API 참조 문서에서 확인할 수 있습니다. 여기에는 각 엔드포인트에 대한 설명과, 인증 구현 예제를 포함한 예시 cURL 요청이 포함됩니다. 추가 정보는 Enterprise Account Activity API를 시작하는 데 도움이 되는 XDev의 샘플 웹 앱 및 헬퍼 스크립트를 참고하세요.
유의하세요Account Activity API를 사용하기 전에 X에서 개발자 App에 대해 Account Activity API 액세스를 활성화해야 합니다. 이를 위해, 인증 목적으로 사용하려는 App ID를 계정 매니저 또는 기술 지원 팀에 반드시 공유하세요.
Account Activity API는 단일 연결을 통해 구독한 모든 계정에 대한 실시간 계정 활동을 수신할 수 있도록, 사용자 구독을 생성하고 관리할 수 있게 해 주는 일련의 엔드포인트로 구성되어 있습니다.  Account Activity API에서는 두 가지 인증 방법(OAuth 1.0aOAuth 2.0 Bearer Token)을 사용할 수 있습니다. 어떤 인증 방법을 사용해야 하는지는 사용 중인 엔드포인트에 따라 달라집니다.
Description**Endpoint **OAuth 1.0a
(user context)
OAuth 2.0 Bearer Token (application-only)
지정된 애플리케이션 컨텍스트에 대해 새로운 webhook URL을 등록합니다POST account_activity/webhooks
지정된 애플리케이션에 대한 모든 URL과 해당 상태를 반환합니다GET account_activity/webhooks
지정된 webhook의 URL에 대해 CRC(Challenge Response Check)를 실행합니다PUT account_activity/webhooks/:webhook_id
애플리케이션을 사용자의 계정 이벤트에 구독하도록 등록합니다POST account_activity/webhooks/:webhook_id/subscriptions/all✓ *
현재 활성화된 구독 수를 반환합니다GET account_activity/subscriptions/count
webhook 구성이 사용자의 이벤트를 구독 중인지 확인합니다GET account_activity/webhooks/:webhook_id/subscriptions/all✓ *
현재 활성화된 구독 목록을 반환합니다GET account_activity/webhooks/:webhook_id/subscriptions/all/list
webhook을 삭제합니다DELETE account_activity/webhooks/:webhook_id
[DEPRECATED] 제공된 사용자 컨텍스트 및 애플리케이션에 대한 구독을 비활성화합니다DELETE account_activity/webhooks/:webhook_id/subscriptions/all✓ *
application-only OAuth를 사용하여 구독을 비활성화합니다DELETE /account_activity/webhooks/:webhook_id/subscriptions/:user_id/all.json
활동을 webhook으로 다시 전송합니다POST /1.1/account_activity/replay/webhooks/:webhook_id/subscriptions/all.json
*_ 인증에는 해당 구독을 생성한 사용자의 액세스 토큰이 필요합니다. _ OAuth 1.0a 사용자 컨텍스트 인증이 필요한 엔드포인트에서는, 요청을 인증하기 위해 다음 자격 증명을 제공해야 합니다. 
  • Consumer Keys (API Key 및 Secret)
  • Access Tokens (Access Token 및 Secret)
다음 세 개의 엔드포인트의 경우, 애플리케이션 컨텍스트 내에서 쓰기 작업을 수행합니다(X 사용자는 관여하지 않습니다). 따라서 제공해야 하는 Access Token은 개발자 App에 소속된 토큰입니다. 이 토큰은 Developer Console의 App에 대한 “Keys and tokens” 탭에서 직접 생성할 수 있습니다.   반면, 다음 세 개의 엔드포인트의 경우에는 애플리케이션이 X 사용자를 대신해 보호된 데이터(예: Direct Messages)에 접근할 수 있도록 요청을 보내게 됩니다. 따라서 해당 구독 사용자에게 속한 액세스 토큰을 제공해야 합니다. 필요한 액세스 토큰은 3-legged OAuth 플로우를 사용해 얻을 수 있습니다(OAuth 1.0a: how to obtain a user’s Access Tokens 참고). 이 엔드포인트들은 위 표에서 별표(*)로 표시되어 있습니다.
유의사항개발자 App이 “Read, Write, and Direct Messages.”에 대해 활성화되어 있는지 확인하세요. 이 설정은 개발자 계정의 Projects & Apps 섹션에서, 선택한 개발자 App의 “App permissions” 아래에서 변경할 수 있습니다. 권한 설정을 변경한 후에는 App 자격 증명을 다시 생성해야 합니다.
Account Activity API에서 사용할 수 있는 모든 엔드포인트 목록(관련 설명과 인증 구현 예시가 포함된 cURL 예제 요청 포함)은 API 참조 문서에서 확인할 수 있습니다. 추가 정보는 Enterprise Account Activity API를 시작하는 데 도움이 되는 XDev의 샘플 웹 앱 및 헬퍼 스크립트를 참고하세요.

재시도

Enterprise Account Activity API 엔터프라이즈 티어의 장점 중 하나는 웹훅 이벤트에 대한 재시도 메커니즘입니다. ‘성공’을 의미하는 200 HTTP 응답 코드를 수신하지 못하면 X 서버는 재시도 메커니즘을 시작하여 5분 동안 최대 세 번까지 웹훅 이벤트를 다시 전송합니다. 이 웹훅 이벤트 재시도 서비스는 네트워크 문제가 발생했을 때와 클라이언트 측 서비스 중단 및 배포 작업 중에 안정성과 이벤트 복구를 향상하는 데 도움이 됩니다.  

재시도란 무엇인가요?

Account Activity API는 클라이언트 웹 앱이 계정 활동 webhook 이벤트에 대해 ‘성공’ 200 응답을 반환하지 않을 때 재시도 기능을 제공합니다. 클라이언트 측에서 이벤트를 성공적으로 수신했음을 확인하지 않으면 X는 해당 이벤트가 수신되지 않은 것으로 간주합니다. 200이 아닌 응답을 받거나, 3초 이내에 응답이 없거나, 아예 응답이 수신되지 않는 경우 요청을 재시도하고, 각 요청에 대해 3초 동안 응답을 기다립니다. 이는 두 번의 시도 동안 총 약 5초 정도의 시간이 주어지며, 이 시간 안에 X가 귀하의 webhook URL로 전송하려는 활동(activity)에 대해 응답해야 한다는 의미입니다. 서버가 응답하지 않거나 일시적인 오류를 반환하는 경우 X는 5분 동안 재시도를 계속합니다. 유효성 확인을 위해 총 세 번의 재시도 시도가 이루어집니다. 이를 통해 중복성을 확보하고 모든 webhook 이벤트를 수신할 수 있도록 보장합니다. 재시도가 활성화된 구독의 경우, 해당 webhook에 대해 구독된 모든 사용자에 대한 모든 활동(어떤 유형의 활동이든)에 대해 재시도된 이벤트를 수신하게 됩니다. 이 여덟 번의 시도 내에 유효성을 확인하지 못하면, 해당 활동은 더 이상 Account Activity API를 통해 제공되지 않습니다. 

재시도 타임라인

Account Activity API는 200 응답을 받을 때까지 최대 5분 동안 최대 세 번 재시도합니다. 자세한 내용은 아래 표를 참고하세요. 약 5분이 지나면 해당 활동은 Account Activity API를 통해 다시 전송할 수 없습니다. 누락된 데이터를 수집하려면 다른 X 엔드포인트를 사용해야 합니다. 예를 들어 검색 API를 사용해 관련 포스트, 리트윗, 인용 트윗, 멘션, 답글을 가져올 수 있습니다. 누락된 다이렉트 메시지는 이 엔드포인트를 사용해 가져올 수 있습니다.

재시도 타임라인

활동이 생성되면 Account Activity API가 webhook URL로 POST 요청을 보내고, 3초 후에 타임아웃됩니다.
이전 타임아웃이 끝난 뒤 3초를 기다렸다가, Account Activity API가 webhook URL로 POST 요청을 보내고 3초 후에 타임아웃됩니다.
이전 타임아웃이 끝난 뒤 27초를 기다렸다가, Account Activity API가 webhook URL로 POST 요청을 보내고 3초 후에 타임아웃됩니다.
이전 타임아웃이 끝난 뒤 242초를 기다렸다가, Account Activity API가 webhook URL로 POST 요청을 보내고 3초 후에 타임아웃됩니다.
이 시점 이후에는 Account Activity API가 더 이상 POST를 시도하지 않습니다. Client는 데이터를 복구하기 위해 다른 X 엔드포인트를 사용해야 합니다.

Account Activity 데이터 객체 구조

ObjectDetails
for_user_id이벤트와 관련된, 구독된 사용자를 식별합니다.
is_blocked_by(조건부) 다른 사용자가 구독된 사용자를 멘션할 때만 표시됩니다. 포스트 멘션 이벤트에 한해, 값이 true인 경우에만 포함됩니다.
source활동을 수행하는 사용자입니다. 예를 들어 팔로우, 차단, 뮤트 동작을 수행하는 사용자가 source 사용자입니다.
target활동의 대상이 되는 사용자입니다. 예를 들어 팔로우, 차단, 뮤트 상태가 되는 사용자가 target 사용자입니다.
사용 가능한 활동
Message TypeDetails
tweet_create_events구독 사용자에 의해 또는 구독 사용자에 대해 다음 작업 중 하나가 수행될 때의 게시물 상태 페이로드입니다: 포스트, 리트윗, 답글, @멘션, 인용 트윗, 인용 트윗의 리트윗.
favorite_events사용자와 대상이 포함된 Favorite(좋아요) 이벤트 상태입니다.
follow_events사용자와 대상이 포함된 팔로우 이벤트입니다.
unfollow_events사용자와 대상이 포함된 언팔로우 이벤트입니다.
block_events사용자와 대상이 포함된 차단 이벤트입니다.
unblock_events사용자와 대상이 포함된 차단 해제 이벤트입니다.
mute_events사용자와 대상이 포함된 뮤트 이벤트입니다.
unmute_events사용자와 대상이 포함된 뮤트 해제 이벤트입니다.
user_event사용자가 애플리케이션 인증을 제거할 때 전송되는 철회 이벤트이며, 이때 구독은 자동으로 삭제됩니다.
direct_message_events다이렉트 메시지가 전송되거나 수신될 때, 사용자와 대상이 포함된 다이렉트 메시지 상태입니다.
direct_message_indicate_typing_events사용자와 대상이 포함된 다이렉트 메시지 입력 중 표시 이벤트입니다.
direct_message_mark_read_events사용자와 대상이 포함된 다이렉트 메시지 읽음 표시 이벤트입니다.
tweet_delete_events규정 준수를 더 쉽게 유지할 수 있도록 삭제된 포스트에 대한 알림입니다.
페이로드 예시 위 표에 설명된 각 Account Activity 이벤트에 대한 페이로드 예시는 아래를 참조하세요.

tweet_create_events (포스트, 리트윗, 답글, 인용 트윗)

{
	"for_user_id": "2244994945",
	"tweet_create_events": [
	  {
		<Tweet Object>
	  }
	]
}

tweet_create_events (@멘션)

{
	"for_user_id": "2244994945",
	"user_has_blocked": "false",
	"tweet_create_events": [
	  {
		<Tweet Object>
	  }
	]
}

favorite_events

{
	"for_user_id": "2244994945",
	"favorite_events": [{
		"id": "a7ba59eab0bfcba386f7acedac279542",
		"created_at": "Mon Mar 26 16:33:26 +0000 2018",
		"timestamp_ms": 1522082006140,
		"favorited_status": {
			<Tweet Object>
		},
		"user": {
			<User Object>
		}
	}]
}

follow_events

{
	"for_user_id": "2244994945",
	"follow_events": [{
			"type": "follow",
			"created_timestamp": "1517588749178",
			"target": {
				<User Object >
			},
			"source": {
				< User Object >
			}
		]
	}
}

unfollow_events

{
	"for_user_id": "2244994945",
	"follow_events": [{
			"type": "unfollow",
			"created_timestamp": "1517588749178",
			"target": {
				<User Object >
			},
			"source": {
				< User Object >
			}
		]
	}
}

block_events

{
	"for_user_id": "2244994945",
	"block_events": [{
		"type": "block",
		"created_timestamp": "1518127020304",
		"source": {
			<User Object>
		},
		"target": {
			<User Object>
		}
	}]
}

unblock_events

{
	"for_user_id": "2244994945",
	"block_events": [{
		"type": "unblock",
		"created_timestamp": "1518127020304",
		"source": {
			<User Object>
		},
		"target": {
			<User Object>
		}
	}]
}

mute_events

{
	"for_user_id": "2244994945",
	"mute_events": [
		{
			"type": "mute",
		  	"created_timestamp": "1518127020304",
			"source": {
				<User Object>
			},
			"target": {
				<User Object>
			}
		}
	]
}

unmute_events

{
	"for_user_id": "2244994945",
	"mute_events": [
		{
			"type": "unmute",
		  	"created_timestamp": "1518127020304",
			"source": {
				<User Object>
			},
			"target": {
				<User Object>
			}
		}
	]
}

user_event

{
	"user_event": {
		"revoke": {
			"date_time": "2018-05-24T09:48:12+00:00",
			"target": {
				"app_id": "13090192"
			},
			"source": {
				"user_id": "63046977"
			}
		}
	}
}

direct_message_events

{
  	"for_user_id": "4337869213",
	"direct_message_events": [{
		"type": "message_create",
		"id": "954491830116155396",
		"created_timestamp": "1516403560557",
		"message_create": {
			"target": {
				"recipient_id": "4337869213"
			},
			"sender_id": "3001969357",
			"source_app_id": "13090192",
			"message_data": {
				"text": "Hello World!",
				"entities": {
					"hashtags": [],
					"symbols": [],
					"user_mentions": [],
					"urls": []
				}
			}
		}
	}],
	"apps": {
		"13090192": {
			"id": "13090192",
			"name": "FuriousCamperTestApp1",
			"url": "https://x.com/furiouscamper"
		},
		"users": {},
		"3001969357": {
			"id": "3001969357",
			"created_timestamp": "1422556069340",
			"name": "Jordan Brinks",
			"screen_name": "furiouscamper",
			"location": "Boulder, CO",
			"description": "Alter Ego - X PE 의견은-제-개인적인-것입니다",
			"url": "https://t.co/SnxaA15ZuY",
			"protected": false,
			"verified": false,
			"followers_count": 22,
			"friends_count": 45,
			"statuses_count": 494,
			"profile_image_url": "null",
			"profile_image_url_https": "https://pbs.twimg.com/profile_images/851526626785480705/cW4WTi7C_normal.jpg"
		},
		"4337869213": {
			"id": "4337869213",
			"created_timestamp": "1448312972328",
			"name": "Harrison Test",
			"screen_name": "Harris_0ff",
			"location": "Burlington, MA",
			"protected": false,
			"verified": false,
			"followers_count": 8,
			"friends_count": 8,
			"profile_image_url": "null",
			"statuses_count": 240,
			"profile_image_url_https": "https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png"
		}
	}
}

direct_message_indicate_typing_events

{
	"for_user_id": "4337869213",
	"direct_message_indicate_typing_events": [{
		"created_timestamp": "1518127183443",
		"sender_id": "3284025577",
		"target": {
			"recipient_id": "3001969357"
		}
	}],
	"users": {
		"3001969357": {
			"id": "3001969357",
			"created_timestamp": "1422556069340",
			"name": "Jordan Brinks",
			"screen_name": "furiouscamper",
			"location": "Boulder, CO",
			"description": "Alter Ego - X PE opinions-are-my-own",
			"url": "https://t.co/SnxaA15ZuY",
			"protected": false,
			"verified": false,
			"followers_count": 23,
			"friends_count": 47,
			"statuses_count": 509,
			"profile_image_url": "null",
			"profile_image_url_https": "https://pbs.twimg.com/profile_images/851526626785480705/cW4WTi7C_normal.jpg"
		},
		"3284025577": {
			"id": "3284025577",
			"created_timestamp": "1437281176085",
			"name": "Bogus Bogart",
			"screen_name": "bogusbogart",
			"protected": true,
			"verified": false,
			"followers_count": 1,
			"friends_count": 4,
			"statuses_count": 35,
			"profile_image_url": "null",
			"profile_image_url_https": "https://pbs.twimg.com/profile_images/763383202857779200/ndvZ96mE_normal.jpg"
		}
	}
}

direct_message_mark_read_events

{
	"for_user_id": "4337869213",
	"direct_message_mark_read_events": [{
		"created_timestamp": "1518452444662",
		"sender_id": "199566737",
		"target": {
			"recipient_id": "3001969357"
		},
		"last_read_event_id": "963085315333238788"
	}],
	"users": {
		"199566737": {
			"id": "199566737",
			"created_timestamp": "1286429788000",
			"name": "Le Braat",
			"screen_name": "LeBraat",
			"location": "Denver, CO",
			"description": "data by day @X, design by dusk",
			"protected": false,
			"verified": false,
			"followers_count": 299,
			"friends_count": 336,
			"statuses_count": 752,
			"profile_image_url": "null",
			"profile_image_url_https": "https://pbs.twimg.com/profile_images/936652894371119105/YHEozVAg_normal.jpg"
		},
		"3001969357": {
			"id": "3001969357",
			"created_timestamp": "1422556069340",
			"name": "Jordan Brinks",
			"screen_name": "furiouscamper",
			"location": "Boulder, CO",
			"description": "Alter Ego - X PE opinions-are-my-own",
			"url": "https://t.co/SnxaA15ZuY",
			"protected": false,
			"verified": false,
			"followers_count": 23,
			"friends_count": 48,
			"statuses_count": 510,
			"profile_image_url": "null",
			"profile_image_url_https": "https://pbs.twimg.com/profile_images/851526626785480705/cW4WTi7C_normal.jpg"
		}
	}
}

tweet_delete_events

{
    "for_user_id": "930524282358325248",
    "tweet_delete_events": [
{
        "status": {
            "id": "1045405559317569537",
            "user_id": "930524282358325248"
        },
        "timestamp_ms": "1432228155593"
    }
   ]
}

Account Activity Replay API

Enterprise Account Activity Replay API는 최대 5일 전까지의 이벤트를 복구할 수 있는 데이터 복구 도구입니다. 웹훅 서버가 이벤트를 수신하지 못한 경우, 즉 재시도 윈도우를 초과하는 기간 동안 연결이 끊겼거나, 시스템을 정상 상태로 복구하는 데 며칠이 필요한 재해 복구 상황에서 데이터를 복구하는 데 사용해야 합니다. Account Activity Replay API는 일정 기간 동안 activities를 수집하지 못한 모든 상황을 위해 개발되었습니다. 이 API는 원래 활동이 실시간으로 전달되던 것과 동일한 웹훅으로 activities를 다시 전달합니다. 이 제품은 백필(backfill) 도구가 아닌 복구 도구이므로, 이전에 해당 이벤트의 전송이 시도된 경우에만 이벤트가 재생됩니다. Account Activity Replay API는 구독이 생성되기 이전 기간에 대한 이벤트는 전달할 수 없습니다.

Account Activity Replay API 사용하기

계정에 Replay 기능이 구성되어 있는 경우, Account Activity API에 요청을 보내는 방식과 유사하게 요청을 보낼 수 있습니다. 이때 어떤 webhook의 활동을 재생할지 지정하기 위해, 요청에는 반드시 webhook id 파라미터를 포함해야 합니다. 즉, Replay 요청은 webhook id와 application id를 기준으로 시작 날짜·시간부터 종료 날짜·시간까지의 이벤트를 가져오도록 Account Activity Replay API에 지시하는 것입니다. UTC 시간이 사용된다는 점에 유의하세요. 이러한 활동은 해당 id와 연결된 등록된 webhook을 통해 초당 최대 2,500개의 이벤트 속도로 전달됩니다. 또한 하나의 webhook당 동시에 실행될 수 있는 Replay job은 하나뿐이지만, 해당 webhook에 대해 지정된 날짜/시간 동안 활성 상태였던 모든 구독은 재생된다는 점을 기억해 두세요. 이벤트는 지정된 기간 중 가장 처음(가장 오래된) 1분부터 시작하여, 마지막 1분이 전달될 때까지 시간 순서대로(가능한 한 정확하게) 전달됩니다. 그 시점에 Replay는 해당 webhook으로 job 완료 이벤트를 전달합니다. 활동을 시간 순서대로 전달하기 때문에, 시작 시간 근처에 일치하는 결과가 거의 없거나 전혀 없는 경우 첫 번째 결과가 전달되기까지 일정 시간이 소요될 수 있습니다.

제한 사항

Replay는 최대 지난 5일간의 활동을 손쉽게 복구하도록 설계된 도구이지만, 특정 구독이 생성되기 이전의 이벤트는 제공하지 않습니다. 예를 들어 3일 전에 새 구독을 추가하고, 오늘을 기준으로 과거 5일을 조회 기간으로 하는 Replay 작업을 실행한 경우, 실제로는 이 새 구독이 활성화되어 있었던 지난 3일치 데이터만 받게 됩니다.

데이터 가용성 및 유형

Account Activity Replay API에서 제공되는 활동 데이터는 요청을 시작한 시점부터 5일 동안 사용할 수 있으며, 새 데이터는 해당 활동이 생성된 후 대략 10분 뒤에 사용 가능해집니다. 이 5일의 기간 내에서 from_date 및 to_date 매개변수를 사용하여 원하는 기간을 지정해 요청할 수 있습니다. Replay에 대한 액세스 권한을 얻기 전에 원래 전달되었던 이벤트는 다시 재생할 수 없습니다. 예를 들어, 계정이 2019년 6월 1일 15:30 UTC에 Account Activity Replay API 액세스 권한을 부여받은 경우, 그 시점 이전의 이벤트는 Replay를 사용해 검색할 수 없습니다. Account Activity Replay API 참조 문서로 이동하세요.

마이그레이션 소개

Site Streams, User Streams, 그리고 Account Activity API - DM Only 표준 베타 버전 제품은 2018년에 사용이 중단되었습니다. 해당 제품을 사용해 오셨다면 반드시 Account Activity API의 프리미엄 또는 엔터프라이즈 버전으로 마이그레이션해 주시기 바랍니다. **레거시 다이렉트 메시지(Direct Message) 엔드포인트도 사용이 중단되었습니다. 해당 엔드포인트를 사용해 오셨다면, 새로운 DM 엔드포인트 또는 Account Activity API의 프리미엄/엔터프라이즈 버전으로 반드시 마이그레이션해 주시기 바랍니다. ** 자세한 내용은 이 공지를 확인해 주시기 바랍니다. 다음 엔드포인트들이 이번 변경의 영향을 받습니다.
  • User Streams
  • Site Streams
  • GET direct_messages
  • GET direct_messages/sent
  • GET direct_messages/show
  • POST direct_messages/new
  • POST direct_messages/destroy  
새로운 엔드포인트와 서비스가 제공되며, 이들은 유사한 액세스를 제공하고 다이렉트 메시지의 경우 일부 추가 기능도 제공합니다. 이러한 새로운 엔드포인트와 서비스로 원활하게 마이그레이션하실 수 있도록 두 가지 마이그레이션 가이드를 제공하고 있습니다. 추가로, Account Activity API와 시작 방법을 설명하는 동영상 시리즈를 제공하고 있습니다. 마지막으로, 이해를 돕고 빠르게 시작할 수 있도록 코드 샘플도 제공하고 있습니다.
  • Account Activity Dashboard는 Account Activity API를 시작하는 데 도움이 되는 헬퍼 스크립트를 포함한 예제 Node.js 웹 App입니다.
  • SnowBot은 Account Activity API와 REST 다이렉트 메시지 엔드포인트를 사용하는 예제 챗봇입니다. Ruby로 작성되었으며, Sinatra 웹 App 프레임워크를 사용하고 Heroku에 배포되어 있습니다.

마이그레이션 가이드: User Streams/Site Streams에서 Account Activity API로 이전하기

2018년 8월 23일부로 Site Streams와 User Streams의 제공이 중단되었습니다. 반드시 Account Activity API로 마이그레이션해 주시기 바랍니다. 자세한 내용은 이 공지를 확인해 주세요. 이 가이드는 기존 User Streams 및 Site Streams API에서 이를 대체하는 Account Activity API로 마이그레이션하는 데 도움이 되도록 작성되었습니다. 아래에서 변경 사항 요약, 새로운 기능 목록, 전환을 돕기 위한 주요 차이점과 고려 사항을 확인할 수 있습니다. 기본 DM 엔드포인트에서 마이그레이션하는 방법에 대해서는 다이렉트 메시지 마이그레이션 가이드를 참고하세요.

변경 내용 요약

Account Activity API는 User Streams 및 Site Streams에서처럼 스트리밍 연결을 사용하는 대신, 웹훅을 통해 인증 및 구독된 계정의 이벤트를 전달합니다.

사용 중단된 API

GET user GET site (다음 제어 스트림 포함: GET site/c/:stream_id, GET site/c/:stream_id/info.json, GET site/c/:stream_id/friends/ids.json, POST site/c/:stream_id/add_user.json, POST /site/c/:stream_id/remove_user.json)

대체 API

Enterprise Account Activity API - 전체 활동

차이점 및 마이그레이션 시 고려사항

API 형식: 새로운 Account Activity API는 User Streams 및 Site Streams와 다르게 동작합니다. 웹후크(webhook)를 통해 데이터를 수신할 수 있도록 웹 앱을 수정해야 합니다. 웹후크에 대한 보다 자세한 정보는 여기에서 확인할 수 있습니다. 사용 가능한 데이터: 또 다른 주요 차이점은 전달되는 데이터와 관련이 있습니다. X는 더 이상 X에서 사용자가 팔로우하는 사람들(즉, 홈 타임라인)로부터 발생하는 이벤트를 전송하지 않습니다. 이는 의도적인 변경 사항이며, 앞으로 변경할 계획이 없습니다. 신뢰성: 스트리밍과 달리 웹후크는 전달 여부 확인과, 웹후크 URL에 도달하지 못한 POST 요청으로 전송된 활동을 재시도할 수 있는 옵션을 제공합니다. 이를 통해 짧은 연결 끊김이나 다운타임이 있더라도 앱이 모든 해당 활동을 수신하고 있다는 점을 보다 확실하게 보장할 수 있습니다.

새로운 기능

Account Activity API는 많은 새로운 기능을 제공하며, 그중 가장 중요한 변화는 데이터가 스트리밍 방식이 아니라 웹훅(webhook)을 통해 전달된다는 점입니다. 웹훅은 스트리밍과 비교했을 때 여러 가지 이점을 제공하지만, 이 중 가장 두드러진 것은 속도와 안정성입니다. API는 데이터가 사용 가능해지는 즉시 JSON 이벤트 형태로 전송하므로, 더 이상 활성 연결을 유지하거나 엔드포인트를 폴링할 필요가 없습니다. 이는 이중화 기능에 대한 필요성을 줄이고 전반적인 효율성을 높여줍니다. 웹훅에 대한 자세한 내용은 기술 문서를 참고하세요.

사용자 구독 관리

Account Activity API는 하나의 등록된 웹훅에 여러 개의 구독을 연결할 수 있습니다. 이를 통해 Site Streams 아키텍처와 유사하게, 여러 사용자 구독의 활동을 웹훅을 통해 동일한 엔드포인트로 전달할 수 있습니다. 이는 구독 한도와 관련된 구독 상태를 웹훅 연결과는 독립적으로 추적할 수 있음을 의미합니다. 또한 단일 웹훅에 대해 구독 수를 하나 또는 소수에서 수천 개까지 확장할 수 있도록 해 줍니다.

마이그레이션 절차

아래 단계를 따라 Site Streams API에서 Account Activity API로 쉽게 마이그레이션하세요

1단계: 패키지 선택하기 현재 User Streams 또는 Site Streams를 어떻게 운영하고 있는지에 따라 Account Activity API의 엔터프라이즈 버전 또는 프리미엄 버전으로 전환하는 것을 고려해야 합니다. 현재 지원 중인 애플리케이션 수나 승인된 사용자 수를 고려하고, 필요한 트래픽 규모와 안정성에 맞게 확장해야 합니다. 필요에 가장 잘 맞는 패키지를 결정할 때 고려할 만한 사항은 다음과 같습니다:
  • 필요한 웹훅(webhook) 수
  • 현재/예상 애플리케이션에서 관리 중인 구독/승인된 사용자 수
  • 현재 X 클라이언트 애플리케이션 수
  • X로부터 원하는 지원 수준(포럼 지원 또는 관리형 엔터프라이즈 1:1 지원)
  • 각 패키지의 가격
2단계: 개발자 콘솔에서 X app 설정 확인하기 현재 User Streams 또는 Site Streams에 사용 중인 X app개발자 콘솔에서 소유 사용자 계정에 대해 표시됩니다. 이 X app은 해당 애플리케이션의 승인된 사용자를 유지하기 위해 Account Activity API에도 사용할 수 있습니다. 새 app을 생성하고, 원한다면 사용자들이 이 새 app에 다시 승인을 부여하도록 할 수도 있습니다. 비즈니스를 대신해 새 app을 생성하는 경우, 기업용 X @handle 계정을 사용해 app을 생성하는 것을 권장합니다.
  • X app 페이지의 permissions 탭에서 “Read, Write and Access direct messages”를 활성화하세요.
    이 설정을 변경해도 소급 적용되지는 않으며, 이미 승인된 사용자는 승인 당시의 권한 설정을 유지합니다. 사용자가 아직 읽기, 쓰기, 다이렉트 메시지 접근 권한을 부여하지 않았다면, 해당 사용자가 애플리케이션을 다시 승인하도록 해야 합니다.
  • X Sign-in과 사용자 컨텍스트가 X API에서 어떻게 동작하는지 잘 모르는 경우 Obtaining Access Tokens를 검토하세요.
  • “Keys and Tokens” 탭의 하단에서 X app 소유자용 액세스 토큰을 생성하세요. 같은 탭에서 Consumer Key, Consumer Secret, Access Token, Access Token Secret 값을 기록해 두세요. API를 사용하려면 이 값들이 필요합니다.
  • application-only API 메서드용으로 Consumer Key와 Consumer Secret을 사용해 Bearer 토큰을 생성하세요.
3단계: 웹훅 설정 및 구성하기
  • 이벤트를 수신하기 위한 웹훅으로 사용할 엔드포인트를 가진 웹 앱을 만드세요(예: https://your&#95;domain.com/webhook/twitter 또는 https://webhooks.your&#95;domain.com).
  • 웹훅을 생성할 때 Consumer Key, Consumer Secret, Access Token, Access Token Secret을 사용하세요. 엔드포인트는 JSON 응답을 반환해야 하며, 여기에는 crc_token과 app Consumer Secret으로 생성한 base64 인코딩 HMAC SHA-256 해시인 response_token이 포함되어야 합니다.
  • Challenge Response Check(CRC) 요구 사항에 특히 유의하여 Securing Webhooks 문서를 검토하세요.
  • 웹훅이 수신 이벤트용 POST 요청과 CRC용 GET 요청을 모두 지원하는지 확인하세요.
  • 웹훅의 지연 시간이 낮은지 확인하세요(POST 요청에 응답하는 데 3초 미만).
4단계: 웹훅 설정 검증하기
  • Webhook API는 다음 두 가지 방식으로 웹훅을 보호합니다:
               - 웹훅 소유자가 웹 앱 소유자인지 검증하기 위한 challenge response check 요구                - 웹 앱이 요청 출처를 검증할 수 있도록 각 POST 요청에 서명 헤더 포함
  • X는 웹 앱과 웹훅 URL의 소유자가 동일한지 확인하기 위해 Challenge Response Check(CRC)를 수행합니다. 이는 cyclic redundancy check와는 다른 개념입니다.
  • crc_token이라는 파라미터가 포함된 GET 요청이 웹훅 URL로 전송됩니다. 엔드포인트는 crc_token과 app Consumer Secret으로 생성한 base64 인코딩 HMAC SHA-256 해시인 response_token을 포함하는 JSON 응답을 반환해야 합니다.
  • 각 CRC 요청마다 crc_token 값은 변경될 수 있습니다. crc_token은 Consumer Secret을 키로 사용하는 계산에서 메시지로 사용해야 합니다.
  • 응답이 유효하지 않은 경우, 등록된 웹훅으로 이벤트 전송이 중단됩니다.
5단계: 각 User Stream 또는 Site Streams 승인 사용자에 대한 구독 생성하기 User Streams에서 Account Activity API로 전환하기:
  • User Streams에서 현재 사용자 구독 목록을 조회합니다.
  • 다음 요청을 사용해 새로운 Account Activity API 구독을 설정합니다:  POST account_activity/all/:env_name/subscriptions
  • 다음 요청을 사용해 Account Activity API 구독을 확인합니다:  _GET account_activity/all/:env_name/subscriptions/list  _
Site Streams에서 Account Activity API로 전환하기(컨트롤 스트림 사용):
  • 다음 요청을 사용해 Site Streams에서 현재 구독 목록을 조회합니다:  GET /1.1/site/c/:stream_id/info.json
  • 다음 요청을 사용해 새로운 Account Activity API 구독을 설정합니다:  POST account_activity/all/:env_name/subscriptions
  • 다음 요청을 사용해 Account Activity API 구독을 확인합니다:  _GET account_activity/all/:env_name/subscriptions/list  _
Webhook 등록 및 구독 생성(Site Streams 또는 User Streams에서 마이그레이션하지 않는 경우)

Account Activity 대시보드 (예제 Account Activity API App)

Account Activity API를 더 빠르게 테스트할 수 있도록 샘플 App을 만들어 두었습니다.   
  • Account Activity Dashboard 샘플 애플리케이션을 여기에서 다운로드합니다(Node.js를 사용합니다).
  • README의 지침을 따라 App을 설치하고 실행합니다.
  • 애플리케이션이 실행되면 UI를 사용해 웹훅을 손쉽게 설정하고 새 구독을 생성할 수 있습니다.

사용 가능한 활동

Message Type세부 정보
tweet_create_events구독 사용자에 의해 또는 구독 사용자를 대상으로 다음 작업 중 하나가 수행될 때의 게시물 상태 페이로드: 포스트, 리트윗, 답글, @멘션, 인용 Tweet
favorite_events사용자와 대상이 포함된 즐겨찾기(좋아요) 이벤트 상태.
follow_events사용자와 대상이 포함된 팔로우 이벤트.
block_events사용자와 대상이 포함된 차단 이벤트.
mute_events사용자와 대상이 포함된 뮤트 이벤트.
direct_message_events사용자와 대상이 포함된 다이렉트 메시지 상태.
direct_message_indicate_typing_events사용자와 대상이 포함된 다이렉트 메시지 입력 중 표시 이벤트.
direct_message_mark_read_events사용자와 대상이 포함된 다이렉트 메시지 읽음 표시 이벤트.

사용 중단된 스트리밍 메시지 타입

빈 줄User Streams 및 Site Streams에서 keep-alive 메시지로 사용되던 빈 줄은 더 이상 Account Activity API에서 전달되지 않습니다.
제한 알림특정 webhook으로 더 이상 제한 알림이 전송되지 않습니다. 대신 사용자는 API를 호출하여 사용 가능한 핸들의 현재 사용량을 확인할 수 있습니다. 이는 향후 개발자 콘솔에 포함될 예정입니다.
연결 해제 메시지webhook은 활성 연결에 의존하지 않기 때문에 더 이상 연결 해제 알림이 필요하지 않습니다.
Stall 경고webhook은 다수의 수신 메시지를 처리할 수 있는 활성 연결에 의존하지 않기 때문에 더 이상 Stall 경고가 필요하지 않습니다.
친구 리스트친구 리스트는 더 이상 자동으로 전송되지 않습니다. 이제 이 정보를 조회하기 위한 REST 엔드포인트가 제공됩니다.

사용 중단된 이벤트 유형

설명이벤트 이름소스대상대상 객체
사용자가 게시물을 삭제함delete현재 사용자현재 사용자Post
팔로우한 사용자가 게시물을 삭제함delete팔로우한 사용자팔로우한 사용자Post
사용자가 게시물 즐겨찾기를 취소함unfavorite현재 사용자게시물 작성자Post
사용자의 게시물이 즐겨찾기에서 제거됨unfavorite즐겨찾기를 취소한 사용자현재 사용자Post
사용자가 다른 사용자를 언팔로우함unfollow현재 사용자언팔로우된 사용자Null
사용자가 리스트를 생성함list_created현재 사용자현재 사용자List
사용자가 리스트를 삭제함list_destroyed현재 사용자현재 사용자List
사용자가 리스트를 수정함list_updated현재 사용자현재 사용자List
사용자가 누군가를 리스트에 추가함list_member_added현재 사용자추가된 사용자List
사용자가 리스트에 추가됨list_member_added추가한 사용자현재 사용자List
사용자가 누군가를 리스트에서 제거함list_member_removed현재 사용자제거된 사용자List
사용자가 리스트에서 제거됨list_member_removed제거한 사용자현재 사용자List
사용자가 리스트를 구독함list_user_subscribed현재 사용자리스트 소유자List
사용자의 리스트가 구독됨list_user_subscribed구독한 사용자현재 사용자List
사용자가 리스트 구독을 취소함list_user_unsubscribed현재 사용자리스트 소유자List
사용자의 리스트가 구독 취소됨list_user_unsubscribed구독을 취소한 사용자현재 사용자List
사용자가 프로필을 업데이트함user_update현재 사용자현재 사용자Null
사용자가 보호 상태를 변경함user_update현재 사용자현재 사용자Null

다이렉트 메시지 마이그레이션 가이드

2018년 9월 17일부로 기존 다이렉트 메시지 엔드포인트는 사용이 중단되었습니다. 이전 엔드포인트를 사용해 오셨다면, 새 다이렉트 메시지 엔드포인트 또는 Account Activity API로 반드시 마이그레이션해 주시기 바랍니다. 자세한 내용은 이 공지를 참고해 주십시오. 이 가이드는 기존 다이렉트 메시지 REST API에서 베타 단계를 마친 향상된 대체 API로 마이그레이션하는 데 도움이 되도록 작성되었습니다. 아래에서 변경 사항 요약, 새로운 기능 목록, 전환에 도움이 되는 주요 차이점과 고려 사항을 확인하실 수 있습니다. 새 다이렉트 메시지 엔드포인트는 현재 모든 개발자가 사용할 수 있습니다. User Streams 또는 Site Streams에서 마이그레이션하는 방법에 대한 안내는 Account Activity API 마이그레이션 가이드를 참조하십시오.

변경 사항 요약

다음 DM 엔드포인트를 아직 사용 중이라면, 신규 엔드포인트로 마이그레이션해야 합니다. 

새로운 기능

새 Direct Message API 엔드포인트는 여러 가지 새로운 기능을 지원하며, 이전 Direct Message에 더 향상된 접근을 제공합니다. 새로운 기능은 다음과 같습니다.
  • 미디어 첨부(이미지, GIF 및 비디오) 지원
  • 미리 정의된 옵션 목록을 사용해 사용자에게 구조화된 응답을 요청하는 기능
  • 최대 30일간 과거 Direct Message에 액세스할 수 있음
새 Direct Message 기능 전체 목록과 추가된 새 API 엔드포인트는 기술 문서를 참조하세요.  

차이점 및 마이그레이션 시 고려 사항

새로운 API 엔드포인트는 이전 엔드포인트와 동작 방식이 크게 다릅니다. 단순히 엔드포인트 URL만 업데이트하면 애플리케이션에서 오류가 발생합니다. 마이그레이션을 위해 애플리케이션을 업데이트할 때 다음 사항을 고려하세요.

새로운 Direct Message 객체

가장 먼저 눈에 띄는 점은 Direct Message의 새로운 객체 구조입니다. 이 새로운 Message Create 객체 구조는 Quick RepliesAttachments와 같은 새로운 기능을 지원하기 위해 도입되었습니다. 새로운 객체에는 더 작게 축약된 사용자 객체도 포함되어 있습니다. 애플리케이션은 이 새로운 객체 구조를 파싱할 때, 그리고 필요하다면 데이터 모델이나 저장소에서도 이를 반영하도록 업데이트해야 합니다. 각 속성에 대한 설명은 Message Create Object 전체 문서를 참고하세요. Message Create 객체 예제
{
      "type": "message_create",
      "id": "1234858592",
      "created_timestamp": "1392078023603",
      "initiated_via": {
        "tweet_id": "123456",
        "welcome_message_id": "456789"
      },
      "message_create": {
        "target": {
          "recipient_id": "1234858592"
        },
        "sender_id": "3805104374",
        "source_app_id": "268278",
        "message_data": {
          "text": "Blue Bird",
          "entities": {
            "hashtags": [],
            "symbols": [],
            "urls": [],
            "user_mentions": [],
          },
          "quick_reply_response": {
            "type": "options",
            "metadata": "external_id_2"
          },
          "attachment": {
            "type": "media",
            "media": {
             ...
            }
          }
        }
      }

요약

  • Direct Message 객체 구조가 완전히 새로워졌습니다.
  • 사용자 객체가 간소화되었습니다.
  • 새로운 정보가 포함됩니다(퀵 리플라이 응답, 첨부 파일 등).

다이렉트 메시지 보내기

POST direct_messages/events/new는 다이렉트 메시지를 보내기 위한 완전한 대체 엔드포인트입니다. 이 엔드포인트의 가장 큰 차이점은 이제 개별 POST 매개변수 대신, 모든 정보를 POST 요청 본문의 JSON으로 전송한다는 점입니다. Twurl 요청 예시
twurl -A 'Content-type: application/json' -X POST /1.1/direct\_messages/events/new.json -d '{"event": {"type": "message\_create", "message\_create": {"target": {"recipient\_id": "4534871"}, "message_data": {"text": "Hello World!"}}}}'
위 요청에서 content-typeapplication/x-www-form-urlencoded가 아니라 application/json으로 설정되어 있다는 점에 유의하세요. 추가로, OAuth 1.0a 서명 값을 직접 생성하는 경우 JSON 본문은 서명 생성 과정에 포함되지 않는다는 점을 명심하세요. 대부분의 OAuth 라이브러리는 이미 이를 처리하고 있습니다. twurl을 사용하는 경우 최소 0.9.3 버전을 사용하고 있는지 확인하세요.

요약

  • 메시지는 JSON POST 요청 본문에 정의됩니다.
  • Content-Type 헤더는 application/json으로 설정해야 합니다.
  • OAuth 서명 생성 시 JSON 본문은 포함되지 않습니다.  

다이렉트 메시지 가져오기

과거 다이렉트 메시지 조회는 이제 단일 API 엔드포인트인 GET direct_messages/events/list로 처리할 수 있습니다. 이 새 엔드포인트의 가장 큰 차이점은 전송한 메시지와 수신한 메시지를 모두 최신순(내림차순)으로 반환한다는 점입니다. 이를 통해 대화를 다시 구성하기가 더 쉬워질 수 있습니다. 다만 전송한 메시지만 또는 수신한 메시지만 조회하려는 경우, sender_id 프로퍼티를 참고하여 응답을 후처리해야 합니다. 페이지네이션은 이제 개별 다이렉트 메시지의 ID가 아니라 커서 값에 기반하여 이뤄집니다. 각 응답에는 커서 프로퍼티가 함께 반환됩니다. GET direct_messages/events/list는 지난 30일간의 메시지를, 해당 기간 내 메시지 개수와 관계없이 최대 30일치까지 반환합니다. 커서가 반환되지 않는다면 더 이상 반환할 메시지가 없다는 의미입니다. 개별 다이렉트 메시지에 접근하는 GET direct_messages/events/show 방식은 동일하게 유지되지만, 반환되는 다이렉트 메시지 객체의 구조는 앞서 설명한 것과 같이 변경되었습니다. 마지막으로, 다이렉트 메시지에 대한 실시간 접근은 이제 Account Activity API를 사용하는 웹훅을 통해 제공됩니다. User Streams 또는 Site Streams에서 마이그레이션하는 방법에 대한 안내는 Account Activity API 마이그레이션 가이드를 참고하십시오.

요약

  • 보낸 메시지와 받은 메시지가 이제 하나의 엔드포인트에서 함께 반환됩니다.
  • 최대 30일치 메시지가 반환됩니다.
  • 커서 기반 페이지네이션을 지원합니다.
  • 웹훅을 통해 다이렉트 메시지에 실시간으로 액세스할 수 있습니다.

다이렉트 메시지 삭제

이제 다이렉트 메시지는 DELETE 메서드를 사용하는 direct_messages/events/destroy 엔드포인트로 삭제할 수 있습니다. 인터페이스는 대부분 동일하며, 삭제할 메시지의 ID가 필요합니다. 주요 차이점은 이제 이 엔드포인트가 POST 요청이 아니라 DELETE 요청을 요구한다는 점입니다. 삭제된 다이렉트 메시지가 X 공식 클라이언트에 반영되는 방식은 그대로입니다. 다이렉트 메시지는 요청에 사용된 사용자 컨텍스트의 인터페이스에서만 제거됩니다. 대화의 다른 참여자는 여전히 해당 다이렉트 메시지에 액세스할 수 있습니다.

요약

  • 다이렉트 메시지를 삭제하려면 ID가 필요합니다.
  • 새로운 엔드포인트에는 DELETE 요청이 필요합니다.
  • 삭제된 다이렉트 메시지가 공식 X 클라이언트에 반영되는 방식은 변경되지 않습니다.
새로운 다이렉트 메시지 엔드포인트로 마이그레이션과 관련해 궁금한 점이 있으신가요? 질문이 있다면 devcommunity.com의 개발자 커뮤니티 포럼에 올려 주세요.

자주 묻는 질문

일반

Account Activity API를 사용하면 어떤 장점이 있나요? Account Activity API는 웹훅을 사용합니다. 즉, 스트리밍 API와 달리, 저희가 정보를 보내기 위해 여러분이 항상 열린 연결을 유지할 필요가 없습니다. 웹훅은 REST API와도 다릅니다. 원하는 데이터를 얻기 위해 15분마다 수백 번씩 저희 쪽으로 주기적으로 요청(polling)을 보낼 필요가 없기 때문입니다. 이 방식은 이벤트가 발생했을 때 데이터를 바로 전달하므로, 사용자와 여러분의 앱 간 효율성을 높여 줍니다. Account Activity API에는 다음과 같은 이점이 있습니다.
  1. 속도: X의 속도로 데이터를 전달합니다.
  2. 단순성: 단일 웹훅 연결 하나를 통해 계정의 모든 이벤트를 전달합니다. API로 전달되는 활동에는 포스트, @멘션, 답글, 리트윗, 인용 Tweet, 인용 Tweet의 리트윗, 좋아요, 발신 Direct Message, 수신 Direct Message, 팔로우, 차단, 뮤트가 포함됩니다. 
  3. 확장성: 관리 중인 계정의 모든 활동을 이벤트 상한이나 요청 한도의 제약 없이 수신할 수 있습니다.
Account Activity API는 프리미엄 샌드박스, 유료 프리미엄, 엔터프라이즈 플랜으로 제공되며, 감사·책임 추적 기능이나 추가 기능을 위해 더 많은 계정이 필요해질수록 요구에 맞게 확장할 수 있습니다. 시작하려면 GitHub에서 샘플 코드 스니펫을 다운로드하세요.   어떤 제품 티어가 저에게 가장 적합한지 어떻게 판단하나요? 프리미엄 옵션들과 엔터프라이즈 옵션 간 차이에 대해 더 알아보려면 Account Activity API 개요 페이지를 읽어보세요.    프리미엄 환경(Premium environment)과 엔터프라이즈 웹훅(Enterprise webhook)의 차이는 무엇인가요? 차이는 없습니다. 각 프리미엄 환경은 자체적인 webhook_id를 갖게 됩니다.   Account Activity API용 개발(Development), 스테이징(Staging), 프로덕션(Production) 환경이 필요합니다. 가능한가요? 네, 가능합니다! Account Activity API의 유료 티어(유료 프리미엄 및 엔터프라이즈)에서는 여러 개의 웹훅 URL을 등록하고, API 메서드를 통해 각 웹훅별로 구독을 별도로 관리할 수 있습니다. 또한 여러 클라이언트 App을 allowlist에 추가하여, 현재 승인된 사용자에 대한 인증 상태를 유지할 수 있습니다.   Account Activity API 설정을 단계별로 안내하는 가이드가 있나요? 물론 있습니다.
  • 처음 시작하는 경우, 웹훅 시작하기 가이드를 먼저 확인하는 것을 권장합니다.
  • X Dev에서 지원하는 스크립트를 따라가 보세요: 
    • Account Activity API dashboard: 웹훅 이벤트를 표시하는 Node 기반 웹 앱입니다.
    • SnowBot chatbot: Account Activity API와 Direct Message API 위에 구축된 Ruby 웹 앱입니다. 이 코드 베이스에는 Account Activity API 웹훅 설정을 도와주는 스크립트가 포함되어 있습니다.  
우리 시스템이 일정 시간 동안 다운되면 데이터를 복구할 방법이 있나요? Account Activity API의 유료 티어(유료 프리미엄 및 엔터프라이즈)에서는, 저희 시스템이 4시간 동안 여러 차례에 걸쳐 활동을 여러분에게 재전송하도록 재시도합니다. 해당 4시간 동안 여러분의 시스템이 응답하지 않으면 그 활동은 유실되며, 7일 이내의 데이터를 복구하려면 다른 REST 엔드포인트를 사용해야 합니다. 각기 다른 웹훅 또는 환경을 Account Activity Replay API와 같이 중복(레던던시) 수단으로 활용하여, 시스템 중 하나가 다운되더라도 활동을 놓치지 않도록 하는 것을 권장합니다.   Account Activity API에는 어떤 인증 방식을 사용해야 하나요? Account Activity API에 필요한 인증 방식은 API 참조 문서 페이지에 메서드별로 설명되어 있습니다. X 인증을 처음 사용하신다면 이 섹션을 읽어보시기를 권장합니다. CRC(Challenge-Response Check)란 무엇인가요? Account Activity API 챌린지 응답 검사는 Account Activity API의 활동이 올바른 개발자에게 전송되고 있는지 확인하기 위해 도입된 보안 기능입니다. 또한 개발자가 자신이 수신하는 데이터가 X에서 온 것인지 확인하는 데에도 사용할 수 있습니다. X는 웹훅 URL이 마지막으로 검증된 시점을 기준으로 24시간마다 한 번씩 자동으로 CRC를 웹훅 URL로 전송합니다. 시스템은 검증 상태를 유지하기 위해 3초 이내에 유효한 응답을 반환해야 합니다.  자세한 내용은 웹훅 보안 페이지를 참고하세요.   웹훅 URL이 즉시 무효화되는 경우가 있나요? 다음 중 하나라도 발생하면 해당 웹훅은 즉시 무효로 표시됩니다.
  • 서버가 CRC에 잘못된 토큰으로 응답한 경우. 이 경우 시스템은 액티비티를 전송하기 위한 재시도를 수행하지 않습니다.
  • 웹훅 URL에 잘못된 인증서가 설정된 경우. 이 경우에도 시스템은 액티비티를 전송하기 위한 재시도를 수행하지 않습니다.
  • 서버가 2XX, 4XXX, 5XXX 이외의 응답 코드를 반환하는 경우.
  • gzip 사용을 지정해 놓고 실제로는 gzip으로 전송하지 않는 경우.
  • gzip 사용을 지정하지 않았는데 실제 응답을 gzip으로 전송하는 경우.  
서로 상호작용하는 사용자들에게 모두 구독을 걸어 둔 경우, 같은 액티비티를 중복해서 받게 되나요? 네. 웹 앱이 사용자 A와 사용자 B 모두에 대해 활성 구독을 가지고 있고, 사용자 A가 게시물에서 사용자 B를 멘션하면, 등록된 웹훅으로 두 개의 POST 액티비티가 전송됩니다. 각 액티비티에는 해당 액티비티가 어떤 구독에 속하는지 표시하기 위한 “for_user_id” 표시가 포함됩니다.   **웹훅에 대한 구독을 생성할 때, 다음 엔드포인트의 /all/ 부분을 다른 Account Activity 데이터 객체로 대체해서 API가 전달하는 액티비티 범위를 제한할 수 있나요? **POST https://api.x.com/1.1/account_activity/all/:env_name/subscriptions.json 아니요, 이는 불가능합니다. 현재로서는 /all/ 제품만 제공되고 있습니다.   **사용자로부터 Direct Messages 권한을 요청하지 않고 Account Activity API를 사용할 수 있는 방법이 있나요? ** 현재로서는 이 API에서 Direct Messages 활동만을 ‘필터링’하는 방법이 없기 때문에 Direct Messages 권한이 필수입니다.    Account Activity API의 샌드박스 버전이 있나요? 네, 테스트용 샌드박스 옵션을 제공합니다. 샌드박스 옵션은 단일 웹훅과 최대 15개의 구독으로 제한됩니다. 샌드박스 옵션에 대한 자세한 내용은 문서에서 확인할 수 있습니다.  **구독된 사용자를 멘션하는 게시물의 리트윗을 가져오기 위해 Account Activity API를 사용할 수 있나요? ** 유감스럽게도, 이는 이 API가 제공하는 액티비티에 포함되어 있지 않습니다. 이 경우에는 대신 Streaming API 사용을 권장합니다.    tweet_create_event가 나타낼 수 있는 가능한 액티비티에는 어떤 것들이 있나요? 다음과 같은 경우 tweet_create_event 페이로드가 전송됩니다. 구독된 사용자가 다음 작업 중 하나를 수행할 때:
  • 게시물 생성
  • 리트윗
  • 게시물에 답글 작성
다른 사용자가 다음을 수행할 때:
  • 구독된 사용자를 @멘션*할 때
  • 구독된 사용자가 작성한 Tweet을 인용할 때 
*참고: Account Activity API는 구독된 사용자가 X에서 알림을 받고 해당 이벤트를 공개적으로 볼 수 있는 경우에만 이벤트를 전달합니다. 이는 멘션된 계정(@userA)이 보호된 계정(@userB)을 팔로우하는 경우 UserA는 UserB가 자신을 멘션했다는 알림을 받는다는 의미입니다. UserA가 UserB를 팔로우하지 않았고(또는 UserB가 이를 승인하지 않았고) 따라서 알림을 받지 못하는 경우, @userA에 대한 구독이 있더라도 tweet_create_event는 AAA를 통해 전송되지 않습니다. 차단된 사용자가 내가 구독한 사용자를 멘션했을 때, 이를 어떻게 식별할 수 있나요? JSON 응답의 최상위에 user\_has\_blocked라는 boolean 필드가 있으며, “true” 또는 “false”로 설정됩니다. 이 필드는 게시물 멘션에서만 노출됩니다.  Enterprise 내 앱을 allowlist에 추가하거나 이미 allowlist에 있는지 확인하려면 어떻게 해야 하나요? Enterprise API를 통해 액세스할 수 있도록 허용 목록에 추가해 둔 X apps를 관리하려면, App ID와 함께 계정 담당자에게 문의해 주세요. App ID는 개발자 콘솔“Apps” 페이지로 이동하면 확인할 수 있습니다.   웹훅 3개에 대한 권한이 있는 경우, 엔터프라이즈용으로 등록한 각 App에서 웹훅 3개씩을 사용할 수 있나요? 웹훅 한도는 App 수준이 아니라 계정 수준에서 설정됩니다. 웹훅 3개에 대한 권한이 있고 엔터프라이즈용으로 등록된 App이 2개인 경우, 한 App에는 웹훅 2개를, 다른 App에는 나머지 1개를 사용할 수 있지만, 각 App마다 3개씩 사용할 수는 없습니다.  Account Activity Replay API를 사용할 때 재전달할 이벤트 유형을 지정할 수 있나요? 재생할 이벤트 유형은 지정할 수 없습니다. 지정한 날짜와 시간 범위 동안 전달된 모든 이벤트가 재생됩니다.  내 애플리케이션이 Account Activity Replay API 이벤트를 수신하지 못한 경우 재시도가 이루어지나요? 아니요, 재시도는 이루어지지 않습니다. 애플리케이션이 Account Activity Replay API에서 전송한 이벤트 수신에 실패한 경우, 동일한 기간에 대해 또 다른 Replay 작업을 제출하여 누락된 Replay 이벤트의 재전달을 시도할 수 있습니다.  부분 성공 완료 이벤트를 수신하면 어떻게 해야 하나요? 수신된 이벤트의 타임스탬프를 기록해 두고, 누락된 이벤트에 대해 다시 Replay 작업을 요청할 것을 권장합니다.  동시에 실행할 수 있는 Account Activity Replay API 작업은 몇 개까지인가요? 웹훅 하나당 동시에 실행할 수 있는 Account Activity Replay API 작업은 하나뿐입니다.  웹훅으로 전달되는 동안 Account Activity Replay API 이벤트와 실시간 프로덕션 이벤트를 어떻게 구분할 수 있나요? Account Activity Replay API는 항상 과거의 이벤트만 전달하므로, 이벤트의 타임스탬프를 기준으로 실시간 프로덕션 이벤트와 구분할 수 있습니다.  애플리케이션에서 누락하거나 처리에 실패한 액티비티를 재전달하기 위해 Account Activity Replay API를 얼마나 빨리 사용할 수 있나요? 액티비티는 생성된 후 약 10분이 지나면 재전달이 가능해집니다. 

오류 해결 가이드

코드 32

이 오류는 일반적으로 요청, 헤더, 인증/인가 정보 또는 지정한 URL 중 어느 한 곳의 형식이 잘못되었음을 의미합니다. 이는 Account Activity API 자체의 오류가 아니라 인가 오류이며, X가 올바른 OAuth 설정이나 URL을 받지 못하고 있는 상태입니다.
  • Enterprise - 사용 중인 consumer key와 access token이 Enterprise 제품 사용을 위해 등록된 X app에 속해 있는지 확인하세요. consumer key와 access token이 없거나 allowlist에 X app을 추가해야 하는 경우에는 계정 담당자에게 문의하세요. 
  • 사용자 컨텍스트로 인증하는 경우, oauth nonce, oauth_signature, oauth_timestamp가 올바르게 포함되도록 요청을 인증했는지 확인하세요.
  • access token에 적절한 권한 수준이 있는지 확인하세요.
    • app 대시보드의 ‘Keys and tokens’ 탭에서 access token의 권한 수준이 ‘Read, write, and direct messages’로 설정되어 있는지 확인하세요. 
    • 토큰의 권한 수준이 이보다 낮게 설정되어 있다면, ‘Permissions’ 탭으로 이동하여 접근 권한을 ‘Read, write, and direct messages’로 변경한 다음, ‘Keys and tokens’ 탭에서 access token과 secret을 다시 생성하세요.
  • URL이 올바른 형식으로 구성되어 있는지 확인하세요.
    • :env_name은 대소문자를 구분한다는 점을 유의하세요.  

Code 200 - Forbidden

  • Premium - API에 요청을 보내기 전에 승인된 개발자 계정이 있는지 확인하세요. 또한 요청에서 올바른 :env_name 값을 사용해야 하며, 이는 dev environments(개발 환경) 페이지에서 설정할 수 있습니다.
  • Enterprise - 담당 계정 관리자가 Account Activity API에 대한 액세스 권한을 부여했는지 확인하세요.
  • URI를 올바르게 구성했는지 확인하세요. 요청에 잘못된 URI를 입력한 경우 이 오류가 발생할 수 있습니다.  

Code 214 - Webhook URL이 요구 사항을 충족하지 않습니다.

코드 214 - CRC GET 요청의 지연 시간이 큽니다. 웹훅은 3초 이내에 응답해야 합니다.

  • 이는 서버가 느리다는 의미입니다. CRC에 3초 이내에 응답하는지 확인하세요.  

Code 214 - CRC GET 요청 중 200이 아닌 응답 코드(예: 404, 500 등).

  • 서버가 다운된 상태입니다. 서버가 정상적으로 실행 중인지 확인하세요.  

코드 214 - 이미 너무 많은 리소스가 생성되었습니다.

  • Enterprise - 이미 사용 가능한 웹후크를 모두 사용했습니다. 등록된 각 App에서 GET webhooks 엔드포인트를 사용하여 웹후크가 어디에 설정되어 있는지 확인하세요. 

코드 261 - 애플리케이션이 쓰기 작업을 수행할 수 없습니다.

  • API와 함께 사용 중인 App에 액세스 토큰과 액세스 토큰 시크릿에 대해 올바른 권한 수준이 설정되어 있지 않습니다. X apps 대시보드의 “Keys and tokens” 탭으로 이동하여 액세스 토큰과 액세스 토큰 시크릿에 할당된 권한 수준을 확인하세요. 값이 “Read, write and Direct Messages”가 아닌 경우, “Permission” 탭에서 설정을 조정한 다음 새로운 설정이 적용되도록 액세스 토큰과 액세스 토큰 시크릿을 다시 생성해야 합니다.
  • 또는 App-only 인증을 사용해 웹훅을 등록하려고 하고 있을 수 있는데, 이는 지원되지 않습니다. 대신 Enterprise Account Activity API에 대한 웹훅 등록용 API 참조 문서 섹션에 설명된 대로 사용자 컨텍스트로 인증하세요.

Account Activity API 참조 문서 인덱스

Purpose엔터프라이즈
웹훅 URL을 등록하고 webhook_id를 생성합니다POST
webhooks
모든 웹훅 URL과 해당 상태를 반환합니다GET
webhooks
챌린지 응답 검사를 수동으로 실행합니다PUT
webhooks/:webhook_id
애플리케이션을 계정의 이벤트에 구독합니다POST
webhooks/:webhook_id/subscriptions/all
현재 활성 구독 수를 반환합니다GET
subscriptions/count
웹훅이 계정에 구독되어 있는지 확인합니다GET
webhooks/:webhook_id/subscriptions/all
현재 활성 구독 목록을 반환합니다GET
webhooks/:webhook_id/subscriptions/all/list
웹훅을 삭제합니다DELETE
webhooks/:webhook_id
3-legged OAuth를 사용해 구독을 비활성화합니다(사용 중단됨)DELETE
webhooks/:webhook_id/subscriptions/all
애플리케이션 전용 OAuth를 사용해 구독을 비활성화합니다DELETE
webhooks/:webhook_id/subscriptions/:user_id/all.json
활동을 웹훅으로 다시 전송합니다POST
replay/webhooks/:webhook_id/subscriptions/all

엔터프라이즈용 Account Activity API

POST account_activity/webhooks

지정된 애플리케이션 컨텍스트에 대해 새로운 webhook URL을 등록합니다. URL은 저장되기 전에 CRC 요청을 통해 검증됩니다. 검증에 실패하면 요청자에게 상세한 오류 메시지를 반환합니다. 허용되는 webhook 수는 요금제에 따라 결정됩니다.

리소스 URL

https://api.x.com/1.1/account_activity/webhooks.json

리소스 정보

응답 형식JSON
인증 필요예 (사용자 컨텍스트 - 모든 consumer 토큰 및 access 토큰)
요청 한도 적용
요청 수 / 15분(사용자 인증)15
Tweet 편집 지원모든 Tweet 객체에 해당 Tweet의 편집 이력을 설명하는 Tweet 편집 메타데이터가 포함됩니다. 자세한 내용은 “Tweet edits” 기본 사항 페이지를 참고하세요.

매개변수

url (required)콜백 엔드포인트용 인코딩된 URL입니다.

요청 예시

$ curl —request POST —url ‘https://api.x.com/1.1/account&#95;activity/webhooks.json?url=https%3A%2F%2Fyour&#95;domain.com%2Fwebhooks%2Ftwitter%2F0&#39; —header ‘authorization: OAuth oauth_consumer_key=“CONSUMER_KEY”, oauth_nonce=“GENERATED”, oauth_signature=“GENERATED”, oauth_signature_method=“HMAC-SHA1”, oauth_timestamp=“GENERATED”, oauth_token=“ACCESS_TOKEN”, oauth_version=“1.0“‘

HTTP 응답

HTTP Code메시지
200웹후크 URL이 제공된 애플리케이션에 등록되어 있습니다
403요청에 오류가 있습니다. 아래의 오류 메시지 섹션을 참조하세요.

예시 응답 - 성공

_HTTP 200_

    {
      "id": "1234567890",
      "url": "https://your_domain.com/webhook/twitter/0",
      "valid": true,
      "created_at": "2016-06-02T23:54:02Z"
    }

오류 메시지

CodeMessage
214Webhook URL이 요구 사항을 충족하지 않습니다.
214이미 생성된 리소스 수가 너무 많습니다.
214Webhook URL이 요구 사항을 충족하지 않습니다. CRC 토큰이 잘못되었거나 JSON 응답 형식이 올바르지 않습니다.
214CRC GET 요청의 지연 시간이 너무 깁니다. Webhook은 3초 이내에 응답해야 합니다.
214CRC GET 요청 중 200 이외의 응답 코드가 반환되었습니다(예: 404, 500 등).
HTTP 403
    {
      "errors": [
        {
          "code": 214,
          "message": "Too many resources already created."
        }
      ]
    }

GET account_activity/webhooks

지정된 App에 대한 모든 URL과 해당 상태를 반환합니다. URL이 매일 수행되는 유효성 검사에서 실패하면 해당 URL을 유효하지 않은 것으로 표시합니다. URL을 다시 활성화하려면 update 엔드포인트를 호출하세요.

리소스 URL

https://api.x.com/1.1/account_activity/webhooks.json

리소스 정보

응답 형식JSON
인증 필요 여부예 (애플리케이션 전용 - Bearer 토큰)
요청 한도 적용 여부
요청 수 / 15분 구간 (애플리케이션 인증)15

요청 예시

    $ curl --request GET
     --url https://api.x.com/1.1/account_activity/webhooks.json
     --header 'authorization: Bearer TOKEN'

예시 응답

HTTP 200 OK
    [
      {
        "id": "1234567890",
        "url": "https://your_domain.com/webhook/twitter/0",
        "valid": true,
        "created_at": "2016-06-02T23:54:02Z"
      }
      {
        "id": "2468013579",
        "url": "https://your_domain2.com/webhook/twitter/0",
        "valid": true,
        "created_at": "2016-06-04T22:31:29Z"
      }
    ]

오류 메시지

코드메시지
99이 리소스에 대한 액세스 권한이 없습니다.

PUT account_activity/webhooks/:webhook_id

지정된 웹훅의 URL에 대해 CRC(Challenge Response Check)를 수행합니다. 검사에 성공하면 204를 반환하고 상태를 valid로 설정하여 웹훅을 다시 활성화합니다.

리소스 URL

https://api.x.com/1.1/account_activity/webhooks/:webhook_id.json

리소스 정보

응답 형식JSON
인증 필요예 (user context - 모든 consumer 토큰 및 access 토큰)
요청 한도 적용
요청 / 15분(사용자 인증 기준)15

매개변수

webhook_id (required)리소스 경로에 정의된 Webhook ID입니다.

예시 요청

    $ curl --request PUT
     --url https://api.x.com/1.1/account_activity/webhooks/:WEBHOOK_ID.json
     --header 'authorization: OAuth oauth_consumer_key="CONSUMER_KEY", oauth_nonce="GENERATED", oauth_signature="GENERATED", oauth_signature_method="HMAC-SHA1", oauth_timestamp="GENERATED", oauth_token="ACCESS_TOKEN", oauth_version="1.0"'

응답

HTTP 204 OK
    { }

오류 메시지

CodeMessage
34웹훅이 존재하지 않거나 다른 X 애플리케이션과 연결되어 있습니다.
214웹훅 URL이 요구 사항을 충족하지 않습니다.
214웹훅 URL이 요구 사항을 충족하지 않습니다. CRC 토큰이 잘못됐거나 JSON 응답 형식이 올바르지 않습니다.
214CRC GET 요청의 지연 시간이 너무 깁니다. 웹훅은 3초 이내에 응답해야 합니다.
214CRC GET 요청 중 200이 아닌 응답 코드(예: 404, 500 등)가 반환되었습니다.

POST account_activity/webhooks/:webhook_id/subscriptions/all

제공된 App이 제공된 사용자 컨텍스트에 대해 모든 메시지 type의 모든 이벤트를 구독하도록 합니다. 활성화가 완료되면, 요청한 사용자와 관련된 모든 이벤트는 POST 요청을 통해 해당 App의 webhook으로 전송됩니다. 현재 구독 수는 계정 구성에 따라 제한됩니다. 더 많은 구독이 필요하다면 계정 담당자에게 문의해 주시기 바랍니다.

리소스 URL

https://api.x.com/1.1/account_activity/webhooks/:webhook_id/subscriptions/all.json

리소스 정보

응답 형식JSON
인증 필요예 (3-legged OAuth - 화이트리스트에 등록된 consumer key 및 구독 중인 사용자의 access token)
요청 한도 적용
요청 수 / 15분 기준 (사용자 인증)500

매개변수

webhook_id (required)리소스 경로에서 정의된 웹후크 ID입니다.

요청 예시

    $ curl --request POST
     --url https://api.x.com/1.1/account_activity/webhooks/:WEBHOOK_ID/subscriptions/all.json
     --header 'authorization: OAuth oauth_consumer_key="WHITELISTED_CONSUMER_KEY", oauth_nonce="GENERATED", oauth_signature="GENERATED", oauth_signature_method="HMAC-SHA1", oauth_timestamp="GENERATED", oauth_token="SUBSCRIBING_USER'S_ACCESS_TOKEN", oauth_version="1.0"'

성공 시 예시 응답

HTTP 204 NO CONTENT
    {}

오류 메시지

코드메시지
34Webhook이 존재하지 않거나 다른 X 앱과 연결되어 있습니다.
348Client 애플리케이션에는 이 사용자의 webhook 구독에 접근할 권한이 없습니다.

GET account_activity/subscriptions/count

현재 계정에서 활성화된 구독의 개수를 반환합니다. /count 엔드포인트는 애플리케이션 전용 OAuth가 필요하므로, 사용자 컨텍스트 대신 Bearer 토큰을 사용해 요청해야 합니다.

리소스 URL

https://api.x.com/1.1/account_activity/subscriptions/count.json

리소스 정보

응답 형식HTTP 응답 코드
인증 필요예 (애플리케이션 전용 - Bearer 토큰)
요청 한도 적용
요청 / 15분 (애플리케이션 인증)15

HTTP Response Codes

코드메시지
200성공. 요청된 webhook에 대한 구독 수가 반환됩니다.
401애플리케이션에 지정된 webhook에 대한 구독을 조회할 권한이 없습니다.

요청 예시

    $ curl --request GET
     --url https://api.x.com/1.1/account_activity/subscriptions/count.json
     --header 'authorization: Bearer TOKEN'

예시 응답 - 성공

HTTP 200
    {
      "account_name":"my-account",
      "subscriptions_count_all":"1",
      "subscriptions_count_direct_messages":"0",
      "provisioned_count":"50"
    }

오류 메시지

Code메시지
32사용자를 인증할 수 없습니다.
HTTP 401
    {
      "errors": [
        {
           "code": 32,
          "message": "Could not authenticate you."
        }
      ]
    }

GET account_activity/webhooks/:webhook_id/subscriptions/all

지정한 사용자의 이벤트에 대해 해당 웹훅 구성이 구독 중인지 확인할 수 있는 방법을 제공합니다. 지정한 사용자 컨텍스트가 지정한 애플리케이션에 대해 활성 구독을 보유하고 있으면 204 OK를 반환합니다. 응답 코드가 204가 아니면 해당 사용자는 활성 구독을 보유하고 있지 않은 것입니다. 자세한 내용은 아래의 HTTP 응답 코드 및 오류 메시지를 참조하십시오.

리소스 URL

https://api.x.com/1.1/account_activity/webhooks/:webhook_id/subscriptions/all.json

리소스 정보

응답 형식JSON
인증 필요예 (3-legged OAuth - 화이트리스트에 등록된 consumer key 및 구독 중인 사용자의 access token)
요청 한도 적용
15분당 요청 수(사용자 인증)500

매개변수

webhook_id (필수)Webhook ID입니다. 리소스 경로에 정의되어 있습니다.

요청 예시

$ curl —request GET —url https://api.x.com/1.1/account&#95;activity/webhooks/:WEBHOOK&#95;ID/subscriptions/all.json —header ‘authorization: OAuth oauth_consumer_key=“WHITELISTED_CONSUMER_KEY”, oauth_nonce=“GENERATED”, oauth_signature=“GENERATED”, oauth_signature_method=“HMAC-SHA1”, oauth_timestamp=“GENERATED”, oauth_token=“SUBSCRIBING_USER’S_ACCESS_TOKEN”, oauth_version=“1.0“‘

예시 응답 - 성공

HTTP 204 NO CONTENT
    { }

GET account_activity/webhooks/:webhook_id/subscriptions/all/list

지정된 webhook에 대해 현재 All Activity 유형 구독 목록을 반환합니다. /list 엔드포인트는 애플리케이션 전용 OAuth가 필요하므로, 요청은 사용자 컨텍스트 대신 Bearer 토큰을 사용해 수행해야 합니다.

리소스 URL

https://api.x.com/1.1/account_activity/webhooks/:webhook_id/subscriptions/all/list.json

리소스 정보

응답 형식HTTP 응답 코드
인증 필요 여부예 (애플리케이션 전용 - Bearer 토큰)
요청 한도 적용
요청 수 / 15분(애플리케이션 인증)50

매개변수

webhook_id (required)Webhook ID입니다. 리소스 경로에서 정의됩니다.

HTTP 응답 코드

CodeMessage
200성공. 요청한 웹훅에 대한 구독 리스트가 반환됩니다.
401애플리케이션에는 지정된 웹훅의 구독을 볼 수 있는 권한이 없습니다.

예시 요청

$ curl —request GET —url https://api.x.com/1.1/account&#95;activity/webhooks/:WEBHOOK&#95;ID/subscriptions/all/list.json —header ‘authorization: Bearer TOKEN’

예시 응답 - 성공

HTTP 200
    {
      "webhook_id": "1234567890",
      "webhook_url": "https://your_domain.com/webhook/twitter/0",
      "application_id": "11231812",
      "subscriptions": [{
        "user_id": "20212306"
      }]
    }

오류 메시지

코드메시지
32인증에 실패했습니다.
HTTP 401
    {
      "errors": [
        {
           "code": 32,
          "message": "Could not authenticate you."
        }
      ]
    }

DELETE account_activity/webhooks/:webhook_id

제공된 App의 설정에서 이 webhook을 제거합니다. webhook ID는 GET /1.1/account_activity/webhooks 엔드포인트를 호출하여 확인할 수 있습니다.

리소스 URL

https://api.x.com/1.1/account_activity/webhooks/:webhook_id.json

리소스 정보

응답 형식JSON
인증 필요예 (사용자 컨텍스트 - 모든 consumer 및 access 토큰)
요청 한도 적용
요청 수 / 15분 단위 (사용자 인증)15

매개변수

webhook_id (required)Webhook ID입니다. 리소스 경로에 정의됩니다.

요청 예시

    $ curl --request DELETE
     --url https://api.x.com/1.1/account_activity/webhooks/:WEBHOOK_ID.json
     --header 'authorization: OAuth oauth_consumer_key="CONSUMER_KEY", oauth_nonce="GENERATED", oauth_signature="GENERATED", oauth_signature_method="HMAC-SHA1", oauth_timestamp="GENERATED", oauth_token="ACCESS_TOKEN", oauth_version="1.0"'

응답

HTTP 204 OK
    { }

DELETE account_activity/webhooks/:webhook_id/subscriptions/all (사용 중단됨)

지정된 사용자 컨텍스트와 애플리케이션에 대한 구독을 비활성화합니다. 비활성화 후에는 요청한 사용자에 대한 모든 이벤트가 더 이상 Webhook URL로 전송되지 않습니다.

리소스 URL

https://api.x.com/1.1/account_activity/webhooks/:webhook_id/subscriptions/all.json

Resource Information

Response FormatJSON
Requires Authentication예 (3-legged OAuth - 화이트리스트에 등록된 consumer key 및 구독한 사용자의 access token)
Rate Limited
Requests / 15-min window (user auth)15분당 요청 수 (user auth): 500

매개변수

webhook_id (required)리소스 경로에 정의된 Webhook ID입니다.

예시 요청

    $ curl --request DELETE
     --url https://api.x.com/1.1/account_activity/webhooks/:WEBHOOK_ID/subscriptions/all.json
     --header 'authorization: OAuth oauth_consumer_key="WHITELISTED_CONSUMER_KEY", oauth_nonce="GENERATED", oauth_signature="GENERATED", oauth_signature_method="HMAC-SHA1", oauth_timestamp="GENERATED", oauth_token="SUBSCRIBED_USER'S_ACCESS_TOKEN", oauth_version="1.0"'
요청 예시
    { }

DELETE /account_activity/webhooks/:webhook_id/subscriptions/:user_id/all.json

지정된 webhook 및 사용자 id에 대한 구독을 비활성화합니다. 비활성화 후에는 요청한 사용자의 모든 이벤트가 더 이상 webhook URL로 전송되지 않습니다. 이 엔드포인트는 애플리케이션 전용 OAuth가 필요하므로 요청은 사용자 컨텍스트 대신 Bearer 토큰을 사용해 보내야 합니다.

리소스 URL

https://api.x.com/1.1/account_activity/webhooks/:webhook_id/subscriptions/:user_id/all.json

리소스 정보

응답 형식JSON
인증 필요예 (애플리케이션 전용 - Bearer 토큰)
요청 한도 적용 여부
15분당 요청 수500

예시 요청

    $ curl --request DELETE
     --url https://api.x.com/1.1/account_activity/webhooks/:webhook_id/subscriptions/:user_id/all.json
     --header 'authorization: Bearer TOKEN'

응답

HTTP 204 NO CONTENT

오류 메시지

코드메시지
404죄송합니다. 해당 페이지는 존재하지 않습니다. - 지정한 사용자 id가 실제로 구독 중이 아닐 때 자주 발생합니다.

Replay API

POST /1.1/account_activity/replay/webhooks/:webhook_id/subscriptions/all.json  요청에 지정된 날짜 및 시간 범위 동안 존재했던 모든 구독으로부터, 최대 지난 5일간의 활동을 가져오도록 요청을 제출합니다. 웹훅에 활성 사용자 구독이 있는 경우, 해당 이벤트도 실시간으로 함께 수신하게 됩니다. 참고: 리플레이 이벤트를 전달하기 전에 CRC를 수행합니다.
Request MethodHTTP POST
URL/1.1/account_activity/replay/webhooks/:webhook_id/subscriptions/all.json?from_date=yyyymmddhhmm&to_date=yyyymmddhhmm
Response FormatJSON
Requires Authentication예 (애플리케이션 전용 - Bearer 토큰)
Rate Limit15분당 5개 요청. 현재 요청할 수 있는 리플레이 작업의 최대 개수에는 제한이 없습니다.
from_date이벤트가 제공될 가장 오래된(시작) UTC 타임스탬프이며, ‘yyyymmddhhmm’ 형식이어야 합니다. 타임스탬프는 분 단위 정밀도를 가지며 포함 범위입니다(예: 12:00은 00분을 포함). 유효한 시간은 UTC 기준 최근 5일 이내여야 하며, 현재 시점으로부터 최소 31분 이전이어야 합니다. from_dateto_date는 약 2시간 이내 범위로 설정할 것을 권장합니다.
to_date이벤트가 제공될 가장 최근(종료) UTC 타임스탬프로, ‘yyyymmddhhmm’ 형식이어야 합니다. 타임스탬프는 분 단위 정밀도를 가지며 제외 범위입니다(예: 12:30은 해당 시의 30분을 포함하지 않음). 유효한 시간은 UTC 기준 최근 5일 이내여야 하며, 현재 시점으로부터 최소 10분 이전이어야 합니다.

응답

다음과 같은 응답을 API가 반환할 수 있습니다. 대부분의 오류 코드는 본문에 추가 세부 정보가 포함된 문자열과 함께 반환됩니다. 200이 아닌 응답이 반환되면 오류를 해결한 뒤 다시 요청해야 합니다.
StatusTextError CodeDescriptionMessage
202AcceptedN/A요청이 성공적으로 처리되었으며 활동 데이터가 전송됩니다.N/A
400Bad Request214Webhook이 유효하지 않은 것으로 표시되었습니다.Webhook is marked invalid and requires a CRC check.
400Bad Request357query parameter가 누락되었습니다.: queryParam is required.
400Bad Request358route 또는 query parameter의 형식이 올바르지 않습니다.Unable to parse parameter.
400Bad Request360route parameter가 음수입니다.webhook_id: [] is not greater than or equal to 0.
400Bad Request368from_date 또는 to_date가 과거 시점이 아닙니다.: [<field_value>] is not in the past.
400Bad Request356from_date는 to_date보다 앞서야 합니다.from_date must be before to_date.
400Bad Request356from_date는 최근 5일 이내여야 합니다.from_date must be within the past 5 days.
401Unauthorized32제공된 3-legged auth로 인해 HTTP 인증에 실패했습니다.Invalid authentication method. Please use application-only authentication.
401Unauthorized61Client는 이 메서드를 요청할 권한이 없습니다.Client is not permitted to request this method.
403Forbidden200Client에 Replay가 활성화된 enterprise 계정이 없습니다.Account Activity API enterprise account with replay is required. Please confirm you have an enterprise account and replay is enabled.
404Not Found34존재하지 않는 webhook_id이거나 webhook_id와 application_id가 일치하지 않습니다.Webhook does not exist or is associated with a different X application.
409Conflict355처리 중인 요청이 있으며, 다른 요청을 하기 전에 해당 처리가 완료되어야 합니다.A replay job is already in progress for this webhook.
429Too Many Requests88Rate limit 초과(일정 기간당 허용된 요청 수 한도에 도달함)Too many requests. Please back off your API request rate.
500Internal Server Error0내부 서버 오류입니다.Internal server error.
503Service Unavailable67X의 하나 이상의 종속 서비스가 사용 불가 상태입니다.X server error. Retry using an exponential backoff pattern.

”Job completed successfully” 메시지

작업이 성공적으로 완료되면 Account Activity Replay API는 다음과 같은 작업 완료 이벤트를 전송합니다. 이 이벤트를 수신하면 해당 작업의 실행이 완료된 것이며, 다른 작업을 제출할 수 있습니다.
{
  "replay\_job\_status": {
    "webhook_id": "1234577122340233217",
    "job_state": "Complete",
    "job\_state\_description": "Job completed successfully"
    "job_id": "1095098195724558337"
  }
}

”Job failed to complete” 메시지

작업이 성공적으로 완료되지 않은 경우 Replay 작업을 다시 시도하도록 안내하는 다음 메시지가 반환됩니다. 이 이벤트를 받으면 해당 작업의 실행은 종료된 상태이며, 새 작업을 제출할 수 있습니다.
{
  "replay\_job\_status": {
    "webhook_id": "123451374207332352",
    "job_state": "Incomplete",
    "job\_state\_description": "Job failed to deliver all events, please retry your replay job",
    "job_id": "1093226942650736640"
  }
}

예제 curl 요청

    curl --request POST  --url 'https://api.x.com/1.1/account_activity/replay/webhooks/:webhook_id/subscriptions/all.json?from_date=yyyymmddhhmm&to_date=yyyymmddhhmm'
    --header 'authorization: Bearer TOKEN'

예시 응답

HTTP 202
{
  "job_id": "1234567890",
  "created_at": "2016-06-02T23:54:02Z"
}