1. 概述
Slack 是全球广泛使用的团队协作通信工具,其强大之处在于支持丰富的第三方集成和自定义插件开发。通过调用 Slack 提供的 HTTP API,我们可以轻松构建自动化机器人(bot),实现与频道、用户的交互。
虽然 Slack 官方没有提供 Java SDK,但社区有一个官方推荐的高质量开源 SDK —— HubSpot Slack Client,它封装了绝大多数 Slack API,让我们无需关心底层 HTTP 细节,专注业务逻辑。
本文将基于该 SDK 实现一个系统监控机器人:定时检查服务器磁盘使用率,当空间不足时自动发送告警。
✅ 推荐使用 HubSpot 的 SDK,踩坑少,API 设计清晰,异步非阻塞,适合生产环境。
2. 获取 API 凭据
要接入 Slack,必须先在开发者平台创建应用并获取认证 Token。
步骤概览:
- 访问 Slack API 管理页面 创建新 App
- 配置 Bot 用户(虚拟账号)
- 安装 App 到工作区,获取访问 Token
- 将 Bot 邀请至目标频道
详细操作:
进入 https://api.slack.com/apps,点击 “Create New App”
填写 App 名称(如
System Monitor
)并选择所属 Workspace进入左侧菜单 “Bot” 配置,创建 Bot 用户
设置 Bot 显示名与用户名(如
system_monitoring
)左侧导航选择 “Install App”,点击 “Install App to Workspace” 完成安装
安装成功后,复制 Bot User OAuth Access Token(形如
xoxb-...
),这是后续调用 API 的凭据
⚠️ 注意:Token 需妥善保管,不要提交到代码仓库最后,进入目标 Slack 频道(如
#dev-ops
),@ 你的 Bot(如@system_monitoring
)将其加入频道,否则无法发送消息。
3. 引入 Slack SDK 依赖
使用 Maven,在 pom.xml
中添加 HubSpot Slack Client 依赖:
<properties>
<slack.version>1.8.0</slack.version>
</properties>
<dependencies>
<dependency>
<groupId>com.hubspot.slack</groupId>
<artifactId>slack-base</artifactId>
<version>${slack.version}</version>
</dependency>
<dependency>
<groupId>com.hubspot.slack</groupId>
<artifactId>slack-java-client</artifactId>
<version>${slack.version}</version>
</dependency>
</dependencies>
✅
slack-base
提供核心模型,slack-java-client
是异步客户端实现。
4. 应用架构设计
为实现灵活扩展,采用接口解耦设计:
核心接口定义
ErrorChecker
:错误检测器,负责执行检查逻辑ErrorReporter
:错误上报器,负责通知(可对接不同渠道)
public interface ErrorChecker {
void check();
}
public interface ErrorReporter {
void reportProblem(String problem);
}
设计优势
- 同一个检查器可绑定多个上报器(例如:磁盘 90% 告警发频道,98% 告警发私信)
- 上报器可复用(邮件、短信、Slack 等)
- 易于测试和替换实现
5. 磁盘空间检查实现
使用 Java 7 引入的 NIO.2 FileStore
API 跨平台获取磁盘信息。
public class DiskSpaceErrorChecker implements ErrorChecker {
private static final Logger LOG = LoggerFactory.getLogger(DiskSpaceErrorChecker.class);
private ErrorReporter errorReporter;
private double limit; // 触发告警的可用空间阈值(如 0.1 表示 10%)
public DiskSpaceErrorChecker(ErrorReporter errorReporter, double limit) {
this.errorReporter = errorReporter;
this.limit = limit;
}
@Override
public void check() {
FileSystems.getDefault().getFileStores().forEach(fileStore -> {
try {
long totalSpace = fileStore.getTotalSpace();
long usableSpace = fileStore.getUsableSpace();
double usablePercentage = ((double) usableSpace) / totalSpace;
if (totalSpace > 0 && usablePercentage < limit) {
String error = String.format("File store %s only has %d%% usable disk space",
fileStore.name(), (int)(usablePercentage * 100));
errorReporter.reportProblem(error);
}
} catch (IOException e) {
LOG.error("Error getting disk space for file store {}", fileStore, e);
}
});
}
}
✅
FileStore
能正确识别 Windows 盘符、Linux 挂载点等,比File.getUsableSpace()
更可靠。
6. 实现 Slack 频道消息上报
通过 SlackClient
向指定频道发送消息。
public class SlackChannelErrorReporter implements ErrorReporter {
private SlackClient slackClient;
private String channel; // 频道 ID,如 C012AB3CD
public SlackChannelErrorReporter(SlackClient slackClient, String channel) {
this.slackClient = slackClient;
this.channel = channel;
}
@Override
public void reportProblem(String problem) {
slackClient.postMessage(
ChatPostMessageParams.builder()
.setText(problem)
.setChannelId(channel)
.build()
).join().unwrapOrElseThrow();
}
}
⚠️ 注意:
channel
应使用频道 ID(以 C 开头),而非名称。可在 Slack 网页版右键频道 → “复制链接” 获取。
7. 应用启动与调度
使用 Java 原生 Timer
实现定时任务(生产环境建议用 ScheduledExecutorService
或 Spring Scheduler)。
public class MainClass {
public static final long MINUTES = 1000 * 60;
public static void main(String[] args) throws IOException {
// 初始化 Slack 客户端
SlackClientRuntimeConfig runtimeConfig = SlackClientRuntimeConfig.builder()
.setTokenSupplier(() -> "xoxb-your-bot-token-here") // 替换为真实 Token
.build();
SlackClient slackClient = SlackClientFactory.defaultFactory().build(runtimeConfig);
// 配置频道告警:低于 10% 发 #general 频道
ErrorReporter slackChannelErrorReporter = new SlackChannelErrorReporter(slackClient, "C012AB3CD");
ErrorChecker diskSpaceErrorChecker10pct = new DiskSpaceErrorChecker(slackChannelErrorReporter, 0.1);
// 配置私信告警:低于 2% 直接发给运维负责人
ErrorReporter slackUserErrorReporter = new SlackUserErrorReporter(slackClient, "alice@example.com");
ErrorChecker diskSpaceErrorChecker2pct = new DiskSpaceErrorChecker(slackUserErrorReporter, 0.02);
// 启动定时任务,每 5 分钟执行一次
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
diskSpaceErrorChecker10pct.check();
diskSpaceErrorChecker2pct.check();
}
}, 0, 5 * MINUTES);
}
}
运行后效果:
8. 实现 Slack 私信(IM)上报
对于紧急告警,直接发送私信更有效,避免被频道消息淹没。
public class SlackUserErrorReporter implements ErrorReporter {
private SlackClient slackClient;
private String user; // 用户邮箱
public SlackUserErrorReporter(SlackClient slackClient, String user) {
this.slackClient = slackClient;
this.user = user;
}
@Override
public void reportProblem(String problem) {
// 1. 根据邮箱查找用户 ID
UsersInfoResponse usersInfoResponse = slackClient
.lookupUserByEmail(UserEmailParams.builder()
.setEmail(user)
.build()
).join().unwrapOrElseThrow();
// 2. 打开与该用户的 IM(私聊)通道
ImOpenResponse imOpenResponse = slackClient.openIm(ImOpenParams.builder()
.setUserId(usersInfoResponse.getUser().getId())
.build()
).join().unwrapOrElseThrow();
// 3. 向该 IM 通道发送消息
imOpenResponse.getChannel().ifPresent(channel -> {
slackClient.postMessage(
ChatPostMessageParams.builder()
.setText(problem)
.setChannelId(channel.getId())
.build()
).join().unwrapOrElseThrow();
});
}
}
✅ 使用邮箱查找用户最稳定,因为用户名可更改,邮箱不可变。
私信效果:
9. 总结
本文通过一个系统监控机器人示例,演示了:
- 如何使用 HubSpot Slack SDK 快速接入 Slack
- 解耦设计:检查器与上报器分离,便于扩展
- 频道消息与私信两种通知方式的实现
- 定时任务集成
该模式可轻松扩展至 CPU、内存、服务健康检查等场景。Slack API 功能丰富,如需更复杂交互(如交互式按钮、模态框),可进一步探索其 Block Kit。
源码已托管至 GitHub:https://github.com/eugenp/tutorials/tree/master/saas-modules/slack