Skip to content

出差审批

审批定义的表单包含 出差控件组 时,该定义下的审批实例通过时,触发该事件。

前提条件

事件

项目
事件类型approval.instance.trip_group_update_v4
支持的应用类型custom,isv
权限要求 订阅该事件所需的权限,开启其中任意一项权限即可订阅 开启任一权限即可approval:approval:readonly 访问审批应用 approval:approval 查看、创建、更新、删除审批应用相关信息
字段权限要求> Tip: 该接口返回体中存在下列敏感字段,仅当开启对应的权限后才会返回;如果无需获取这些字段,则不建议申请 contact:user.employee_id:readonly 获取用户 user ID
推送方式Webhook

事件体

字段数据类型描述
schemastring事件模式
headerevent_header事件头
  └ event_idstring事件 ID
  └ event_typestring事件类型
  └ create_timestring事件创建时间戳(单位:毫秒)
  └ tokenstring事件 Token
  └ app_idstring应用 ID
  └ tenant_keystring租户 Key
eventobject/-
  └ objectobject事件详细信息。
    └ instance_codestring审批实例 Code。可调用获取单个审批实例详情接口,根据 Code 查询实例详情。
    └ start_timeint审批开始时间,秒级时间戳。
    └ end_timeint审批结束时间,秒级时间戳。
    └ schedulesobject出差详细信息。
      └ departurestring出发地。
      └ departure_idstring出发地 ID。
      └ destinationstring目的地。
      └ destination_idsstring[]目的地 ID。
      └ remarkstring备注信息。
      └ transportationstring交通工具。
      └ trip_start_timestring出差开始时间。示例格式:2022-08-25 12:00:00
      └ trip_end_timestring出差结束时间。示例格式:2022-08-25 12:00:00
      └ trip_intervalstring出差时长。单位:秒
      └ trip_typestring出差类型。可能值:
- 单程 - 往返
    └ start_userobject审批提交人的信息。
      └ idobject审批提交人的 ID。不同类型 ID 介绍参见用户身份概述
        └ open_idstring提交人的 open_id
        └ union_idstring提交人的 union_id
        └ user_idstring提交人的 user_id
为应用开通以下权限才能获取 user_id:
contact:user.employee_id:readonly 获取用户 user ID
    └ trip_intervalstring出差时长。单位:秒
    └ trip_reasonstring出差原因。
    └ typestring固定值 APPROVED
    └ trip_peersobject出差同行人信息。
      └ idobject同行人 ID。不同类型 ID 介绍参见用户身份概述
        └ open_idstring同行人的 open_id
        └ union_idstring同行人的 union_id
        └ user_idstring同行人的 user_id
为应用开通以下权限才能获取 user_id:
contact:user.employee_id:readonly 获取用户 user ID

事件体示例

json
{
  "schema": "2.0",
  "header": {
        "event_id": "b53e80a132ec090ba249a8bb74da0123",
        "token": "ijuh4XAlBSRUIwhBFtLDSfWnIC61234",
        "event_type":"approval.instance.trip_group_update_v4",
        "app_id": "cli_xxx",
        "tenant_key": "d6ae59e175fxxx"
        "event_create_time": "1502199207.7171419"
  },
  "event": {
    "object": {
      "type": "APPROVED",
      "instance_code": "FC2CB9B2-966F-4B65-AC7E-B21E04F497CB",
      "start_user": {
        "id": {
          "user_id": "abc456",
          "open_id": "ou_0e188d8010729123",
          "union_id": "on_445705689d4d112"
        }
      },
      "start_time": "1661333019",
      "end_time": "1661333029",
      "schedules": [
        {
          "trip_start_time": "2022-08-25 12:00:00",
          "trip_end_time": "2022-09-01 00:00:00",
          "trip_interval": "561600",
          "departure": "中国/北京市/北京市/朝阳区",
          "departure_id": "6c758b5dc54930abc7a454c7477d3496cfca0a62fd941e0093b2d819e0e263a6",
          "destination": "美国",
          "destination_ids": [
            "dcb23aebd41ad8a8aabf3f6a72fa8fabed7fae73b662d332a4a7d411d6f2312e"
          ],
          "transportation": "飞机",
          "trip_type": "往返",
          "remark": "text demo"
        }
      ],
      "trip_interval": "561600",
      "trip_reason": "test",
      "trip_peers": [
        {
          "id": {
            "user_id": "abc123",
            "open_id": "ou_0e188d8010729321",
            "union_id": "on_445705689d4d132"
          }
        }
      ]
    }
  }
}

