Skip to content

使用长连接接收回调

长连接是飞书 SDK 内提供的能力,你可以在本地服务器集成飞书 SDK, 与开放平台建立一条 WebSocket 全双工通道(你的服务器需要能够访问公网)。后续当应用订阅的回调发生时,开放平台会通过该通道向你的服务器发送回调消息。

功能优势

相较于传统的 Webhook 模式,长连接模式大大降低了接入成本,将原先 1 周左右的开发周期降低到 5 分钟。具体优势如下:

  • 开发调用方便快捷

    只需保证运行环境具备访问公网的能力即可,无需提供公网 IP 或域名、无需使用内网穿透工具,通过长连接模式在本地开发环境中即可接收回调消息,后续在线上部署本地服务后也可以直接生效。

  • 加密传输,无需额外处理加密解密逻辑

    长连接方式内置了通信通信加密和鉴权的逻辑,回调数据网络上传输时为加密传输,对于开发者而言无需额外解密、验签逻辑,也无需部署防火墙和配置白名单。

配置回调订阅方式用于接收开放平台向应用推送的回调消息。当应用订阅的回调(例如,飞书卡片交互、链接预览)发生时,开放平台会按照指定方式进行回调。

使用限制

注意事项

  • 长连接模式下接收到消息后,需要在 3 秒内处理完成。

  • 长连接模式的消息推送为 集群模式,不支持广播,即如果同一应用部署了多个客户端(client),那么只有其中随机一个客户端会收到消息。

上手体验

开放平台提供了一键开发卡片交互机器人的场景体验教程,你可以前往体验基于卡片回传交互回调所搭建的机器人应用,详情参见:

步骤一:集成 SDK

以下示例代码中以 卡片回传交互拉取链接预览数据 回调为例。

Go SDK

安装

bash
go get -u github.com/larksuite/oapi-sdk-go/v3@latest

示例代码

go
package main

import (
    "context"
    "fmt"
    larkcore "github.com/larksuite/oapi-sdk-go/v3/core"
    "github.com/larksuite/oapi-sdk-go/v3/event/dispatcher"
    "github.com/larksuite/oapi-sdk-go/v3/event/dispatcher/callback"
    larkws "github.com/larksuite/oapi-sdk-go/v3/ws"
)
func main() {
    // 注册回调
    eventHandler := dispatcher.NewEventDispatcher("", "").
       // 监听「卡片回传交互 card.action.trigger」
       OnP2CardActionTrigger(func(ctx context.Context, event *callback.CardActionTriggerEvent) (*callback.CardActionTriggerResponse, error) {
          fmt.Printf("[ OnP2CardActionTrigger access ], data: %s\n", larkcore.Prettify(event))
          return nil, nil
       }).
       // 监听「拉取链接预览数据 url.preview.get」
       OnP2CardURLPreviewGet(func(ctx context.Context, event *callback.URLPreviewGetEvent) (*callback.URLPreviewGetResponse, error) {
          fmt.Printf("[ OnP2URLPreviewAction access ], data: %s\n", larkcore.Prettify(event))
          return nil, nil
       })
    // 创建Client
    cli := larkws.NewClient("YOUR_APP_ID", "YOUR_APP_SECRET",
       larkws.WithEventHandler(eventHandler),
       larkws.WithLogLevel(larkcore.LogLevelDebug),
    )
    // 建立长连接
    err := cli.Start(context.Background())
    if err != nil {
       panic(err)
    }
}

步骤说明:

  1. 通过 dispatcher.NewEventDispatcher() 初始化回调处理器(eventHandler),注意两个参数必须填空字符串

  2. 通过 eventHandler 的 OnXXXX() 方法监听不同的回调类型,上述示例中分别监听了 卡片回传交互 card.action.trigger拉取链接预览数据 url.preview.get 两个回调。

  3. 通过 larkws.NewClient() 初始化长连接客户端,必填参数为应用的 APP_ID 和 APP_SECRET,可在开发者后台的应用详情页内,进入 基础信息 > 凭证与基础信息 页面,获取应用的 APP_ID 和 APP_SECRET。

  4. 可选参数传入 eventHandler,同时可设置日志级别。

  5. 通过 cli.Start() 启动客户端,如连接成功,控制台会打印 connected to wss://xxxxx,主线程将阻塞,直到进程结束。

