> ## Documentation Index
> Fetch the complete documentation index at: https://generaltranslation.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# はじめに

Powerstream は、公開 X データにアクセスするための、当社で最速のリアルタイムストリーミング API です。従来の GNIP Powetrack API と同様に、キーワード、オペレーター、メタデータに基づいてポストをフィルタリングするルールを使用します。Powerstream エンドポイントへの永続的な HTTP 接続が確立されると、ほぼリアルタイムで条件に一致するポストを受信し始めることができます。

現在、Powerstream は最大 1,000 個のルールをサポートしており、各ルールは 2048 文字まで指定できます。

<div id="key-features">
  ## 主な機能:
</div>

* **リアルタイムなデータ配信**: ルールに一致するデータをほぼリアルタイムで取得できます。
* **高精度なフィルタリング**: 演算子付きのブールクエリを使用して、必要なデータだけを正確にフィルタリングできます。
* **配信方式**: HTTP/1.1 のチャンク転送エンコーディングを用いた JSON レスポンス。
* **ローカルデータセンター対応**: レプリケーション遅延を回避してレイテンシを低減するために、ローカルデータセンターからの投稿のみを取得できます。

<Note>
  Powerstream API は、一部の Enterprise プランで利用可能なプレミアムなサービスです。

  Powerstream へのアクセスや Enterprise 向けサービスの詳細にご興味がある場合は、[Enterprise Request Form](/ja/forms/enterprise-api-interest) から営業チームまでお問い合わせください。
  Powerstream がどのようにお客様のニーズにお応えできるか、喜んでご相談させていただきます。
</Note>

<div id="quick-start">
  ## クイックスタート
</div>

このセクションでは、Python の `requests` ライブラリを使用して PowerStream エンドポイントをすぐに使い始める方法を紹介します。`pip install requests` でインストールしてください。すべての例は OAuth 2.0 ベアラートークン認証を使用します。`YOUR_BEARER_TOKEN` を実際のトークンに置き換えてください (`os.getenv('BEARER_TOKEN')` などを使って安全に保存してください) 。

各エンドポイントについて、コードスニペットとともに紹介します。ファイルの先頭に次の import があるものとします。

```python theme={null}
import requests
import json
import time
import sys
import os  # 環境変数用
```

<div id="setup">
  ### セットアップ
</div>

```python theme={null}
bearer_token = os.getenv('BEARER_TOKEN') or "YOUR_BEARER_TOKEN"  # セキュリティのため環境変数を使用
base_url = "https://api.x.com/2/powerstream"
rules_url = f"{base_url}/rules"  # ルール管理用
headers = {
   "Authorization": f"Bearer {bearer_token}",
   "Content-Type": "application/json"
}
```

<div id="1-create-rules-post-rules">
  ### 1. ルールの作成 (POST /rules)
</div>

ストリームを絞り込むためのルールを追加します。

```python theme={null}
data = {
   "rules": [
       {
           "value": "(cat OR dog) lang:en -is:retweet",
           "tag": "pet-monitor"
       },
       # 必要に応じてルールを追加してください(最大100件まで)
   ]
}

response = requests.post(rules_url, headers=headers, json=data)
if response.status_code == 201:
   rules_added = response.json().get("data", {}).get("rules", [])
   print("Rules added:")
   for rule in rules_added:
       print(f"ID: {rule['id']}, Value: {rule['value']}, Tag: {rule.get('tag', 'N/A')}")
else:
   print(f"Error {response.status_code}: {response.text}")
```

<div id="2-delete-rules-post-rules">
  ### 2. ルールを削除する (POST /rules)
</div>

id (推奨) または value を指定して、ルールを削除します。

```python theme={null}
data = {
   "rules": [
       {
           "value": "(cat OR dog) lang:en -is:retweet",
           "tag": "pet-monitor"
       },
       # 必要に応じてルールを追加してください(最大100件)
   ]
}

response = requests.delete(rules_url, headers=headers, json=data)
if response.status_code == 200:
   deleted = response.json().get("data", {})
   print(f"Deleted count: {deleted.get('deleted', 'N/A')}")
   if 'not_deleted' in deleted:
       print("Not deleted:", deleted['not_deleted'])
else:
   print(f"Error {response.status_code}: {response.text}")
```

**ヒント**: すべてのルールを削除するには、まず GET リクエストで取得し、ID を抽出してから一括削除します。

<div id="3-get-rules-get-rules">
  ### 3. ルールの取得 (GET /rules)
</div>

すべての有効なルールを取得します。

```python theme={null}
response = requests.get(rules_url, headers=headers)
if response.status_code == 200:
   rules = response.json().get("data", {}).get("rules", [])
   if rules:
       print("Active rules:")
       for rule in rules:
           print(f"ID: {rule['id']}, Value: {rule['value']}, Tag: {rule.get('tag', 'N/A')}")
   else:
       print("No active rules.")
else:
   print(f"Error {response.status_code}: {response.text}")
```

<div id="4-powerstream-get-stream">
  ### 4. PowerStream (GET /stream)
</div>

