From ecc
트윗, 스레드 게시, 타임라인 조회, 검색, 분석을 위한 X/Twitter API 통합입니다. OAuth 인증 패턴, 레이트 리밋, 플랫폼 네이티브 콘텐츠 게시를 다룹니다. 사용자가 X를 코드로 다루고 싶을 때 사용합니다.
npx claudepluginhub sam42-lab/everything-claude-code-krThis skill uses the workspace's default tool permissions.
게시, 조회, 검색, 분석을 위한 X(Twitter) 프로그래매틱 연동입니다.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
게시, 조회, 검색, 분석을 위한 X(Twitter) 프로그래매틱 연동입니다.
"post to X", "tweet", "X API", "Twitter API"라고 말할 때적합한 용도: 읽기 중심 작업, 검색, 공개 데이터 조회
# 환경 변수 설정
export X_BEARER_TOKEN="your-bearer-token"
import os
import requests
bearer = os.environ["X_BEARER_TOKEN"]
headers = {"Authorization": f"Bearer {bearer}"}
# 최근 트윗 검색
resp = requests.get(
"https://api.x.com/2/tweets/search/recent",
headers=headers,
params={"query": "claude code", "max_results": 10}
)
tweets = resp.json()
필요한 용도: 트윗 게시, 계정 관리, DM, 모든 쓰기 작업
# 환경 변수 설정 — 사용 전 source
export X_CONSUMER_KEY="your-consumer-key"
export X_CONSUMER_SECRET="your-consumer-secret"
export X_ACCESS_TOKEN="your-access-token"
export X_ACCESS_TOKEN_SECRET="your-access-token-secret"
예전 구성에서는 X_API_KEY, X_API_SECRET, X_ACCESS_SECRET 같은 레거시 별칭이 있을 수 있습니다. 새 흐름을 문서화하거나 연결할 때는 X_CONSUMER_*, X_ACCESS_TOKEN_SECRET 이름을 우선합니다.
import os
from requests_oauthlib import OAuth1Session
oauth = OAuth1Session(
os.environ["X_CONSUMER_KEY"],
client_secret=os.environ["X_CONSUMER_SECRET"],
resource_owner_key=os.environ["X_ACCESS_TOKEN"],
resource_owner_secret=os.environ["X_ACCESS_TOKEN_SECRET"],
)
resp = oauth.post(
"https://api.x.com/2/tweets",
json={"text": "Hello from Claude Code"}
)
resp.raise_for_status()
tweet_id = resp.json()["data"]["id"]
def post_thread(oauth, tweets: list[str]) -> list[str]:
ids = []
reply_to = None
for text in tweets:
payload = {"text": text}
if reply_to:
payload["reply"] = {"in_reply_to_tweet_id": reply_to}
resp = oauth.post("https://api.x.com/2/tweets", json=payload)
tweet_id = resp.json()["data"]["id"]
ids.append(tweet_id)
reply_to = tweet_id
return ids
resp = requests.get(
f"https://api.x.com/2/users/{user_id}/tweets",
headers=headers,
params={
"max_results": 10,
"tweet.fields": "created_at,public_metrics",
}
)
resp = requests.get(
"https://api.x.com/2/tweets/search/recent",
headers=headers,
params={
"query": "from:affaanmustafa -is:retweet",
"max_results": 10,
"tweet.fields": "public_metrics,created_at",
}
)
resp = requests.get(
"https://api.x.com/2/tweets/search/recent",
headers=headers,
params={
"query": "from:affaanmustafa -is:retweet -is:reply",
"max_results": 25,
"tweet.fields": "created_at,public_metrics",
}
)
voice_samples = resp.json()
resp = requests.get(
"https://api.x.com/2/users/by/username/affaanmustafa",
headers=headers,
params={"user.fields": "public_metrics,description,created_at"}
)
# 미디어 업로드는 v1.1 엔드포인트 사용
# 1단계: 미디어 업로드
media_resp = oauth.post(
"https://upload.twitter.com/1.1/media/upload.json",
files={"media": open("image.png", "rb")}
)
media_id = media_resp.json()["media_id_string"]
# 2단계: 미디어 포함 게시
resp = oauth.post(
"https://api.x.com/2/tweets",
json={"text": "Check this out", "media": {"media_ids": [media_id]}}
)
X API의 레이트 리밋은 엔드포인트, 인증 방식, 계정 티어에 따라 달라지고 시간에 따라 바뀝니다. 항상 다음을 지킵니다.
x-rate-limit-remaining, x-rate-limit-reset 헤더를 읽습니다.import time
remaining = int(resp.headers.get("x-rate-limit-remaining", 0))
if remaining < 5:
reset = int(resp.headers.get("x-rate-limit-reset", 0))
wait = max(0, reset - int(time.time()))
print(f"Rate limit approaching. Resets in {wait}s")
resp = oauth.post("https://api.x.com/2/tweets", json={"text": content})
if resp.status_code == 201:
return resp.json()["data"]["id"]
elif resp.status_code == 429:
reset = int(resp.headers["x-rate-limit-reset"])
raise Exception(f"Rate limited. Resets at {reset}")
elif resp.status_code == 403:
raise Exception(f"Forbidden: {resp.json().get('detail', 'check permissions')}")
else:
raise Exception(f"X API error {resp.status_code}: {resp.text}")
.env 파일을 사용합니다..env 파일 커밋 금지. .gitignore에 추가합니다.brand-voice와 content-engine으로 플랫폼 네이티브 콘텐츠를 만든 뒤 X API로 게시합니다.
VOICE PROFILE을 만들거나 재사용합니다.content-engine으로 X 네이티브 형식의 콘텐츠를 생성합니다.public_metrics로 참여도를 추적합니다.brand-voice — 실제 X 및 사이트/소스 자료에서 재사용 가능한 보이스 프로필 생성content-engine — X용 플랫폼 네이티브 콘텐츠 생성crosspost — X, LinkedIn 등 여러 플랫폼에 콘텐츠 배포connections-optimizer — 네트워크 기반 아웃리치 초안 전 X 그래프 정리