Python SDK

安装

pip install lark-oapi==1.4.0

示例代码

python
import lark_oapi as lark
from lark_oapi.event.callback.model.p2_card_action_trigger import P2CardActionTrigger, P2CardActionTriggerResponse
from lark_oapi.event.callback.model.p2_url_preview_get import P2URLPreviewGet, P2URLPreviewGetResponse

# 监听「卡片回传交互 card.action.trigger」
def do_card_action_trigger(data: P2CardActionTrigger) -> P2CardActionTriggerResponse:
    print(lark.JSON.marshal(data))
    resp = {
        "toast": {
            "type": "info",
            "content": "卡片回传成功 from python sdk"
        }
    }
    return P2CardActionTriggerResponse(resp)

# 监听「拉取链接预览数据 url.preview.get」
def do_url_preview_get(data: P2URLPreviewGet) -> P2URLPreviewGetResponse:
    print(lark.JSON.marshal(data))
    resp = {
        "inline": {
            "title": "链接预览测试",
        }
    }
    return P2URLPreviewGetResponse(resp)
event_handler = lark.EventDispatcherHandler.builder("", "") \
    .register_p2_card_action_trigger(do_card_action_trigger) \
    .register_p2_url_preview_get(do_url_preview_get) \
    .build()
def main():
    cli = lark.ws.Client(lark.APP_ID, lark.APP_SECRET,
                         event_handler=event_handler, log_level=lark.LogLevel.DEBUG)
    cli.start()
if __name__ == "__main__":
    main()

