TwexAPI で X の DM 到達性を確認する方法
DM アウトリーチで見落とされやすいのは、メッセージ本文ではなく、相手が今そのメッセージを受け取れるかです。DM を閉じているアカウント、フォロー中ユーザーからしか受け取らないアカウント、Premium や XChat 条件が関係するアカウントがあります。確認せずに送ると、文面が悪かったのか、そもそも届く経路がなかったのか分からなくなります。
TwexAPI の POST /v2/dm/status は、この送信前チェックに使えます。username または user ID の配列を送信し、can_dm、dm_blocking、can_dm_on_xchat、認証関連フィールドを読みます。CRM、サポートキュー、成長施策の前に入れることで、送信、別チャネル、または人間レビューを判断できます。
いつ先に DM 状態を確認するか
DM 到達性チェック とは、送信前に対象アカウントが現在の条件で到達可能かを API で一括確認することです。これはリードスコアでも、最終的な送達保証でもありません。送信前の説明可能な確認です。
使う場面:
- 営業や提携アウトリーチ:送信キューに入れる前に、
can_dmがtrueではないアカウントを除外する。 - サポートとコミュニティ運用:公開投稿で問い合わせがあったとき、DM に移れるか確認する。
- CRM 同期:DM 到達性を連絡先フィールドとして保存し、X、メール、別チャネルを選べるようにする。
- キャンペーンリスト整理:クリエイター、KOL、提携アカウントの入庫時に到達性を記録する。
can_dm: false を「このアカウントには永遠に DM できない」と書かないでください。これは今回のクエリで返った状態です。設定、フォロー関係、認証条件、プラットフォームルールは変わるため、確認時刻を保存し、重要な連絡先は再確認します。
API エンドポイント
API エンドポイント とは、現在の OpenAPI にある V2 DM 状態確認 API、POST /v2/dm/status です。リクエスト body は文字列配列で、各要素は X user ID または username です。
POST https://api.twexapi.io/v2/dm/status
Authorization: Bearer <your_token>
Content-Type: application/json
["1696160451770429440", "elonmusk", "openai"]主要なレスポンス構造:
1{
2 "code": 200,
3 "msg": "success",
4 "data": [
5 {
6 "user_id": "1696160451770429440",
7 "screen_name": "example_user",
8 "is_blue_verified": false,
9 "is_verified_organization_affiliate": false,
10 "verified": false,
11 "can_dm": true,
12 "can_dm_on_xchat": null,
13 "dm_blocking": false,
14 "passes_premium_check": true
15 }
16 ]
17}フィールドは保守的に解釈します。
| フィールド | 用途 |
|---|---|
user_id | 安定したアカウント ID |
screen_name | 現在の username |
can_dm | 現在 DM 可能に見えるかの主シグナル |
dm_blocking | DM ブロックシグナル |
can_dm_on_xchat | XChat 関連の到達性シグナル、null もある |
passes_premium_check | Premium 条件に関する説明 |
is_blue_verified、is_verified_organization_affiliate、verified | 認証コンテキストであり、単独の送信許可ではない |
Python の例
Python の例 とは、サーバー側の一括事前確認スクリプトです。入力を整形し、V2 エンドポイントを呼び、フィールドを正規化し、連絡先ごとに次のアクションを返します。DM 送信自体は行いません。
1import os
2from datetime import datetime, timezone
3
4import requests
5
6API_URL = "https://api.twexapi.io/v2/dm/status"
7TOKEN = os.environ["TWEXAPI_BEARER_TOKEN"]
8
9def clean_targets(targets):
10 cleaned = []
11 seen = set()
12
13 for target in targets:
14 value = str(target).strip().lstrip("@")
15 if not value or value.lower() in seen:
16 continue
17
18 cleaned.append(value)
19 seen.add(value.lower())
20
21 return cleaned
22
23def check_dm_reachability(targets):
24 cleaned = clean_targets(targets)
25 if not cleaned:
26 return []
27
28 response = requests.post(
29 API_URL,
30 headers={
31 "Authorization": f"Bearer {TOKEN}",
32 "Content-Type": "application/json",
33 "Accept": "application/json",
34 },
35 json=cleaned,
36 timeout=30,
37 )
38 response.raise_for_status()
39 payload = response.json()
40
41 if payload.get("code", 200) >= 400:
42 raise RuntimeError(payload.get("msg", "TwexAPI returned an error"))
43
44 checked_at = datetime.now(timezone.utc).isoformat()
45 rows = []
46
47 for item in payload.get("data") or []:
48 can_dm = item.get("can_dm") is True
49 blocked = item.get("dm_blocking") is True
50
51 if can_dm and not blocked:
52 decision = "READY_TO_MESSAGE"
53 elif blocked:
54 decision = "DO_NOT_MESSAGE"
55 else:
56 decision = "RECHECK_OR_USE_OTHER_CHANNEL"
57
58 rows.append({
59 "user_id": item.get("user_id"),
60 "screen_name": item.get("screen_name"),
61 "can_dm": item.get("can_dm"),
62 "dm_blocking": item.get("dm_blocking"),
63 "can_dm_on_xchat": item.get("can_dm_on_xchat"),
64 "passes_premium_check": item.get("passes_premium_check"),
65 "verified": item.get("verified"),
66 "decision": decision,
67 "checked_at": checked_at,
68 "raw": item,
69 })
70
71 return rows
72
73targets = ["elonmusk", "@openai", "1696160451770429440"]
74
75for row in check_dm_reachability(targets):
76 print(row["screen_name"], row["decision"], row["can_dm"])本番では、正規化フィールドと raw レスポンスの両方を保存します。正規化データは CRM やルールエンジンに使いやすく、raw JSON はフィールド変化や誤判定の調査に役立ちます。
アウトリーチフローに入れる
アウトリーチフロー とは、送信失敗後に補修するのではなく、送信前に DM 状態を確認することです。実用的な流れは、リスト入庫、状態確認、ルール分岐、送信前再確認、結果書き戻しです。
- リスト入庫:
screen_name、user_id、リストソース、キャンペーン ID、担当者を保存する。 - 一括事前確認:
/v2/dm/statusを呼び、can_dm、dm_blocking、passes_premium_check、raw レスポンスを保存する。 - ルール分岐:
can_dm === trueかつブロックシグナルがなければ送信キューへ。その他はメール、公開返信、人間レビューへ回す。 - 送信前再確認:高価値連絡先は送信直前に再確認する。
- 結果書き戻し:送信結果、失敗理由、最後の DM 状態を CRM に保存する。
価値は失敗送信の削減だけではありません。各連絡先がなぜ DM キューに入ったか、または外れたかを説明できます。
状態の解釈
状態の解釈 とは、API フィールドを業務アクションに保守的に変換することです。can_dm は主シグナルですが、dm_blocking、Premium チェック、認証フィールド、確認時刻と一緒に見ます。
| 返却シグナル | 推奨アクション |
|---|---|
can_dm === true かつ dm_blocking !== true | DM 送信キューに入れられる |
can_dm === false | 自動送信せず、別チャネルまたは後日再確認 |
dm_blocking === true | 送信を止め、理由を保存 |
passes_premium_check === false | アカウント、送信条件、X ルールを確認 |
認証フィールドが true | 文脈として使うが、単独の許可ではない |
フィールドが null | 不明として扱い、自動承認しない |
送信アカウント、cookie、フォロー関係、Premium 状態が変わる場合、DM 状態を長期間キャッシュしないでください。通常のリストは時間または日単位で更新し、高価値連絡先は送信直前に再確認します。
最小本番構成
最小本番構成 とは、一括リクエスト、重複排除、タイムアウト、エラー処理、状態保存、再確認ルールだけを持つことです。
最低限保存するフィールド:
| フィールド | 理由 |
|---|---|
target_input | username 変更や ID 混在の調査 |
user_id と screen_name | 安定した照合と表示 |
can_dm、dm_blocking、can_dm_on_xchat | 到達性判断 |
passes_premium_check | Premium 条件の説明 |
| 認証フィールド | 営業、サポート、リスク文脈 |
decision | ルールによる業務アクション |
checked_at | 状態が古いか判断 |
raw_response | フィールド変更時の再処理 |
エラー処理では、401 は通常 Token 問題なのでジョブを止めます。422 はリクエスト body 形式の問題としてバッチ単位で記録します。ネットワークタイムアウトはリトライできますが、同じ連絡先を無限に再試行しないでください。
よくある誤り
よくある誤り とは、DM 到達性を永続的な事実として扱ったり、認証フィールドを送信許可として扱うことです。
- 現在の OpenAPI V2 パス
/v2/dm/statusを使う。 - V2 レスポンスの
can_dm、dm_blocking、関連コンテキストフィールドを見る。 can_dm: trueを送達保証と書かない。関係性、設定、プラットフォームルールで送信は失敗する可能性がある。can_dm: falseを永久に到達不能と書かない。今回のクエリ状態では直接 DM に適さないという意味です。
まとめ
まとめ とは、DM 状態を送信前の到達性チェックとして扱うことです。username または user ID 配列を POST /v2/dm/status に送り、can_dm、dm_blocking、passes_premium_check を読み、raw レスポンスと確認時刻を保存し、CRM、サポートキュー、アウトリーチルールに書き戻します。