GoToSocial 0.22.3 常用 CLI 命令与 API 详解
GoToSocial 0.22.3 常用 CLI 命令与 REST API 详解:server/database/admin 等五大子命令与账号管理实测,Mastodon 兼容 API 的 OAuth 认证、发帖、时间线、媒体上传全流程 curl 实测。
GoToSocial 0.22.3 常用 CLI 命令与 API 详解
目标:把 GoToSocial v0.22.3 的运维入口一次讲全——
gotosocial命令行工具(server/database/migrations/debug/admin 五大子命令树)与 Mastodon 兼容 REST API(应用注册、OAuth 换 token、发帖、时间线、媒体上传、实例信息),全部命令与 JSON 回显在 Ubuntu 22.04.5 实测环境(/gotosocial、端口 8147、演示账号admin)逐条验证。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS x86_64
- 软件版本:GoToSocial
0.22.3+git-5a6c8e2(安装见《Ubuntu 22.04 安装 GoToSocial 0.22.3 指南》) - 实例形态:本地实例模式(
host: localhost、HTTP、端口 8147、SQLite、本地存储) - 演示账号:
admin/Q1w2E3r4T5!(CLI 创建并已 promote 为管理员) - API 基址:
http://localhost:8147(Mastodon 兼容 API 前缀/api/v1,OAuth 前缀/oauth) - 客户端工具:curl 7.81.0(系统自带)
二、工具概览
GoToSocial 的运维入口只有两样:单二进制自带的 CLI(服务启动、数据库、迁移、调试、账号管理全在这一个命令里)与 REST API(Mastodon 兼容,Web 设置面板与第三方客户端都走它)。CLI 结构(gotosocial --help 实测首段):
GoToSocial - a fediverse social media server
Usage:
gotosocial [command]
Available Commands:
admin gotosocial admin-related tasks
completion Generate the autocompletion script for the specified shell
database gotosocial database-releated tasks
debug gotosocial debug-related tasks
help Help about any command
migrations gotosocial migrations-related tasks
server gotosocial server-related tasks
Flags:
--account-domain string Domain to use in account names …
--bind-address string Bind address to use for the GoToSocial server …(default "0.0.0.0")
…(全局 flag 与全部配置键一一对应)
💡 技术拓展:联邦社交服务器的 API 兼容策略不止一种。主流对比——
策略 代表 特点 兼容 Mastodon REST API GoToSocial、Akkoma、Pleroma 直接复用 Mastodon 客户端生态 自有 API + 兼容层 Misskey 自家 API 为主,Mastodon 兼容是子集 仅 ActivityPub 早期实现 无客户端 API,功能受限 GoToSocial 全量实现 Mastodon 客户端 API(含 OAuth 流程),本文 API 章节即按该口径实测。
三、前置条件
- 服务已启动并监听:
systemctl is-active gotosocial为active,curl -s -o /dev/null -w "%{http_code}" http://localhost:8147/返回200; - 至少存在一个本地账号:
admin account list能看到记录(创建方法见安装指南 7.1); - CLI 命令统一在
/gotosocial目录以配置文件参数执行:./gotosocial --config-path ./config.yaml <子命令>(systemd 场景亦同,服务以gotosocial用户运行,CLI 操作建议su -s /bin/bash gotosocial或保证对该用户数据目录的写权限)。
四、主命令详解
gotosocial 根命令下五个功能子命令,逐一实测。
4.1 server:服务启停与维护模式
./gotosocial server --help
实测回显:
gotosocial server-related tasks
Usage:
gotosocial server [command]
Available Commands:
maintenance start the gotosocial server in maintenance mode (returns 503 for almost all requests)
start start the gotosocial server
server start:前台启动服务(systemd 单元的 ExecStart 即此命令);server maintenance:以维护模式启动,除探活外全部请求返回 503,用于迁移数据库前挂公告页。日常启停用 systemd:
systemctl start gotosocial && systemctl is-active gotosocial
实测回显:
active
4.2 database:数据库连通与专属任务
./gotosocial --config-path ./config.yaml database ping
实测回显(输出节选,INFO 日志 + ping 确认):
timestamp="29/10/2026 17:45:11.495" func=bundb.sqliteConn level=INFO msg="connected to SQLITE database with address file:/gotosocial/sqlite.db?_pragma=busy_timeout%281800000%29&_pragma=journal_mode%28WAL%29&_pragma=synchronous%28NORMAL%29&_pragma=cache_size%28-8192%29&_txlock=immediate"
timestamp="29/10/2026 17:45:11.496" func=bundb.doMigration level=INFO msg="there are no new migrations to run"
timestamp="29/10/2026 17:45:11.496" func=database.Ping.func1 level=INFO msg=ping
服务运行中执行 ping 亦成功(SQLite WAL 读写并发),输出末尾进程以 done! exiting... 退出。database sqlite 子命令提供 SQLite 专属维护任务(vacuum/analyze 类);切 PostgreSQL 后同命令探测 PG 连通性。
4.3 migrations:手动跑迁移
./gotosocial migrations --help
实测回显:
gotosocial migrations-related tasks
Usage:
gotosocial migrations [command]
Available Commands:
run starts and stops the database, running any outstanding migrations
migrations run 会临时拉起数据库服务执行未完成的迁移再退出。日常无需手动执行——server start 启动时自动迁移(日志 doMigration),它主要在升级排障时使用。
4.4 debug:配置与调试
./gotosocial debug --help
实测回显:
gotosocial debug-related tasks
Usage:
gotosocial debug [command]
Available Commands:
config print the collated config (derived from env, flag, and config file) to stdout
debug config 把 flag/env/文件/默认值四级合并后的生效配置以 JSON 打印(249 键),是配置排障第一工具,用法与回显见《GoToSocial 0.22.3 配置参数详解》第三章。
五、admin 命令详解
管理员的日常入口,覆盖账号、媒体、状态与数据导入导出(gotosocial admin --help 实测):
Available Commands:
account admin commands related to local (this instance) accounts
export export data from the database to file at the given path
import import data from a file into the database
media admin commands related to stored media / emojis
statuses admin commands related to stored statuses
5.1 admin account:本地账号管理
./gotosocial admin account --help
实测回显(9 个子命令):
Available Commands:
confirm confirm an existing local account manually, thereby skipping email confirmation
create create a new local account
demote demote a local account from admin to normal user
disable set 'disabled' to true on a local account to prevent it from signing in or posting etc, but don't delete anything
disable-2fa disable 2fa for the given local account
enable undo a previous disable command by setting 'disabled' to false on a local account
list list all existing local accounts
password set a new password for the given local account
promote promote a local account to admin
实例初始化三连(创建→确认→提权)与状态核对:
cd /gotosocial
./gotosocial --config-path ./config.yaml admin account create --username admin --email admin@localhost.localdomain --password 'Q1w2E3r4T5!'
./gotosocial --config-path ./config.yaml admin account confirm --username admin
./gotosocial --config-path ./config.yaml admin account promote --username admin
./gotosocial --config-path ./config.yaml admin account list 2>/dev/null
实测回显(list):
user account approved admin moderator suspended confirmed
admin 01GCAFW13JWEEZ9BG56T9B4CQQ yes yes yes no yes
列含义:account 为账号 ULID;approved 注册审核、admin/moderator 角色位、suspended 停用位、confirmed 邮箱确认位。disable 与 suspended 的区别是前者仅禁登录禁发帖、保留全部数据,可随时 enable 恢复。
5.2 admin media:媒体巡检与清理
./gotosocial admin media --help
实测回显:
Available Commands:
list-attachments list local, remote, or all attachments
list-emojis list local, remote, or all emojis
prune admin commands for pruning media from storage
巡检本地附件(prune 下含孤儿文件与过期远端缓存清理任务,配合 config 的 media-cleanup-cron 使用):
./gotosocial --config-path ./config.yaml admin media list-attachments --local-only 2>/dev/null | tail -3
实测回显(实测环境已有 1 个测试附件):
01M64C6RR6PEZSFTTW3ESGYN4V image/png admin 实测上传的红绿渐变 64x64 PNG
5.3 admin export / import:数据搬家
admin export --path <file> 把数据库数据导出为 JSON 文件,admin import --path <file> 反向导入,配合 SQLite 文件拷贝即构成实例迁移的最小方案。export 的参数面(实测 --help):
Flags:
--path string the path of the file to import from/export to
六、REST API 详解
API 全部走 http://localhost:8147。认证链路是 Mastodon 标准 OAuth2:注册应用 → 用户授权 → 换 access_token → Bearer 调用,以下逐步实测。
6.1 注册应用(POST /api/v1/apps)
curl -s -X POST http://localhost:8147/api/v1/apps \
-H 'Content-Type: application/json' \
-d '{"client_name":"quzuo-cli-test","redirect_uris":"urn:ietf:wg:oauth:2.0:oob","scopes":"read write follow push","website":"https://localhost.localdomain"}'
实测回显:
{
"id": "01M64C21WH4GSZF4G04YRSGSVR",
"created_at": "2026-10-29T17:41:54.193Z",
"name": "quzuo-cli-test",
"website": "https://localhost.localdomain",
"redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
"redirect_uris": ["urn:ietf:wg:oauth:2.0:oob"],
"client_id": "01ZCBZDVVHWREYXR50E52WWSDY",
"client_secret": "71a7df30-ccb1-440d-95f5-bee24e4296c0",
"vapid_key": "BADRE6FPArd4KmMrT-0ZN5KbVjqAlthLCQf58VpeS7B8rChvwaROrGUOnTr-871fhVpJ0qAJSSktYD04JgwkJTc",
"scopes": ["read","write","follow","push"]
}
urn:ietf:wg:oauth:2.0:oob 是带外授权回调(授权码直接显示在页面上,便于 CLI 场景);client_id/client_secret 为本测试实例的临时凭据,读者环境以实际返回为准。
6.2 用户授权拿授权码(/oauth/authorize 四步)
授权页依赖会话状态,curl 复现需严格按四步走(实测全通过):
# 第 1 步:带参数访问授权页,拿到 303 跳登录并初始化会话
curl -s -c /tmp/c.txt -o /dev/null -w '%{http_code} -> %{redirect_url}\n' \
'http://localhost:8147/oauth/authorize?client_id=01ZCBZDVVHWREYXR50E52WWSDY&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&scope=read+write+follow+push'
实测回显:
303 -> http://localhost:8147/auth/sign_in
# 第 2 步:提交登录表单,302 回授权页
curl -s -b /tmp/c.txt -c /tmp/c.txt -o /dev/null -w '%{http_code} -> %{redirect_url}\n' \
-d 'username=admin@localhost.localdomain&password=Q1w2E3r4T5!' \
http://localhost:8147/auth/sign_in
实测回显:
302 -> http://localhost:8147/oauth/authorize
# 第 3 步:带会话访问授权页,返回 Allow 确认表单
curl -s -b /tmp/c.txt -c /tmp/c.txt 'http://localhost:8147/oauth/authorize?client_id=01ZCBZDVVHWREYXR50E52WWSDY&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&scope=read+write+follow+push' \
| grep -oE '<form[^>]*>|<button[^>]*>[^<]*'
实测回显:
<form action="/oauth/authorize" method="POST">
<button type="submit" class="btn btn-success">Allow
# 第 4 步:提交 Allow,302 的 Location 里就是带外授权码
curl -s -b /tmp/c.txt -D - -o /dev/null -X POST http://localhost:8147/oauth/authorize | grep -i location
实测回显:
Location: /oauth/oob?code=MWQ3MMVHMWMTMJCWZI0ZNJQ2LTGZNDKTYZVJNJI2N2FJNTI2
⚠️ 注意:跳过第 1 步、拿已登录会话直接访问授权页会得到 500,日志报
key redirect_uri not found in session——授权参数必须先经过第 1 步写入会话。
6.3 换取 access_token(POST /oauth/token)
curl -s -X POST http://localhost:8147/oauth/token \
-H 'Content-Type: application/json' \
-d '{"redirect_uri":"urn:ietf:wg:oauth:2.0:oob","client_id":"01ZCBZDVVHWREYXR50E52WWSDY","client_secret":"71a7df30-ccb1-440d-95f5-bee24e4296c0","grant_type":"authorization_code","code":"MWQ3MMVHMWMTMJCWZI0ZNJQ2LTGZNDKTYZVJNJI2N2FJNTI2"}'
实测回显:
{
"access_token": "NDRLNJRKNJKTZDKYMY0ZODY5LTHKNDQTZDU4MTVIYTZIN2E0",
"created_at": 1793295795,
"scope": "read write follow push",
"token_type": "Bearer"
}
6.4 验证凭据(GET /api/v1/accounts/verify_credentials)
TOKEN=NDRLNJRKNJKTZDKYMY0ZODY5LTHKNDQTZDU4MTVIYTZIN2E0
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:8147/api/v1/accounts/verify_credentials | head -c 400; echo
实测回显(节选):
{
"id": "01GCAFW13JWEEZ9BG56T9B4CQQ",
"username": "admin",
"acct": "admin",
"display_name": "admin",
"locked": true,
"discoverable": false,
"created_at": "2026-10-29T17:41:36.000Z",
"url": "http://localhost/@admin",
"avatar": "http://localhost/assets/default_avatars/GoToSocial_icon1.webp",
"followers_count": 0,
"following_count": 0,
"statuses_count": 0,
不带 token 调用受保护接口得到明确 401:
curl -s -o /dev/null -w '%{http_code} ' http://localhost:8147/api/v1/timelines/home; curl -s http://localhost:8147/api/v1/timelines/home; echo
实测回显:
401 {"error":"Unauthorized: token not supplied"}
6.5 发帖(POST /api/v1/statuses)
curl -s -X POST http://localhost:8147/api/v1/statuses \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"status":"Hello from GoToSocial v0.22.3 on Ubuntu 22.04! 这是一条 API 实测帖。#gotosocial","visibility":"public"}' | head -c 500; echo
实测回显(节选,hashtag 已被解析为可点击话题链接):
{
"id": "01M64C4XWNTGE9ZGZWDDBHJ46E",
"created_at": "2026-10-29T17:43:28.406Z",
"visibility": "public",
"language": "en",
"uri": "http://localhost/users/admin/statuses/01M64C4XWNTGE9ZGZWDDBHJ46E",
"url": "http://localhost/@admin/statuses/01M64C4XWNTGE9ZGZWDDBHJ46E",
"content": "<p>Hello from GoToSocial v0.22.3 on Ubuntu 22.04! 这是一条 API 实测帖。<a href=\"http://localhost/tags/gotosocial\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>gotosocial</span></a></p>",
visibility 支持 public/unlisted/private/direct 四档,与 Mastodon 语义一致。
6.6 时间线(GET /api/v1/timelines/home)
curl -s -H "Authorization: Bearer $TOKEN" 'http://localhost:8147/api/v1/timelines/home?limit=5' \
| python3 -c "import json,sys; d=json.load(sys.stdin); print('count:', len(d)); print('first:', d[0]['content'][:60])"
实测回显:
count: 1
first: <p>Hello from GoToSocial v0.22.3 on Ubuntu 22.04! 这是一条 API 实测帖。<a h
刚发的帖子实时出现在 home 时间线;limit/max_id/since_id 分页参数与 Mastodon 约定一致。公开时间线受 instance-expose-public-timeline 配置控制(默认关闭,未授权访问被拒)。
6.7 媒体上传与带图发帖(POST /api/v1/media)
curl -s -X POST http://localhost:8147/api/v1/media \
-H "Authorization: Bearer $TOKEN" \
-F 'file=@/gotosocial/test.png;type=image/png' \
-F 'description=实测上传的红绿渐变 64x64 PNG' | head -c 430; echo
实测回显(节选,自动生成原图与缩略图两级 URL):
{
"id": "01M64C6RR6PEZSFTTW3ESGYN4V",
"type": "image",
"url": "http://localhost/fileserver/01GCAFW13JWEEZ9BG56T9B4CQQ/attachment/original/01M64C6RR6PEZSFTTW3ESGYN4V.png",
"text_url": "http://localhost/fileserver/01GCAFW13JWEEZ9BG56T9B4CQQ/attachment/original/01M64C6RR6PEZSFTTW3ESGYN4V.png",
"preview_url": "http://localhost/fileserver/01GCAFW13JWEEZ9BG56T9B4CQQ/attachment/small/01M64C6RR6PEZSFTTW3ESGYN4V.jpeg",
"meta": {
"original": {"width": 64, "height": 64, "size": "64x64", "aspect": 1},
"small": {"width": 64, "height": 64, "size": "64x64", "aspect": 1}
上传成功后把 media_ids 带进发帖请求:
curl -s -X POST http://localhost:8147/api/v1/statuses \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"status":"媒体接口实测:配图发帖成功","media_ids":["01M64C6RR6PEZSFTTW3ESGYN4V"],"visibility":"public"}' \
| python3 -c "import json,sys; d=json.load(sys.stdin); print('id:', d['id']); print('media:', [(a['id'], a['type']) for a in d['media_attachments']])"
实测回显:
id: 01M64C73YV42Z4NSFNRQSNADV2
media: [('01M64C6RR6PEZSFTTW3ESGYN4V', 'image')]
⚠️ 注意:损坏的图片文件会得到
422 {"error":"Unprocessable Entity: error processing media"},服务端日志可见具体解码错误(实测传坏 PNG 报png: invalid format: bad filter type);媒体处理由内置 WASM ffmpeg 完成,无需宿主机安装 ffmpeg。
6.8 实例信息与健康检查
curl -s http://localhost:8147/api/v1/instance | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['domain'], '|', d['title'], '|', d['version'])"
curl -s -o /dev/null -w 'livez -> %{http_code}\n' http://localhost:8147/livez
curl -s -o /dev/null -w 'readyz -> %{http_code}\n' http://localhost:8147/readyz
curl -s -o /dev/null -w 'nodeinfo/2.0 -> %{http_code}\n' http://localhost:8147/nodeinfo/2.0
curl -s -o /dev/null -w 'GET /@admin -> %{http_code}\n' http://localhost:8147/@admin
实测回显:
localhost | localhost | 0.22.3+git-5a6c8e2
livez -> 200
readyz -> 200
nodeinfo/2.0 -> 200
GET /@admin -> 200
/livez、/readyz 是给负载均衡与监控探针用的存活/就绪探针;/nodeinfo/2.0 返回实例软件与统计的标准化描述;/@<用户名> 是用户的公开 Web 主页。完整可调用的接口矩阵见官方 Swagger(/api/swagger),接口面与 Mastodon 客户端 API 对齐。
七、注意事项
- token 权限即应用申请的 scope:0.19.0 起 GoToSocial 支持带 scope 的授权令牌,申请
read的 token 无法执行写操作;更早版本令牌是全权限的,给第三方应用授权时先确认版本。 - CLI 与服务并发:SQLite WAL 下 CLI 子命令可在服务运行中执行,但大批量维护(vacuum、大导出)建议低峰执行。
- 限流:默认 300 次/5 分钟(
advanced-rate-limit-requests),批量脚本调 API 时注意节流,被限流会收到带Retry-After的响应。 host即身份:API 返回的 url/uri 全部基于host配置,本地测试用 localhost 的实例对外不可联邦,正式实例务必定型正式域名(原因见《GoToSocial 0.22.3 配置参数详解》 5.2)。- 配置排障:任何「改了没生效」先用
debug config看合并后的最终值(见《GoToSocial 0.22.3 配置参数详解》第三章)。
八、常见问题(FAQ)
Q1:admin account create panic 报 password 强度不足?
A:CLI 与 Web 用同一套密码强度策略,弱口令(实测 q1w2e3r4 报 password is only 68% strength)直接拒绝;换含大小写+数字+符号的口令。
Q2:/oauth/authorize 返回 500,key redirect_uri not found in session?
A:授权流程必须从带 client_id 参数的授权页入口开始(6.2 第 1 步),先初始化会话再登录;直接拿已登录会话访问授权页会因会话缺授权参数而 500。
Q3:media 上传报 422?
A:几乎都是文件本身问题(损坏/伪造扩展名/超过 media-local-max-size),看服务端日志定位;上传成功但 meta 为空时检查 Content-Type 是否与文件一致。
Q4:database ping 失败?
A:确认 --config-path 指向正确配置(连的库与服务的库一致);SQLite 场景确认 db-address 路径存在且 gotosocial 用户可写;PostgreSQL 场景核对 db-address/port/user/password 与网络可达性。
Q5:如何临时停一个用户的登录而不删数据?
A:admin account disable --username <name>;恢复用 admin account enable。彻底停用(suspended)与降权(demote)同族命令见 5.1。
九、参考链接
- 官方 CLI 文档:
https://docs.gotosocial.org/en/latest/admin/cli/ - 官方 API 认证文档:
https://docs.gotosocial.org/en/latest/api/authentication/ - 官方 Swagger:
https://docs.gotosocial.org/en/latest/api/swagger/(实例内亦挂/api/swagger) - 官方用户创建文档:
https://docs.gotosocial.org/en/latest/getting_started/user_creation/ - 本文安装与账号初始化流程:《Ubuntu 22.04 安装 GoToSocial 0.22.3 指南》;配置参数体系:《GoToSocial 0.22.3 配置参数详解》;组件定位与选型:《GoToSocial 0.22.3 介绍与选型指南》;Mastodon CLI 对照可读《Mastodon 4.7.3 常用 CLI 命令详解》。