# 接入指南

## 接口能力

流程的开放接口提供了一系列安全、可靠的 API 接口和事件，来方便企业对流程信息进行查询和操作，通过 API 你可以实现以下功能：
- 流程相关信息查询：包括流程实例信息、审批任务信息、流程中的单据数据等信息查询
- 流程动态监控：可通过事件监听流程实例、流程节点、审批任务等状态变更动态
- 对流程进行操作：包括通过/拒绝审批任务等

## 接口分组
-  流程操作

代发起人进行流程相关操作

方法 (API) | 权限要求 | 访问凭证
---|---|---
[撤回流程](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process_withdraw/update)<br>`PUT`/open-apis/corehr/v2/process_withdraw/:process_id | </md-perm> | `tenant_access_token`
[撤销流程](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process_revoke/update)<br>`PUT`/open-apis/corehr/v2/process_revoke/:process_id | <md-perm name="corehr:process.instance:write" desc="通过/拒绝审批任务" support_app_types="custom,isv">(corehr:process.instance:write) | `tenant_access_token`

代审批人进行相关操作

方法 (API) | 权限要求 | 访问凭证
---|---|---
[通过/拒绝审批任务](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process-approver/update)<br>`PUT`/open-apis/corehr/v2/processes/:process_id/approvers/:approver_id | </md-perm> | `tenant_access_token`
[加签审批任务](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process-extra/update)<br>`PUT`/open-apis/corehr/v2/processes/:process_id/extra | <md-perm name="corehr:process.instance:write" desc="通过/拒绝审批任务" support_app_types="custom,isv">(corehr:process.instance:write) | `tenant_access_token`
[转交审批任务](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process-transfer/update)<br>`PUT`/open-apis/corehr/v2/processes/:process_id/transfer | </md-perm> | `tenant_access_token`

-  流程信息查询

方法 (API) | 权限要求 | 访问凭证
---|---|---
[查询流程实例列表](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process/list)<br>`GET`/open-apis/corehr/v2/processes | <md-perm name="corehr:process:read" desc="获取流程数据" support_app_types="custom,isv">(corehr:process.instance:write) | `tenant_access_token`
[获取单个流程详情](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process/get)<br>`GET`/open-apis/corehr/v2/processes/:process_id | (corehr:process:read) | `tenant_access_token`
[获取流程表单数据](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process-form_variable_data/get)<br>`GET`/open-apis/corehr/v2/processes/:process_id/form_variable_data | (corehr:process:read) | `tenant_access_token`
[获取指定人员审批任务列表](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/approver/list)<br>`GET`/open-apis/corehr/v2/approvers | </md-perm> | `tenant_access_token`

-  流程动态监控

事件（event） | 权限要求 | 触发时机
---|---|---
[流程实例状态变化](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process-status/events/update) | <md-perm name="corehr:process:read" desc="获取流程数据" support_app_types="custom,isv">(corehr:process:read) | 流程实例状态变化时会触发该事件
[流程实例信息变更](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process/events/updated) | </md-perm> | 流程中有审批人操作、流程数据更新、流程状态变化时会触发该事件
[流程节点状态变更](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process-node/events/updated) | <md-perm name="corehr:process:read" desc="获取流程数据" support_app_types="custom,isv">(corehr:process:read) | 流程中节点状态变化时会触发该事件
[审批任务状态变更](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process-approver/events/updated) | </md-perm> | 单个审批任务状态变化时会触发该事件
[抄送单据状态变更](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process-cc/events/updated) | <md-perm name="corehr:process:read" desc="获取流程数据" support_app_types="custom,isv">(corehr:process:read) | 生成抄送单据后会触发该事件

## 名词解释

