You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用事件API的PHP版Slack应用迁移至Socket Mode实现咨询

PHP版Slack应用Socket Mode迁移本地开发指南

前置准备

  • 先到Slack应用管理后台开启Socket Mode,生成App Level Token(必须添加connections:write权限),这个令牌和你原有xoxb开头的Bot Token是两个独立凭证,不要混淆
  • 本地VM环境提前安装php-cli、php-curl扩展,推荐通过composer安装jolicode/slack-php-api和php-websocket/websocket依赖,无需自行封装WebSocket底层握手、心跳逻辑
  • 清空原有Slack后台配置的slash command、interactivity模块的HTTP请求URL,Socket Mode下无需暴露公网端点,Slack会主动通过WebSocket连接推送事件

核心适配逻辑

原有HTTP模式是被动接收Slack请求、返回响应,Socket Mode改为主动维持长连接,接收Slack推送的事件包处理后返回ACK回执即可,原有业务逻辑几乎可以完全复用:

<?php
require __DIR__ . '/vendor/autoload.php';

// 两个凭证区分清楚
$appToken = 'xapp-******************'; // 刚生成的App Level Token
$botToken = 'xoxb-******************'; // 你原有Bot Token

// 第一步:调用接口获取WebSocket连接地址
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://slack.com/api/apps.connections.open');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $appToken,
    'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
$res = curl_exec($ch);
$connData = json_decode($res, true);
if (!$connData['ok']) {
    die('获取连接地址失败: ' . $connData['error']);
}
$wsUrl = $connData['url'];

// 第二步:建立WebSocket长连接监听事件
$client = new WebSocket\Client($wsUrl);
while (true) {
    try {
        $message = $client->receive();
        $event = json_decode($message, true);

        // 处理Slack心跳、握手事件无需额外逻辑
        if ($event['type'] === 'hello') {
            continue;
        }

        // 所有事件必须先返回ACK回执,否则Slack会重复推送
        if (isset($event['envelope_id'])) {
            $client->send(json_encode([
                'envelope_id' => $event['envelope_id']
            ]));
        }

        // 原有业务逻辑直接复用
        $payload = $event['payload'];
        switch ($event['type']) {
            // slash command触发场景,对应你原来打开弹窗的逻辑
            case 'slash_commands':
                if ($payload['command'] === '/你配置的触发命令') {
                    // 直接复用你原有打开对话框的代码
                    $dialog = [
                        'callback_id' => 'git_issue',
                        'title' => 'Add issue',
                        'submit_label' => 'Create',
                        'elements' => [
                            [
                                'type' => 'text',
                                'label' => 'Name',
                                'name' => 'name'
                            ],
                            [
                                'type' => 'text',
                                'label' => 'E-mail',
                                'name' => 'email'
                            ]
                        ],
                        'trigger_id' => $payload['trigger_id']
                    ];
                    $query = [
                        'token' => $botToken,
                        'dialog' => json_encode($dialog)
                    ];
                    // 你原有调用dialog.open接口的代码完全不变
                    $ch = curl_init();
                    curl_setopt($ch, CURLOPT_URL, 'https://slack.com/api/dialog.open');
                    curl_setopt($ch, CURLOPT_HTTPHEADER, [
                        'Content-Type: application/x-www-form-urlencoded'
                    ]);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
                    curl_setopt($ch, CURLOPT_POST, true);
                    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($query));
                    $response = curl_exec($ch);
                }
                break;
            // 表单提交交互场景,对应你原有同步GitHub的逻辑
            case 'interactive':
                if ($payload['callback_id'] === 'git_issue') {
                    $submission = $payload['submission'];
                    // 这里直接放你原有同步数据到GitHub的代码即可
                }
                break;
        }
    } catch (Exception $e) {
        // 连接断开自动重连
        $client->close();
        $client = new WebSocket\Client($wsUrl);
    }
}

本地运行注意事项

  • 脚本需要在cli模式下运行,不要放到fpm容器中,直接在VM终端执行php 你的脚本文件名.php即可,需要常驻后台可以用nohup或者systemd管理进程
  • 本地VM只要能连通外网即可测试,不需要公网IP、端口映射
  • 原有HTTP请求签名校验逻辑可以移除,Socket Mode的事件通过加密长连接推送,无需额外做签名校验

内容的提问来源于stack exchange,提问作者bhavan k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 22:36:03