步骤说明:

  1. 通过 lark.EventDispatcherHandler.builder() 初始化回调处理器(event_handler),两个参数必须填空字符串

  2. 通过 event_handler 的 register_xxxx() 方法监听不同的回调类型,上述示例中监听了 卡片回传交互 card.action.trigger拉取链接预览数据 url.preview.get 两个回调。

  3. 通过 register_p2_card_action_trigger 注册卡片回调的处理函数。

  4. 通过 register_p2_url_preview_get 注册链接预览的回调的处理函数。

  5. 通过 lark.ws.Client() 初始化长连接客户端,必填参数为应用的 APP_ID 和 APP_SECRET,可在开发者后台获取应用的 APP_ID 和 APP_SECRET。

  6. 可选参数传入 event_handler,同时可设置日志级别。

  7. 通过 cli.start() 启动客户端,如连接成功,控制台会打印 connected to wss://xxxxx,主线程将阻塞,直到进程结束。

     ![](https://sf3-cn.feishucdn.com/obj/open-platform-opendoc/ac590caeb5cc3fe42ca3855696f42c6e_4ZrUub9NAL.png?height=264&lazyload=true&maxWidth=600&width=2488)
    

Java SDK

安装 SDK

xml
<dependencies>
  ...
  <dependency>
    <groupId>com.larksuite.oapi</groupId>
    <artifactId>oapi-sdk</artifactId>
    <version>2.4.0</version>
  </dependency>
  ...
</dependencies>

示例代码

java
package com.lark.oapi.sample.ws;

import com.lark.oapi.core.request.EventReq;
import com.lark.oapi.core.utils.Jsons;
import com.lark.oapi.event.CustomEventHandler;
import com.lark.oapi.event.EventDispatcher;
import com.lark.oapi.event.cardcallback.P2CardActionTriggerHandler;
import com.lark.oapi.event.cardcallback.P2URLPreviewGetHandler;
import com.lark.oapi.event.cardcallback.model.*;
import com.lark.oapi.service.im.ImService;
import com.lark.oapi.service.im.v1.model.P2MessageReceiveV1;
import com.lark.oapi.ws.Client;
import java.nio.charset.StandardCharsets;

public class Sample {
    private static final EventDispatcher EVENT_HANDLER = EventDispatcher.newBuilder("", "")  // 长连接不需要这两个参数,请保持空字符串
            // 监听「卡片回传交互 card.action.trigger」
            .onP2CardActionTrigger(new P2CardActionTriggerHandler() {
                @Override
                public P2CardActionTriggerResponse handle(P2CardActionTrigger event) throws Exception {
                    System.out.printf("[ P2CardActionTrigger access ], data: %s\n", Jsons.DEFAULT.toJson(event.getEvent()));
                    P2CardActionTriggerResponse resp = new P2CardActionTriggerResponse();
                    CallBackToast toast = new CallBackToast();
                    toast.setType("info");
                    toast.setContent("卡片交互成功 from Java SDk");
                    resp.setToast(toast);
                    return resp;
                }
            })
            // 监听「拉取链接预览数据 url.preview.get」
            .onP2URLPreviewGet(new P2URLPreviewGetHandler() {
                @Override
                public P2URLPreviewGetResponse handle(P2URLPreviewGet event) throws Exception {
                    System.out.printf("[ P2URLPreviewGet access ], data: %s\n", Jsons.DEFAULT.toJson(event.getEvent()));
                    P2URLPreviewGetResponse resp = new P2URLPreviewGetResponse();
                    URLPreviewGetInline inline = new URLPreviewGetInline();
                    inline.setTitle("链接预览测试fromJavaSDK");
                    resp.setInline(inline);
                    return resp;
                }
            })
            .build();
    public static void main(String[] args) {
        Client client = new Client.Builder("", "")
                .eventHandler(EVENT_HANDLER)
                .build();
        client.start();
    }
}

步骤说明:

  1. 通过 EventDispatcher.newBuilder() 初始化回调处理器(EVENT_HANDLER),注意两个参数必须填空字符串

  2. 通过 EVENT_HANDLER 的 onXXXX() 方法监听不同的回调类型,上述示例中分别监听了 卡片回传交互 card.action.trigger拉取链接预览数据 url.preview.get 两个回调。

  3. 通过 new Client.Builder() 初始化长连接客户端,必填参数为应用的 APP_ID 和 APP_SECRET,可在开发者后台获取。

  4. 可选参数传入 EVENT_HANDLER

  5. 日志级别在自己项目的日志框架(log4j2、logback等)配置中修改。

  6. 通过 cli.start() 启动客户端,如连接成功,控制台会打印 "connected to wss://xxxxx",主线程将阻塞,直到进程结束。

Node SDK

安装

npm install @larksuiteoapi/node-sdk@1.36.0

示例代码

Javascript
import * as Lark from "@larksuiteoapi/node-sdk";
const wsClient = new Lark.WSClient({
  appId: "YOUR_APP_ID",
  appSecret: "YOUR_APP_SECRET",
});
const eventDispatcher = new Lark.EventDispatcher({}).register({
  "card.action.trigger": async (data) => {
    console.log(data);
    return {
      toast: {
        type: "success",
        content: "卡片交互成功",
        i18n: {
          zh_cn: "卡片交互成功",
          en_us: "card action success",
        },
      },
    };
  },
});
wsClient.start({ eventDispatcher });

步骤说明:

  1. 通过 new Lark.WSClient() 初始化长连接客户端,必填参数为应用的 APP_ID 和 APP_SECRET,可在开发者后台的应用详情页内,进入 基础信息 > 凭证与基础信息 页面,获取应用的 APP_ID 和 APP_SECRET。

  2. 通过 new Lark.EventDispatcher 初始化回调处理器(eventDispatcher)。

  3. 通过 eventDispatcher 的 register 方法监听不同的回调类型,上述示例中监听了 卡片回传交互 card.action.trigger 回调。

  4. 通过 wsClient.start 启动客户端,如连接成功,控制台会打印 [info]: [ "[ws]", "ws client ready" ],主线程将阻塞,直到进程结束。

步骤二:设置订阅方式

  1. 登录 开发者后台,进入指定的企业自建应用详情页。

    目前长连接模式不支持商店应用。

  2. 进入 事件与回调 > 回调配置 页面。

  3. 编辑订阅方式,选择 使用长连接接收事件,并点击 保存

     :::warning
     此时本地基于 SDK 建立的长连接程序必须处于已连接并运行中状态,才能成功保存。
    

    :::

内容来源:飞书开放平台 · 自动爬取整理