| 订阅方式 | 介绍 |
|---|---|
| 使用长连接接收回调 | 该方式是飞书 SDK 内提供的能力,你可以通过集成飞书 SDK 与开放平台建立一条 WebSocket 全双工通道(你的服务器需要能够访问公网)。后续当应用订阅的回调发生时,开放平台会通过该通道向你的服务器发送消息。相较于传统的 Webhook 模式,长连接模式大大降低了接入成本,将原先 1 周左右的开发周期降低到 5 分钟。具体优势如下:测试阶段无需使用内网穿透工具,通过长连接模式在本地开发环境中即可接收回调。SDK 内封装了鉴权逻辑,只在建连时进行鉴权,后续回调推送均为明文数据,无需再处理解密和验签逻辑。只需保证运行环境具备访问公网能力即可,无需提供公网 IP 或域名。无需部署防火墙和配置白名单。 |
| 将回调发送至开发者服务器 | 传统的 Webhook 模式,该方式需要你提供用于接收回调消息的服务器公网地址。后续当应用订阅的回调发生时,开放平台会向服务器的公网地址发送 HTTP POST 请求,请求内包含回调数据。 |

{
"behaviors": [
{ // 声明交互类型是卡片回传交互。
"type": "callback",
"value": {
// 回传交互数据。开放平台 SDK 仅支持对象类型的卡片回传参数。
"key": "value"
}
}
]
}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」事件 P2CardActionTrigger。
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」事件 P2URLPreviewGet。
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 为前缀。
.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()
connected to wss://xxxxx,主线程将阻塞,直到进程结束。
from flask import Flask
import lark_oapi as lark
from event.callback.model.p2_card_action_trigger import P2CardActionTrigger, P2CardActionTriggerResponse
from event.callback.model.p2_url_preview_get import P2URLPreviewGet, P2URLPreviewGetResponse
from lark_oapi.adapter.flask import *
from lark_oapi.api.im.v1 import *
app = Flask(__name__)
# 自定义订阅的事件或者回调
def do_customized_event(data: lark.CustomizedEvent) -> None:
print(lark.JSON.marshal(data))
# 新版卡片回调,卡片回传交互 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)
handler = lark.EventDispatcherHandler.builder(lark.ENCRYPT_KEY, lark.VERIFICATION_TOKEN, lark.LogLevel.DEBUG) \
.register_p2_card_action_trigger(do_card_action_trigger) \
.register_p2_url_preview_get(do_url_preview_get) \
.register_p1_customized_event("这里填入你要自定义订阅的 event 的 key,例如 out_approval", do_customized_event) \
.build()
@app.route("/event", methods=["POST"])
def event():
resp = handler.do(parse_req())
return parse_resp(resp)
if __name__ == "__main__":
app.run(port=7777)from typing import Any
from flask import Flask
import lark_oapi as lark
from lark_oapi.adapter.flask import *
app = Flask(__name__)
def do_interactive_card(data: lark.Card) -> Any:
print(lark.JSON.marshal(data))
content = {
"header": {
"title": {
"tag": "plain_text",
"content": "更新卡片成功"
},
"template": "green"
},
"elements": [
{
"tag": "div",
"text": {
"tag": "lark_md",
"content": "**Success!\n成功啦😄**"
}
},
]
}
return content
handler = lark.CardActionHandler.builder(lark.ENCRYPT_KEY, lark.VERIFICATION_TOKEN, lark.LogLevel.DEBUG) \
.register(do_interactive_card) \
.build()
@app.route("/card", methods=["POST"])
def card():
resp = handler.do(parse_req())
return parse_resp(resp)
if __name__ == "__main__":
app.run(port=7777)