View on GitHub

WePush

专注批量推送的小而美的工具,目前支持:模板消息-公众号、模板消息-小程序、微信客服消息、微信企业号/企业微信消息、阿里云短信、阿里大于模板短信 、腾讯云短信、云片网短信、E-Mail、HTTP请求、钉钉、华为云短信、百度云短信、又拍云短信、七牛云短信

WePush Next

WePush Next 是与 Classic 完全独立的新产品线。Classic 与 Next 可以按需拥有重复代码,彼此不建立共享源码依赖。

产品定位:WePush Next 是开源、可下载、可安装、由用户自行部署和运维的消息推送产品。项目不建设官方公共 SaaS、注册计费订阅、公共租户平台或云 KMS/Secret Manager 集成。正式范围和分版本计划见《产品目标、边界与路线图》

当前版本:1.1.0 Stable。Desktop 与安装包按项目约定不使用商业代码签名;下载后必须验证同一 Release 中的 SHA256SUMS。发行边界和升级承诺见 UNSIGNED-NOTICE.md《兼容性策略》《升级与回滚指南》docs/releases/1.1.0.md

第一次下载和使用请从《WePush Next 对外使用指南》开始。渠道账号、模板、Recipient、SecretRef、限流和错误语义见《内置 Provider 指南》

下载与安装

正式发行物统一位于 next-v1.1.0 GitHub Release

使用方式 选择的发行物
推荐的 Standalone 安装 与操作系统、架构匹配的 wepush-next-1.1.0-<os>-<arch> 完整包,已包含 Java Runtime
已有 Java 21+ 或分组件部署 wepush-next-1.1.0.tar.gzwepush-next-1.1.0.zip 精简包
只使用管理界面 与操作系统、架构匹配的 wepush-next-desktop-1.1.0-<os>-<arch>
Java 集成 wepush-next-java-sdk-1.1.0.zip
运营商短信 Agent 插件 wepush-provider-{cmpp,smgp,sgip,smpp}-1.1.0.zipwepush-provider-trusted-key-1.1.0.env

下载后先验证 SHA256SUMS。安装运营商插件时,还必须校验信任公钥文件及各插件的旁路 .sha256;不要从插件 ZIP 或第三方页面获取替代公钥。完整资产说明和升级步骤见 1.1.0 Release Notes

完整包解压后执行统一 Standalone 安装入口:

# Linux / macOS
sudo ./install/install.sh
# Windows 管理员 PowerShell
Set-ExecutionPolicy -Scope Process Bypass
& .\install\install.ps1

安装完成前会检查 Service Readiness、Flyway 数据库版本和本地 Provider Dry Run。需要便携运行或已有 Java 21+ 时,可选择精简包;分组件部署仍可直接使用 install/<os>/install.* service|agent|all

验证 Java 工程

cd next
./mvnw verify

完整构建、三平台安装、Server/HA、Agent Enrollment、插件升级和恢复步骤见 docs/deployment-and-operations.md。安全问题请按 SECURITY.md 私下报告。

启动 Service

cd next
./mvnw -pl service/service-app -am package -DskipTests
java -jar service/service-app/target/wepush-next-service.jar

Service 默认只监听 127.0.0.1:18990。启动后可访问:

本地无认证模式只允许监听回环地址;将 WEPUSH_BIND_ADDRESS 改为非回环地址时必须同时开启 WEPUSH_SECURITY_ENABLED=true 并配置足够强度的 WEPUSH_BOOTSTRAP_TOKEN,否则 Service 拒绝启动。

Standalone 数据默认保存到 .local/data/wepush-next.db,可通过 WEPUSH_DATABASE_PATH 指定其他位置。Service 首次启动会运行 Flyway 迁移并创建 ws_default 工作区。

Secret 默认使用本地信封加密:密文进入 SQLite,主密钥单独保存到 .local/secrets/master-key.json。可通过 WEPUSH_MASTER_KEY_PATH 修改路径,或使用 WEPUSH_MASTER_KEY_BASE64 注入 32-byte Base64 主密钥。已有密文但主密钥缺失、权限不安全或认证失败时,Service 会失败关闭,不会生成新密钥覆盖。