名词 | 描述
---|---
流程定义 | 指管理员在设置侧配置的流程，类似流程模板，flow_definition_id 是其唯一标识。用户发起的流程是按照对应的流程定义的配置生成
流程实例 | 指用户在业务功能或者飞书人事的审批中心发起的具体流程，process_id 是其唯一标识
流程状态 | 流程状态是指整个流程实例的运行状态，随着审批人执行通过、拒绝等操作，流程状态会随之发生变化。流程状态包含以下几种状态：<br>1. 进行中：表示当前流程实例还在流转中，没有最终结果<br>1. 已完成：表示当前流程实例已经被通过<br>1. 已拒绝：表示当前流程实例已经被拒绝<br>1. 已撤回：表示当前还在“进行中”的流程实例已被发起人或审批单管理员撤回<br>1. 已撤销：表示当前“已完成”的流程实例已被发起人或审批单管理员撤销
流程节点 | 每一个审批流程由一或多个流程节点构成，每一个节点表示审批流转过程中的一个步骤，在当前节点完成后进入下一个节点。每当流程实例创建时，会生成该实例对应的各个流程节点，并由流程节点构成审批流程
审批任务 | 审批任务依赖于流程节点存在，每个流程节点可能包含有一或多个审批任务，每一个任务表明当前流程节点的审批人是谁
任务状态 | 任务状态是指审批任务的运行状态，随着审批人执行通过、拒绝等操作，任务状态会随之发生变化。任务状态包含以下几种状态：<br>1. 跳过：在审批任务运行时，由于满足特定条件，某个或某些审批节点会被自动忽略，流程直接进入下一个节点<br>1. 发起：表示当前审批任务已经被发起人发起<br>1. 未开始：表示当前审批任务尚未发起<br>1. 进行中：表示当前审批任务正在在进行中，没有最终结果<br>1. 已拒绝：表示当前审批任务已经被拒绝<br>1. 已通过：表示当前审批任务已经被通过，可流转到下一个审批任务<br>1. 被撤回：表示当前还在“进行中”的审批任务已经被发起人或审批单管理员进行撤回<br>1. 抄送：表示当前审批任务已经抄送给对应节点的抄送人<br>1. 表单提交：表示表单节点的操作人已经完成了表单提交操作<br>1. 失败：表示电子签节点签署失败<br>1. 已回退：表示当前审批任务已经完成了回退操作<br>1. 发起撤销：表示当前“已完成”的审批任务被发起人或审批单管理员撤销
业务类型 | 飞书People 流程支持飞书 People 中多个业务的审批流程（例如信息变更申请、离职等），不同的业务对应不同的业务类型。在不同业务类型下创建的流程将仅在对应的业务可以使用，且如果审批通过，会触发对应业务关联的系统作业（例如“信息变更申请”审批通过后，会自动更新员工的相关信息）。<br>| 业务类型  | 参数 | bizType  <br>| --------- | --------------- | -------   | ----------- | --------- |<br>|`离职补偿金申请` | `41` | resignation_compensation | <br>|`试用期转正` | `42` | corehr_probation_default_flow| <br>|`员工异动` | `43` | job_change| <br>|`离职申请` | `44` | offboarding_info| <br>|`合同续约` | `45` | renewal_record| <br>|`组织架构调整` | `46` | reorg_approval_group| <br>|`猎头服务费审批` | `48` | headhunting| <br>|`离职手续办理` | `50` | offboarding_transfer| <br>|`申请虚线团队权限` | `51` | additional_manage_relation_rule| <br>|`Offer 审批` | `52` | offer| <br>|`回流人员确认` | `53` | pre_hire_back| <br>|`申请信息变更` | `54` | person_info_change| <br>|`编制规划调整审批` | `55` | workforce_plan_adjustment| <br>|`休假申请` | `56` | leave_application| <br>|`Offer 薪酬审批` | `57` | offer_salary| <br>|`自助证明` | `58` | self_certificate| <br>|`自助服务` | `59` | self_service| <br>|`Offer 及薪酬合并审批` | `60` | offer_salary_merge| <br>|`Payroll 发薪活动审批` | `61` | payroll| <br>|`调薪` | `62` | cpst_adjust_salary_flow_info| <br>|`职位广告内容审批` | `63` | job_post_content_approval| <br>|`职位广告渠道审批` | `64` | job_post_channel_approval| <br>|`招聘需求审批` | `65` | recruitment_request_approval| <br>|`期权到期补齐审批` | `70` | rsu_refrsh_approval_new| <br>|`加班申请` | `68` | work_application| <br>|`出差申请` | `69` | travel_application| <br>|`外出申请` | `72` | outing_application| <br>|`补卡申请` | `71` | remedy_application|<br>|`换班申请` | `76` | swap_shift_application| <br>|`值班补贴（新）` | `75` | onduty_bonus_apply| <br>|`批量调薪（新）` | `74` | batch_compensation_adjustment_new|<br>|`数据填报审批` | `73` | payroll_data_report|

