xdevplatform/xurl
GitHub: xdevplatform/xurl
一个基于 Go 的命令行工具,提供对 X API 的 OAuth 1.0a/2.0 认证与多应用管理,解决手动请求与令牌分发难题。
Stars: 765 | Forks: 63
# xurl - 用于 X API 的类似 curl 的 CLI 工具
一个用于与 X(前身为 Twitter)API 交互的命令行工具,支持 OAuth 1.0a 和 OAuth 2.0 认证。
## 功能特性
- **多应用支持** — 为不同的 X API 应用注册独立的凭据和令牌
- OAuth 2.0 PKCE 流程认证
- OAuth 1.0a 认证
- 每个应用支持多个 OAuth 2.0 账户
- 默认应用和默认用户选择(交互式 Bubble Tea 选择器或单条命令)
- 以 YAML 格式持久化存储令牌(`~/.xurl`),自动从旧版 JSON 迁移
- HTTP 请求自定义(头部、方法、主体)
- 通过 `--app` 参数对每个请求覆盖应用
## 安装
### Homebrew(macOS)
```
brew install --cask xdevplatform/tap/xurl
```
### npm
```
npm install -g @xdevplatform/xurl
```
### Shell 脚本(无需 sudo)
```
curl -fsSL https://raw.githubusercontent.com/xdevplatform/xurl/main/install.sh | bash
```
安装到 `~/.local/bin`。如果该路径不在你的 PATH 中,脚本会提示你需要添加什么。
### Go
```
go install github.com/xdevplatform/xurl@latest
```
## 使用
### 认证
使用此工具前,你必须拥有开发者账户和应用。
#### 注册应用
注册你的 X API 应用凭据,以便它们被存储在 `~/.xurl` 中(此后无需设置环境变量):
```
xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET
```
如果你希望该应用在 `~/.xurl` 中保留自己的回调配置,也可以将重定向 URI 存储在其中:
```
xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET --redirect-uri http://localhost:8080/callback
```
你可以注册多个应用:
```
xurl auth apps add prod-app --client-id PROD_ID --client-secret PROD_SECRET
xurl auth apps add dev-app --client-id DEV_ID --client-secret DEV_SECRET
```
#### OAuth 2.0 用户上下文
**注意:** 使用 OAuth 2.0 认证时,必须在 [X API 开发者门户](https://developer.x.com/en/portal/dashboard) 中指定重定向 URI。
1. 在 [X API 开发者门户](https://developer.x.com/en/portal/dashboard) 创建一个应用。
2. 进入认证设置,将重定向 URI 设置为 `xurl` 将使用的相同值,通过 `REDIRECT_URI`。
默认值为 `http://localhost:8080/callback`,`xurl` 从有效的重定向 URI 中派生回调主机、端口和路径。有效值按以下顺序解析:`REDIRECT_URI` 环境变量 → 应用存储的 `redirect_uri` → 内置默认值。当使用 `localhost` 时,`xurl` 会同时监听 `127.0.0.1` 和 `::1`,以便浏览器回环解析不会破坏回调。


3. 注册应用(如果尚未注册):
```
xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET
```
4. 获取访问密钥:
```
xurl auth oauth2
```
如果 X 返回 `client-forbidden` / `client-not-enrolled` 错误,即使认证已成功,请检查应用的包和环境设置。在当前 X 平台设置中,修复方法是:
1. 进入 `Apps` -> `Manage apps`
2. 打开应用
3. 使用 `Move to package`
4. 选择 `Pay-per-use`
5. 将应用移动到 `Production` 环境
如果没有完成此注册步骤,即使 OAuth 回调和令牌有效,`xurl whoami` 和其他 `/2/*` 读取操作也可能失败。
如果 X 不能通过 `/2/users/me` 可靠地返回你的用户名,可以使用显式的用户名句柄进行认证:
```
xurl auth oauth2 YOUR_USERNAME
```
这样可以将 OAuth2 令牌与预期的用户名关联,并在 `/2/users/me` 不可用时为快捷命令提供备用方案。
#### 应用认证(承载令牌):
```
xurl auth app --bearer-token BEARER_TOKEN
```
#### OAuth 1.0a 认证:
```
xurl auth oauth1 --consumer-key KEY --consumer-secret SECRET --access-token TOKEN --token-secret SECRET
```
### 多应用管理
列出已注册的应用:
```
xurl auth apps list
```
更新现有应用的凭据:
```
xurl auth apps update my-app --client-id NEW_ID --client-secret NEW_SECRET
xurl auth apps update my-app --redirect-uri http://localhost:8080/callback
```
`REDIRECT_URI` 环境变量仍会在运行时覆盖存储的应用值,因此对于每个应用的默认回调,`auth apps update --redirect-uri` 是最佳选择,而环境变量仍作为临时覆盖路径。
查看应用的有效和存储的 URI:
```
xurl auth apps redirect-uri get my-app
```
设置应用存储的 URI:
```
xurl auth apps redirect-uri set my-app http://localhost:8080/callback
```
移除应用:
```
xurl auth apps remove old-app
```
设置默认应用和用户 — **交互式选择器**(使用 Bubble Tea):
```
xurl auth default
```
设置默认应用和用户 — **单条命令**:
```
xurl auth default my-app # set default app
xurl auth default my-app alice # set default app + default user
```
为单个请求使用特定应用:
```
xurl --app dev-app /2/users/me
```
### 认证状态
查看所有应用的认证状态:
```
xurl auth status
```
此输出会显示每个应用的有效重定向 URI,并在环境变量设置了 `REDIRECT_URI` 时单独显示存储的应用值,以便查看优先级顺序。
示例输出:
```
▸ my-app [client_id: VUttdG9P…]
redirect_uri: http://localhost:8080/callback [app config]
▸ oauth2: alice
oauth2: bob
oauth1: ✓
bearer: ✓
dev-app [client_id: OTHER789…]
redirect_uri: http://localhost:8080/callback [built-in default]
oauth2: (none)
oauth1: –
bearer: –
```
### X 平台注册问题排查
如果认证成功但类似 `xurl whoami` 的读取操作失败,并返回包含 `client-forbidden` 或 `client-not-enrolled` 错误体的响应,当前 X 平台的修复方法是将应用移动到 `Pay-per-use` 包并在开发者控制台中将其环境设置为 `Production`。这是一个 X 平台的注册问题,而不是 `xurl` 本地回调监听器的问题。
左侧的 `▸` 表示默认应用。紧邻用户的 `▸` 表示默认用户。
### 清除认证
```
xurl auth clear --all # Clear all tokens
xurl auth clear --oauth1 # Clear OAuth 1.0a tokens
xurl auth clear --oauth2-username USERNAME # Clear specific OAuth 2.0 token
xurl auth clear --bearer # Clear bearer token
```
### 发起请求
基础 GET 请求:
```
xurl /2/users/me
```
自定义 HTTP 方法:
```
xurl -X POST /2/tweets -d '{"text":"Hello world!"}'
```
添加请求头:
```
xurl -H "Content-Type: application/json" /2/tweets
```
指定认证类型:
```
xurl --auth oauth2 /2/users/me
xurl --auth oauth1 /2/tweets
xurl --auth app /2/users/me
```
使用特定的 OAuth 2.0 账户:
```
xurl --username johndoe /2/users/me
```
### 流式响应
对于流式端点(如 `/2/tweets/search/stream`)会自动检测并妥善处理。该工具会自动为这些端点流式传输响应:
- `/2/tweets/search/stream`
- `/2/tweets/sample/stream`
- `/2/tweets/sample10/stream`
- `/2/tweets/firehose/stream/lang/en`
- `/2/tweets/firehose/stream/lang/ja`
- `/2/tweets/firehose/stream/lang/ko`
- `/2/tweets/firehose/stream/lang/pt`
例如:
```
xurl /2/tweets/search/stream
```
你也可以使用 `--stream` 或 `-s` 标志强制启用流式模式:
```
xurl -s /2/users/me
```
### 临时 Webhook 设置
`xurl` 可以帮助你快速设置一个临时的 Webhook URL,以便接收来自 X API 的事件。这在开发和测试中非常有用。
1. **使用 ngrok 启动本地 Webhook 服务器:**
运行 `webhook start` 命令。这将启动本地服务器并使用 ngrok 创建一个公开 URL,将请求转发到你的本地服务器。如果尚未配置 `NGROK_AUTHTOKEN` 环境变量,系统会提示你输入 ngrok 的认证令牌。
xurl webhook start
# 或者使用指定端口和输出文件记录 POST 请求体
xurl webhook start -p 8081 -o webhook_events.log
命令会输出一个 ngrok URL(例如:`https://your-unique-id.ngrok-free.app/webhook`)。请记录下这个 URL。
2. **使用 X API 注册 Webhook:**
使用上一步获得的 ngrok URL 来注册你的 Webhook。通常你需要使用应用认证来完成此操作。
# 将 https://your-ngrok-url.ngrok-free.app/webhook 替换为实际的 URL
xurl --auth app /2/webhooks -d '{"url": ""}' -X POST
此时,你本地的 `xurl webhook start` 服务器将处理来自 Twitter 的 CRC 握手,并记录所有传入的 POST 事件(如果使用了 `-o` 参数,还会写入文件)。
### 媒体上传
该工具支持使用分块上传流程将媒体文件上传到 X API。
上传媒体文件:
```
xurl media upload path/to/file.mp4
```
使用自定义媒体类型和分类:
```
xurl media upload --media-type image/jpeg --category tweet_image path/to/image.jpg
```
检查媒体上传状态:
```
xurl media status MEDIA_ID
```
等待媒体处理完成:
```
xurl media status --wait MEDIA_ID
```
#### 直接媒体上传
你也可以使用主命令配合 `-` 标志进行直接媒体上传:
1. 首先初始化上传:
```
xurl -X POST '/2/media/upload?command=INIT&total_bytes=FILE_SIZE&media_type=video/mp4&media_catefory=tweet_video'
```
2. 接着追加媒体分块:
```
xurl -X POST -F path/to/file.mp4 '/2/media/upload?command=APPEND&media_id=MEDIA_ID&segment_index=0'
```
3. 最后完成上传:
```
xurl -X POST '/2/media/upload?command=FINALIZE&media_id=MEDIA_ID'
```
4. 检查状态:
```
xurl '/2/media/upload?command=STATUS&media_id=MEDIA_ID'
```
## 令牌存储
令牌和应用凭据以 YAML 格式存储在 `~/.xurl` 中。每个注册应用都有其独立的令牌集合。示例:
```
apps:
my-app:
client_id: abc123
client_secret: secret456
redirect_uri: http://localhost:8080/callback
default_user: alice
oauth2_tokens:
alice:
type: oauth2
oauth2:
access_token: "..."
refresh_token: "..."
expiration_time: 1234567890
bearer_token:
type: bearer
bearer: "AAAA..."
default_app: my-app
```
## 贡献
欢迎贡献!
## 许可证
本项目根据 MIT 许可证开源,详情参见 LICENSE 文件。
标签:Bubble Tea, CLI, EVTX分析, Go 安装, Homebrew, HTTP 请求, JSON 迁移, npm, OAuth 1.0a, OAuth 2.0, PKCE, Shell 安装, Twitter API, WiFi技术, X API, YAML 配置, 交互式选择器, 令牌存储, 回调配置, 多应用管理, 应用覆盖, 开发者账户, 持久化存储, 日志审计, 自动迁移, 请求体, 请求头定制, 请求方法, 重定向 URI