Artifact 默认保存到 .local/artifacts,SQLite 只保存元数据、SHA-256、大小和生命周期状态。可通过 WEPUSH_ARTIFACT_ROOT 修改根目录;临时结果导出默认保留 24 小时,可通过 WEPUSH_EXPORT_RETENTION 使用 ISO-8601 Duration 调整。Service 会按 WEPUSH_RETENTION_INTERVAL 周期回收过期且未 Pin/Legal Hold 的文件。

启动 WebUI 开发环境

cd next/ui
pnpm install
pnpm check
pnpm dev

WebUI 默认运行在 http://127.0.0.1:5173,开发代理连接本地 Service。界面、API Client、Schema Renderer、设计 Token 与 Electron Desktop 外壳均在同一个 pnpm Workspace 内。

启动 Agent

cd next
./mvnw -pl agent/agent-app -am package -DskipTests
java -jar agent/agent-app/target/wepush-next-agent.jar

Agent 默认主动连接 127.0.0.1:19090 的 gRPC 双向控制流,发送 Hello 和周期心跳,断线后使用带抖动的指数退避重连;Sequence 与 Lease Fence Journal 默认保存在 .local/agent/agent-state.properties

常用环境变量:

Service 的 gRPC 端口默认只绑定回环地址。暴露到非回环地址时强制 TLS,HTTP Lease/Artifact 与 gRPC 都拒绝匿名 Agent;正式生产通过一次性 Enrollment 获取长期 Credential 和客户端证书,并使用 mTLS。共享 Token 只保留为回环开发兼容入口。

要把 Run 交给独立 Agent 执行,Service 使用以下配置启动:

WEPUSH_EXECUTION_MODE=remote \
WEPUSH_AGENT_PUBLIC_BASE_URL=http://127.0.0.1:18990 \
java -jar service/service-app/target/wepush-next-service.jar

远端模式会按 Provider ID/版本和可用容量选择在线 Agent,持久化带 Epoch/Fencing Token 的 Lease。Agent 校验冻结 Execution Spec 与 Audience 的 SHA-256 后 ACK,随后使用同一 Core Engine 执行,并经 gRPC 回传事件、Item Result、命令确认和 Run Summary。

需要 Secret 的远端 Run 会使用 Agent 在 Hello 中发布的会话级 X25519 公钥。Service 只解析冻结配置中实际引用的最小 Secret 集,使用一次性 X25519、HKDF-SHA-256 和 AES-256-GCM 加密,并绑定 Agent、Run、Lease、Epoch、Fencing Token 与过期时间。Agent 仅在内存中解密,运行结束立即清零,不写入 Journal。正式跨主机部署仍应关闭明文 gRPC 并配置 TLS;Secret Envelope 不替代 Agent 身份认证和传输层安全。

Java SDKs

Next 提供两种独立 SDK。Remote SDK 通过 HTTP 调用 Service,只依赖公开 service-api,不依赖 Core、Engine 或具体 Provider:

稳定发行包在 sdk/ 中附带可安装到本地 Maven Repository 的 POM/JAR,步骤见 sdk/README.md

try (var client = WePushClient.builder()
        .endpoint(URI.create("http://127.0.0.1:18990"))
        .build()) {
    var system = client.system().info();
    var providers = client.providers().list();
    var agents = client.agents().list();
    var workspace = client.workspace("ws_default");
    var runs = workspace.runs();
    var artifacts = workspace.runArtifacts(runs.getFirst().id());
}

Embedded SDK 则在调用方 JVM 内直接运行 Engine,显式装配所需 Provider,不启动 Service、Agent 或数据库:

var store = new InMemoryExecutionStore();
try (var engine = WePushEngine.builder()
        .provider(new HttpProviderFactory())
        .resultSink(store)
        .eventSink(store)
        .build()) {
    var summary = engine.start(spec, recipients)
            .completion().toCompletableFuture().join();
}

从源码安装、依赖声明和完整示例见 sdk/README.mdsdk/embedded-java/README.md1.1.0 发行包和独立 Java SDK 附件同时提供 Remote SDK、Embedded SDK、HTTP Provider 与标准渠道 Provider;CMPP、SMGP、SGIP、SMPP 则作为独立签名 Agent 插件发布,不进入 Embedded SDK 的默认依赖。

1.1.0 已交付基线

产品范围和迭代优先级以 docs/product-scope-and-roadmap.md 为准;模块边界和实现细节以 docs/architecture-and-high-level-design.mddocs/detailed-design.mddocs/implementation-status.mddocs/deployment-and-operations.mddocs/adr/ 为准。