リアルタイムの投稿を取得するためにストリームに接続します。行ごとに読み取るには `stream=True` を使用します。堅牢性を高めるために、再接続ロジックを実装してください。

```python theme={null}
stream_url = base_url

def main():
   while True:
       response = requests.request("GET", stream_url, headers=headers, stream=True)
       print(response.status_code)
       for response_line in response.iter_lines():
           if response_line:
               json_response = json.loads(response_line)
               print(json.dumps(json_response, indent=4, sort_keys=True))
               if response.status_code != 200:
                   print(response.headers)
                   raise Exception(
                       "Request returned an error: {} {}".format(
                           response.status_code, response.text
                       )
                   )
```

<div id="local-datacenter-support">
  #### ローカルデータセンターサポート
</div>

レイテンシを最適化するために、Powerstream では、接続が確立されているローカルデータセンター発 (で作成された) 投稿のみを取得できるオプションを提供しています。これによりレプリケーション遅延を回避でき、他のデータセンターからの投稿と比べて、より高速に配信されます。これを有効にするには、クエリパラメータ `?localDcOnly=true` をストリームエンドポイント (例: `/2/powerstream?localDcOnly=true`) に追加します。接続しているデータセンターは、ストリームの初期データペイロード内とレスポンスの HTTP ヘッダーの両方で示されます。

コードで利用するには:

```python theme={null}
# ローカルデータセンターのみの場合:
stream_url = "https://api.x.com/2/powerstream?localDcOnly=true"
```

`localDcOnly` パラメータが有効になっている場合、ストリームが最初に接続されると、どのローカルデータセンターが使用されているかを示す次のレスポンスヘッダーが含まれます。

```bash theme={null}
'x-powerstream-datacenter': 'atla',
'x-powerstream-localdconly': 'true'
```

これに加えて、データセンターを指定する初回のペイロードも送信されます。

```bash theme={null}
{
    "type": "connection_metadata",
    "datacenter": "atla",
    "timestamp": 1762557264155
}
```

<Note>
  **ヒント:** レイテンシーを最適化するには、複数の地理的ロケーション (例：米国東海岸のアトランタ近郊と米国西海岸のポートランド近郊) から接続を構成し、それぞれで `localDcOnly=true` を有効にします。これにより、各データセンター内の投稿へより高速にアクセスできます。データセンター間のデータを統合するには、クライアント側でストリームを集約してください。
</Note>

<div id="operators">
  ## 演算子
</div>

フィルタリングルールを設定するには、キーワードと演算子を使用します。利用可能な演算子は以下のとおりです。

<div id="field-based-operators">
  ### フィールドベースの演算子
</div>

<div id="user-operators">
  #### ユーザー演算子
</div>

| Operator       | Summary            | Example                             |
| -------------- | ------------------ | ----------------------------------- |
| `from:`        | 特定のユーザーからの投稿に一致します | `from:xdevelopers` or `from:123456` |
| `to:`          | 特定のユーザー宛ての投稿に一致します | `to:jvaleski`                       |
| `retweets_of:` | 特定のユーザーのリポストに一致します | `retweets_of:xdevelopers`           |

<div id="content-operators">
  #### コンテンツ演算子
</div>

| Operator        | Summary                    | Example                                   |
| --------------- | -------------------------- | ----------------------------------------- |
| `contains:`     | 特定のテキストやキーワードを含む投稿にマッチします  | `contains:hello` または `contains:-2345.432` |
| `url_contains:` | URL に特定のテキストが含まれる投稿にマッチします | `url_contains:"com/willplayforfood"`      |
| `lang:`         | 特定の言語の投稿にマッチします            | `lang:en`                                 |

<div id="entity-operators">
  #### エンティティオペレーター
</div>

| Operator | Summary                                                                                   | Example                                 |
| -------- | ----------------------------------------------------------------------------------------- | --------------------------------------- |
| `has:`   | 特定のエンティティを含む投稿に一致します (指定可能な値: mentions, geo, links, media, lang, symbols, images, videos) | `has:images`, `has:geo`, `has:mentions` |
| `is:`    | 特定の種類、または特定のプロパティを持つ投稿に一致します (指定可能な値: retweet, reply)                                     | `is:retweet`, `is:reply`                |

<div id="location-operators">
  #### ロケーション演算子
</div>

| Operator        | Summary                   | Example                                                                                  |
| --------------- | ------------------------- | ---------------------------------------------------------------------------------------- |
| `place:`        | 特定の場所からの投稿に一致します          | `place:"Belmont Central"`, `place:02763fa2a7611cf3`                                      |
| `bounding_box:` | 地理的なバウンディングボックス内の投稿に一致します | `bounding_box:[-112.424083 42.355283 -112.409111 42.792311]`                             |
| `point_radius:` | ある地点を中心とした半径内の投稿に一致します    | `point_radius:[-111.464973 46.371179 25mi]`, `point_radius:[-111.464973 46.371179 15km]` |

<div id="advancedcontent-operators">
  #### 高度/コンテンツオペレーター
</div>