事件订阅示例代码

事件订阅流程可参考:事件订阅概述,新手入门可参考:教程

订阅方式

长连接方式(推荐):无需发布到公网地址,在本地开发环境中即可接收事件回调,且无需处理加解密逻辑。 发送至开发者服务器:需要提供服务器公网地址。

package main

import (
        "context"
        "fmt"

        larkcore "github.com/larksuite/oapi-sdk-go/v3/core"
        larkevent "github.com/larksuite/oapi-sdk-go/v3/event"
        "github.com/larksuite/oapi-sdk-go/v3/event/dispatcher"
        "github.com/larksuite/oapi-sdk-go/v3/service/approval/old"
        larkws "github.com/larksuite/oapi-sdk-go/v3/ws"
)

// SDK 使用说明 SDK user guide:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/golang-sdk-guide/preparations
func main() {
        // 注册事件 Register event
        eventHandler := dispatcher.NewEventDispatcher("", "").
                OnCustomizedEvent("approval.instance.trip_group_update_v4", func(ctx context.Context, event *larkevent.EventReq) error {
                        fmt.Printf("[ OnCustomizedEvent access ], type: message, data: %s\n", string(event.Body))
                        return nil
                })

        // 构建 client Build client
        cli := larkws.NewClient("YOUR_APP_ID", "YOUR_APP_SECRET",
                larkws.WithEventHandler(eventHandler),
                larkws.WithLogLevel(larkcore.LogLevelDebug),
        )

        // 建立长连接 Establish persistent connection
        err := cli.Start(context.Background())

        if err != nil {
                panic(err)
        }
}
# SDK 使用说明 SDK user guide:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/python--sdk/preparations-before-development
import lark_oapi as lark


def do_customized_event(data: lark.CustomizedEvent) -> None:
    print(f'[ do_customized_event access ], type: message, data: {lark.JSON.marshal(data, indent=4)}')

# 注册事件 Register event
event_handler = lark.EventDispatcherHandler.builder("", "") \
    .register_p1_customized_event("approval.instance.trip_group_update_v4", do_customized_event) \
    .build()


def main():
    # 构建 client Build client
    cli = lark.ws.Client("APP_ID", "APP_SECRET",
                        event_handler=event_handler, log_level=lark.LogLevel.DEBUG)
    # 建立长连接 Establish persistent connection
    cli.start()

if __name__ == "__main__":
    main()
package com.example.sample;

import java.nio.charset.StandardCharsets;
import com.lark.oapi.core.request.EventReq;
import com.lark.oapi.event.CustomEventHandler;
import com.lark.oapi.event.EventDispatcher;
import com.lark.oapi.ws.Client;

// SDK 使用说明 SDK user guide:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/java-sdk-guide/preparations
public class Sample {
    // 注册事件 Register event
    private static final EventDispatcher EVENT_HANDLER = EventDispatcher.newBuilder("", "")
            .onCustomizedEvent("approval.instance.trip_group_update_v4", new CustomEventHandler() {
                @Override
                public void handle(EventReq event) throws Exception {
                    System.out.printf("[ onCustomizedEvent access ], type: message, data: %s\n", new String(event.getBody(), StandardCharsets.UTF_8));
                }
            })
            .build();

    public static void main(String[] args) {
        // 构建 client Build client
        Client client = new Client.Builder("APP_ID", "APP_SECRET")
                .eventHandler(EVENT_HANDLER)
                .build();
        // 建立长连接 Establish persistent connection
        client.start();
    }
}
// SDK 使用说明 SDK user guide:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/nodejs-sdk/preparation-before-development
import * as Lark from '@larksuiteoapi/node-sdk';
const baseConfig = {
    appId: 'APP_ID',
    appSecret: 'APP_SECRET'
}
// 构建 client Build client
const wsClient = new Lark.WSClient(baseConfig);
// 建立长连接 Establish persistent connection
wsClient.start({
    // 注册事件 Register event
    eventDispatcher: new Lark.EventDispatcher({}).register({
        'approval.instance.trip_group_update_v4': async (data) => {
            console.log(data);
        }
    })
});
package main