## 接入流程

### 接入准备
1、创建应用

首先需要在[飞书开放平台](https://open.larkoffice.com/)创建一个应用

![20241202-162306.jpeg](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7060b70b98a004c88a1e7b56d60a8ada_YdtBxUUx3T.jpeg?height=608&lazyload=true&width=1754)

2、申请调用流程接口和订阅事件所需要的权限

创建应用成功后，在开发配置 -> 权限管理页面申请所需要的权限

![20241202-165153.jpeg](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/02494398290a79a10f69983496c8f344_KudIOaTShI.jpeg?height=1344&lazyload=true&width=3434)

3、发布应用版本

![20241202-165254.jpeg](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8df046afa259af056f73a03f1524281b_bulyRCtnpL.jpeg?height=1354&lazyload=true&width=2642)
### api接入示例
接下来我们会尝试利用 Open API 查询指定员工的审批任务，并对该任务进行审批。

1. 获得开放平台应用的 App ID 和 App Secret

在开放平台找到刚才发布通过了的应用，我们可以找到这个应用对应的 [App ID 和 App Secret](https://open.feishu.cn/document/ukTMukTMukTM/uYTM5UjL2ETO14iNxkTN/terminology)

![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b42378b0963e82e71ee860978bc6ad4a_4IbawiPvWD.png?height=1916&lazyload=true&width=3840)

2. 使用服务端API

以Go语言为例，通过[调用服务端API](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/golang-sdk-guide/calling-server-side-apis)文档，构建出 API Client。

这里我们采用最简单的方式快速构建出一个 API Client 供我们接下来使用。
```javascript
var client = lark.NewClient("YOUR_APP_ID", "YOUR_APP_SECRET") // 默认配置为自建应用
```

3. 查询指定员工的审批任务

通过下面的代码我们可以查询到指定员工的[审批任务](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/corehr-v1/process-form_variable_data/approver-task/resource-introduce)，其中UserID等入参方式的获取方式可以参考[获取指定人员审批任务列表](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/approver/list)的接口文档。

```javascript
func main() {
	// 创建 Client
	client := lark.NewClient("YOUR_APP_ID", "YOUR_APP_SECRET")
	// 创建请求对象
	req := larkcorehr.NewListApproverReqBuilder().
		PageSize(20).
		UserIdType("open_id").
		UserId("123").
		Build()

// 发起请求
	resp, err := client.Corehr.V2.Approver.List(context.Background(), req)

// 处理错误
	if err != nil {
		fmt.Println(err)
		return
	}

// 服务端错误处理
	if !resp.Success() {
		fmt.Printf("logId: %s, error response: \n%s", resp.RequestId(), larkcore.Prettify(resp.CodeError))
		return
	}

// 业务处理
	fmt.Println(larkcore.Prettify(resp))
}
```
执行下面的代码后，可以在响应体的`Data`字段中获得形式如下的数据
```json
{
    PageToken: "2",
    HasMore: false,
    ApproverList: [
      {
        ApproverId: "7444909165174081068",
        ProcessId: "7444909155858531884",
        ApproverStatus: 1
      },
      {
        ApproverId: "7444908178954798636",
        ProcessId: "7444908169433728556",
        ApproverStatus: 1
      },
      {
        ApproverId: "7444906172873721388",
        ProcessId: "7444906165458191916",
        ApproverStatus: 1
      }
  ]
}

```
根据响应体的定义可知：查询的员工有三个正在进行的审批任务。接下来可以根据响应体中的`ApproverId`和`ProcessId`对相应的审批任务进行审批。

4. 通过/拒绝审批任务

在获取到流程实例ID和审批任务ID后，通过[通过/拒绝审批任务](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/corehr-v2/process-approver/update)接口实现对审批任务的处理。对于一个简单的审批任务，使用 Open API 通过审批的示例代码如下
```javascript
func main() {
	// 创建 Client
	client := lark.NewClient("YOUR_APP_ID", "YOUR_APP_SECRET")
	// 创建请求对象
	req := larkcorehr.NewUpdateProcessApproverReqBuilder().
		ProcessId(`1`).
		ApproverId(`1`).
		ProcessApprover(larkcorehr.NewProcessApproverBuilder().
			Status(2).
			UserId(`ou_91791271921729102012`).
			SystemApproval(true).
			Reason(`原因自定义字符串`)
			Build()).
		Build()

// 发起请求
	resp, err := client.Corehr.V2.ProcessApprover.Update(context.Background(), req)

// 处理错误
	if err != nil {
		fmt.Println(err)
		return
	}

// 服务端错误处理
	if !resp.Success() {
		fmt.Printf("logId: %s, error response: \n%s", resp.RequestId(), larkcore.Prettify(resp.CodeError))
		return
	}

// 业务处理
	fmt.Println(larkcore.Prettify(resp))
}
```

### 事件订阅接入示例

1、配置事件订阅方式

事件订阅方式一共有两种，分别为“推送至开发者服务器”和“长连接”，详细区别可通过链接查看[配置事件订阅方式](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case)，本示例使用的是长连接的方式来接收事件

![20241203-194837.jpeg](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6425c1e46bdb77997ee728ade44c389e_kbWnwmffgo.jpeg?height=1202&lazyload=true&width=2768)

2、添加要订阅的事件

![20241203-195821.jpeg](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/037136485e34670b63f7ab1afcc1665d_qtwlXgHNug.jpeg?height=1564&lazyload=true&width=3454)
添加所需订阅的事件后，当事件发生时，开放平台会向应用推送事件信息，以便应用快速响应事件

3、申请事件权限

添加事件后，还需为应用申请开通相关事件权限才能使订阅生效。应用权限包括接口调用权限和字段访问权限（针对部分敏感字段，需要额外申请字段访问权限）

本示例订阅的“流程实例状态变化”权限要求为“获取流程数据”，已在接入准备中申请过了，此处不再详细演示

4、接收并处理事件

以golang为例（其他示例代码可参考[事件订阅示例代码](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case)），接收事件代码如下：

```javascript 
func main() {
	eventHandler := dispatcher.NewEventDispatcher("应用的 verificationToken", "应用的 eventEncryptKey（未设置可以填入空串）").
	OnP2MessageReceiveV1(func(ctx context.Context, event *larkim.P2MessageReceiveV1) error {
			fmt.Printf("[ OnP2MessageReceiveV1 access ], data: %s\n", larkcore.Prettify(event))
			return nil
		}).
	OnCustomizedEvent("此处写订阅事件的eventType", func(ctx context.Context, event *larkevent.EventReq) error {
			fmt.Printf("[ OnCustomizedEvent access ], type: message, data: %s\n", string(event.Body))
			return nil
		})
	// 创建Client
	cli := larkws.NewClient("应用的appId", "应用的appSecret",
		larkws.WithEventHandler(eventHandler),
		larkws.WithLogLevel(larkcore.LogLevelDebug),
	)
	// 启动客户端
	err := cli.Start(context.Background())
	if err != nil {
		panic(err)
	}
}
``` 
-  verificationToken和eventEncryptKey的获取方式

![20241203-203103.jpeg](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/72797ab1bff5625140af0effabb9c322_EJ6ubqNkQ8.jpeg?height=1124&lazyload=true&width=2374)

-  订阅事件eventType的获取方式

![20241203-203226.jpeg](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/dc2e5760bc2fd88118e0d3a156bf9bc7_mqZf9k7SQy.jpeg?height=1296&lazyload=true&width=3412)