| Operator    | Summary                                   | Example |
| ----------- | ----------------------------------------- | ------- |
| `bio:`      | 特定の自己紹介文を持つユーザーの投稿に一致します (フレーズマッチを使用)     | N/A     |
| `bio_name:` | 自己紹介文内に特定の名前を含むユーザーの投稿に一致します (フレーズマッチを使用) | N/A     |

<div id="additional-operators">
  #### 追加のオペレーター
</div>

| Operator                 | Summary           | Example                                     |
| ------------------------ | ----------------- | ------------------------------------------- |
| `retweets_of_status_id:` | 特定の投稿のリポストに一致します  | `retweets_of_status_id:1234567890123456789` |
| `in_reply_to_status_id:` | 特定の投稿に対する返信に一致します | `in_reply_to_status_id:1234567890123456789` |

<div id="non-field-operators">
  ### フィールド以外の演算子
</div>

<div id="special-syntax-operators">
  #### 特殊構文演算子
</div>

| 演算子     | 概要          | 例                |
| ------- | ----------- | ---------------- |
| `@`     | メンション演算子    | `@username`      |
| フレーズマッチ | フレーズの完全一致検索 | `"exact phrase"` |

<div id="logical-operators">
  #### 論理演算子
</div>

| Operator  | Summary        | Example                             |
| --------- | -------------- | ----------------------------------- |
| `OR`      | 複数の式の論理和 (OR)  | `x OR facebook`                     |
| Space/AND | 複数の式の論理積 (AND) | `x facebook` (両方の語が含まれている必要があります)   |
| `()`      | 複雑な式をまとめてグループ化 | `(x OR facebook) iphone`            |
| `-`       | 否定／除外          | `x -facebook` (x だが facebook は含まない) |

<div id="responses">
  ## レスポンス
</div>

Powerstream API のペイロードは、レガシー版 GNIP Powertrack API と同じ形式です。JSON レスポンスの例は次のとおりです。

```json theme={null}
[
   {
       "created_at": "Tue Mar 21 20:50:14 +0000 2006",
       "id": 20,
       "id_str": "20",
       "text": "just setting up my twttr",
       "truncated": false,
       "entities": {
           "hashtags": [],
           "symbols": [],
           "user_mentions": [],
           "urls": []
       },
       "source": "<a href=\"http://x.com\" rel=\"nofollow\">X Web Client</a>",
       "in_reply_to_status_id": null,
       "in_reply_to_status_id_str": null,
       "in_reply_to_user_id": null,
       "in_reply_to_user_id_str": null,
       "in_reply_to_screen_name": null,
       "user": {
           "id": 12,
           "id_str": "12",
           "name": "jack",
           "screen_name": "jack",
           "location": "",
           "description": "no state is the best state",
           "url": "https://t.co/ZEpOg6rn5L",
           "entities": {
               "url": {
                   "urls": [
                       {
                           "url": "https://t.co/ZEpOg6rn5L",
                           "expanded_url": "http://primal.net/jack",
                           "display_url": "primal.net/jack",
                           "indices": [
                               0,
                               23
                           ]
                       }
                   ]
               },
               "description": {
                   "urls": []
               }
           },
           "protected": false,
           "followers_count": 6427829,
           "friends_count": 3,
           "listed_count": 32968,
           "created_at": "Tue Mar 21 20:50:14 +0000 2006",
           "favourites_count": 36306,
           "utc_offset": null,
           "time_zone": null,
           "geo_enabled": true,
           "verified": false,
           "statuses_count": 30134,
           "lang": null,
           "contributors_enabled": false,
           "is_translator": false,
           "is_translation_enabled": false,
           "profile_background_color": "EBEBEB",
           "profile_background_image_url": "http://abs.twimg.com/images/themes/theme7/bg.gif",
           "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme7/bg.gif",
           "profile_background_tile": false,
           "profile_image_url": "http://pbs.twimg.com/profile_images/1661201415899951105/azNjKOSH_normal.jpg",
           "profile_image_url_https": "https://pbs.twimg.com/profile_images/1661201415899951105/azNjKOSH_normal.jpg",
           "profile_banner_url": "https://pbs.twimg.com/profile_banners/12/1742427520",
           "profile_link_color": "990000",
           "profile_sidebar_border_color": "DFDFDF",
           "profile_sidebar_fill_color": "F3F3F3",
           "profile_text_color": "333333",
           "profile_use_background_image": true,
           "has_extended_profile": true,
           "default_profile": false,
           "default_profile_image": false,
           "following": null,
           "follow_request_sent": null,
           "notifications": null,
           "translator_type": "regular",
           "withheld_in_countries": []
       },
       "geo": null,
       "coordinates": null,
       "place": null,
       "contributors": null,
       "is_quote_status": false,
       "retweet_count": 122086,
       "favorite_count": 263321,
       "favorited": false,
       "retweeted": false,
       "lang": "en"
   }
]
```

<div id="limits-best-practices">
  ## 制限事項とベストプラクティス
</div>

* レート制限: ルール管理は 24時間あたり 50 リクエスト。ストリーム自体に制限はありません (ただし接続数の制限が適用されます) 。
* 再接続: 切断時は指数バックオフ方式で再接続します。
* 監視: `Connection: keep-alive` ヘッダーを使用します。