import (
        "context"
        "fmt"
        "net/http"

        larkcore "github.com/larksuite/oapi-sdk-go/v3/core"
        "github.com/larksuite/oapi-sdk-go/v3/core/httpserverext"
        larkevent "github.com/larksuite/oapi-sdk-go/v3/event"
        "github.com/larksuite/oapi-sdk-go/v3/event/dispatcher"
        "github.com/larksuite/oapi-sdk-go/v3/service/approval/old"
)

// SDK 使用说明 SDK user guide:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/golang-sdk-guide/preparations
func main() {
        // 注册事件 Register event
        eventHandler := dispatcher.NewEventDispatcher("", "").
                OnCustomizedEvent("approval.instance.trip_group_update_v4", func(ctx context.Context, event *larkevent.EventReq) error {
                        fmt.Printf("[ OnCustomizedEvent access ], type: message, data: %s\n", string(event.Body))
                        return nil
                })

        // 创建路由处理器 Create route handler
        http.HandleFunc("/webhook/event", httpserverext.NewEventHandlerFunc(handler, larkevent.WithLogLevel(larkcore.LogLevelDebug)))

        err := http.ListenAndServe(":7777", nil)

        if err != nil {
                panic(err)
        }
}
# SDK 使用说明 SDK user guide:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/python--sdk/preparations-before-development
from flask import Flask
from lark_oapi.adapter.flask import *
import lark_oapi as lark

app = Flask(__name__)


def do_customized_event(data: lark.CustomizedEvent) -> None:
    print(f'[ do_customized_event access ], type: message, data: {lark.JSON.marshal(data, indent=4)}')

# 注册事件 Register event
event_handler = lark.EventDispatcherHandler.builder("", "") \
    .register_p1_customized_event("approval.instance.trip_group_update_v4", do_customized_event) \
    .build()


# 创建路由处理器 Create route handler
@app.route("/webhook/event", methods=["POST"])
def event():
    resp = handler.do(parse_req())
    return parse_resp(resp)

if __name__ == "__main__":
    app.run(port=7777)
package com.lark.oapi.sample.event;

import java.nio.charset.StandardCharsets;
import com.lark.oapi.core.request.EventReq;
import com.lark.oapi.event.CustomEventHandler;
import com.lark.oapi.sdk.servlet.ext.ServletAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// SDK 使用说明 SDK user guide:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/java-sdk-guide/preparations
@RestController
public class EventController {

    // 注册事件 Register event
    private static final EventDispatcher EVENT_HANDLER = EventDispatcher.newBuilder("verificationToken", "encryptKey")
            .onCustomizedEvent("approval.instance.trip_group_update_v4", new CustomEventHandler() {
                @Override
                public void handle(EventReq event) throws Exception {
                    System.out.printf("[ onCustomizedEvent access ], type: message, data: %s\n", new String(event.getBody(), StandardCharsets.UTF_8));
                }
            })
            .build();

    // 注入 ServletAdapter 实例 Inject ServletAdapter instance
    @Autowired
    private ServletAdapter servletAdapter;

    // 创建路由处理器 Create route handler
    @RequestMapping("/webhook/event")
    public void event(HttpServletRequest request, HttpServletResponse response)
            throws Throwable {
        // 回调扩展包提供的事件回调处理器 Callback handler provided by the extension package
        servletAdapter.handleEvent(request, response, EVENT_DISPATCHER);
    }
}
// SDK 使用说明 SDK user guide:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/nodejs-sdk/preparation-before-development
import http from 'http';
import * as lark from '@larksuiteoapi/node-sdk';

// 注册事件 Register event
const eventDispatcher = new lark.EventDispatcher({
    encryptKey: '',
    verificationToken: '',
}).register({
    'approval.instance.trip_group_update_v4': async (data) => {
        console.log(data);
        return 'success';
    },
});

const server = http.createServer();
// 创建路由处理器 Create route handler
server.on('request', lark.adaptDefault('/webhook/event', eventDispatcher));
server.listen(3000);

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