文章目录

前言1. 准备工作1.1 创建应用1.2 创建文件夹

2. 测试租户/个人版实践2.1 权限配置2.2 控制台调试2.3 协作文档添加应用2.4 CRUD2.4.1 根据文档描述选择token并生成2.4.2 新增多维表格数据API2.4.3 删除多维表格数据API2.4.4 查询多维表格数据API2.4.5 修改多维表格数据API

3. 项目实战3.1 工具类3.2 业务实战

4. 总结参考资料

飞书应用接入飞书云文档

前言

自从团队接入飞书之后,我们许多应用及数据都要接入或迁移至飞书。不久之前,我就承接并完成了一个监控信息接入飞书机器人实时通知的需求。上次接入的直接体验:飞书文档详略得当,简单易入手。

需求描述

创建飞书应用,配置权限等,通过该应用调用飞书云文档API调用飞书云文档API,实现业务数据可及时同步到飞书云文档定时任务执行:将业务本身的数据更新同步到飞书云文档,并将云文档的更改同步到数据库。

学习目标

结合官方文档,参考本次分享的经历,实现业务数据通过飞书应用接入飞书云文档。学习并练习 基于Java的 Http 请求及响应处理方式。期望本文可作为有类似需求读者实现类似业务的参考,希望可以突出重点。

实操准备 若读者要随着本文进行实操,需要事先准备如下:

个人或企业飞书账号,并确保拥有创建应用等权限有一个基础项目,语言不限,可以通过这个项目发送 Http 请求。本文是以 Java Spring 项目为例。

下面我们开始!

1. 准备工作

这一小节我们一起做一些准备工作:创建应用、创建目标文档。

1.1 创建应用

为了不影响公司数据,我们先在飞书个人版创建应用,并编写Demo代码测试。但是要注意,截止至发文日期,飞书个人版并不存在管理后台,因此在个人版申请的应用目前用完后无法停用与删除。因此若是有和我一样的强迫症读者,可以自己创建一个企业账户进行实践。为了方便权限管理,以下实践基于我个人创建的测试企业租户。当然个人版的流程我也走了一遍,过程是几乎一样的,供读者参考。

我们的目的是要通过飞书应用来进行飞书云文档的操作。那么第一步就是要创建应用。创建飞书应用一方面可以直接在开发者后台进行API调试,另一方面我们需要拿到这个应用的一些key来在代码层面调用API。

首先,我们进入开发者后台: 飞书开放平台-开发者后台

登录后,我们可以选择创建应用,如图所示:

1.2 创建文件夹

我们的目标是要进行云文件操作,首先要有一个文件夹。我们创建该文件夹并复制链接:

复制链接是为了拿到API所需的 文件夹信息。我们可以先在某个地方保存这个路径,待会会用到。

准备工作完成,接下来,我们就可以对飞书API进行实践了!

2. 测试租户/个人版实践

2.1 权限配置

为了避免读者在第一次调试的时候就反复跳转开通权限,由于小编本人已事先读过官方文档,这里建议追求省时间的读者先开通所需权限,再进行API控制台调试。

权限配置是我们做飞书应用接入业务的重要一环。当然也要注意,由于租户隔离,自己的个人应用目前是无法调用企业云文档的。

在接下来的学习与调试中,若飞书API返回结果报权限错误,那么就需要我们重新关注权限,并重复权限配置这一环节了。

2.2 控制台调试

调试第一步,我们可以先在控制台调试。我们打开飞书官方文档并翻出在上一小节复制的文件夹地址,其中包含folder_token,来进行控制台调试:

其中,folder_token 参数在链接最后获取(详情见官方文档)。注意,飞书多维表格相关API很多参数都是在对应的云文档链接获取的。

还有一个注意点:飞书主要提供2种token:user_access_token 与 tenant_access_token . 分别对应以用户还是以租户身份操作,两者权限不同。在控制台调试阶段,我们可以先用简单一些的 user_access_token 调通。如截图所示,我个人演示用的是tenant_access_token, 可以在控制台进行切换。

如果调用成功,那么我们应该可以在刚才创建的文件夹里找到这个文件。

2.3 协作文档添加应用

我们需要在写作文档中将应用添加进去,并将应用开启机器人能力,这样,接下来我们就可以使用tenant_access_token进行API调用了!

2.4 CRUD

这一小节我们来调用增删查改 API 来实现飞书云文档的增删查改基础功能吧 !

在开始之前,我们还要重复复制文件等步骤获取所需的key,以及关注 tenant_access_token 的生成。

同时,这一小节我们可以在自己的项目调用这里举例的官方 CRUD API代码示例来进行操作。

2.4.1 根据文档描述选择token并生成

官方提供了https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal接口为我们生成调用 API 必需的token。

以下是示例代码:

public static String getAccessToken(String appId, String appSecret) throws Exception {

String res = null;

// 创建一个 URL 对象

URL url = new URL("https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal");

// 打开一个 HTTP 连接

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

// 设置连接超时时间

connection.setConnectTimeout(5000);

// 设置读取超时时间

connection.setReadTimeout(5000);

// 设置请求方法为 POST

connection.setRequestMethod("POST");

// 设置 doOutput 属性为 true

connection.setDoOutput(true);

// 设置通用的请求属性

connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");

// 设置请求体

JSONObject jsonObject = new JSONObject();

jsonObject.put("app_id", appId);

jsonObject.put("app_secret", appSecret);

connection.getOutputStream().write(jsonObject.toJSONString().getBytes());

// 发送请求

connection.connect();

// 获取响应码

int responseCode = connection.getResponseCode();

// 如果响应码为 200,则表示请求成功

if (responseCode == 200) {

// 获取响应内容

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

String line;

StringBuilder response = new StringBuilder();

while ((line = reader.readLine()) != null) {

response.append(line);

}

reader.close();

res = response.toString();

} else {

// 请求失败

log.info("请求失败,响应码{}",responseCode);

}

// 关闭连接

connection.disconnect();

return res;

}

至于 appId、appSecret,点击我们的应用,在醒目的地方有显示。

2.4.2 新增多维表格数据API

官方文档链接 新增多维表格数据

调用代码示例

package com.lark.oapi.sample.apiall.bitablev1;

import com.lark.oapi.Client;

import com.lark.oapi.core.utils.Jsons;

import com.lark.oapi.service.bitable.v1.model.*;

import java.util.HashMap;

import com.lark.oapi.core.request.RequestOptions;

// SDK 使用文档:https://github.com/larksuite/oapi-sdk-java/tree/v2_main

// 开发者复制该Demo后,需要修改Demo里面的"appID", "appSecret"为自己应用的appId,appSecret.

public class CreateAppTableRecordSample {

public static void main(String arg[]) throws Exception {

// 构建client

Client client = Client.newBuilder("appId", "appSecret")

.disableTokenCache() //如需SDK自动管理租户Token的获取与刷新,可删除该行

.build();

// 创建请求对象

CreateAppTableRecordReq req = CreateAppTableRecordReq.newBuilder()

.appToken("")

.tableId("")

.userIdType("")

.clientToken("")

.appTableRecord(AppTableRecord.newBuilder()

.fields()

.build())

.build();

// 发起请求

// 如开启了Sdk的token管理功能,就无需调用 RequestOptions.newBuilder().tenantAccessToken("t-xxx").build()来设置租户token了

CreateAppTableRecordResp resp = client.bitable().appTableRecord().create(req, RequestOptions.newBuilder()

.tenantAccessToken("")

.build());

// 处理服务端错误

if(!resp.success()) {

System.out.println(String.format("code:%s,msg:%s,reqId:%s", resp.getCode(), resp.getMsg(), resp.getRequestId()));

return;

}

// 业务数据处理

System.out.println(Jsons.DEFAULT.toJson(resp.getData()));

}

}

2.4.3 删除多维表格数据API

官方文档链接 删除多维表格数据

调用代码示例

package com.lark.oapi.sample.apiall.bitablev1;

import com.lark.oapi.Client;

import com.lark.oapi.core.utils.Jsons;

import com.lark.oapi.service.bitable.v1.model.*;

import java.util.HashMap;

import com.lark.oapi.core.request.RequestOptions;

// SDK 使用文档:https://github.com/larksuite/oapi-sdk-java/tree/v2_main

// 开发者复制该Demo后,需要修改Demo里面的"appID", "appSecret"为自己应用的appId,appSecret.

public class DeleteAppTableRecordSample {

public static void main(String arg[]) throws Exception {

// 构建client

Client client = Client.newBuilder("appId", "appSecret")

.disableTokenCache() //如需SDK自动管理租户Token的获取与刷新,可删除该行

.build();

// 创建请求对象

// 发起请求

// 如开启了Sdk的token管理功能,就无需调用 RequestOptions.newBuilder().tenantAccessToken("t-xxx").build()来设置租户token了

DeleteAppTableRecordResp resp = client.bitable().appTableRecord().delete(RequestOptions.newBuilder()

.tenantAccessToken("")

.build());

// 处理服务端错误

if(!resp.success()) {

System.out.println(String.format("code:%s,msg:%s,reqId:%s", resp.getCode(), resp.getMsg(), resp.getRequestId()));

return;

}

// 业务数据处理

System.out.println(Jsons.DEFAULT.toJson(resp.getData()));

}

}

2.4.4 查询多维表格数据API

官方文档链接 多维表格数据列表

调用代码示例

package com.lark.oapi.sample.apiall.bitablev1;

import com.lark.oapi.Client;

import com.lark.oapi.core.utils.Jsons;

import com.lark.oapi.service.bitable.v1.model.*;

import java.util.HashMap;

import com.lark.oapi.core.request.RequestOptions;

// SDK 使用文档:https://github.com/larksuite/oapi-sdk-java/tree/v2_main

// 开发者复制该Demo后,需要修改Demo里面的"appID", "appSecret"为自己应用的appId,appSecret.

public class ListAppTableRecordSample {

public static void main(String arg[]) throws Exception {

// 构建client

Client client = Client.newBuilder("appId", "appSecret")

.disableTokenCache() //如需SDK自动管理租户Token的获取与刷新,可删除该行

.build();

// 创建请求对象

// 发起请求

// 如开启了Sdk的token管理功能,就无需调用 RequestOptions.newBuilder().tenantAccessToken("t-xxx").build()来设置租户token了

ListAppTableRecordResp resp = client.bitable().appTableRecord().list(RequestOptions.newBuilder()

.tenantAccessToken("")

.build());

// 处理服务端错误

if(!resp.success()) {

System.out.println(String.format("code:%s,msg:%s,reqId:%s", resp.getCode(), resp.getMsg(), resp.getRequestId()));

return;

}

// 业务数据处理

System.out.println(Jsons.DEFAULT.toJson(resp.getData()));

}

}

2.4.5 修改多维表格数据API

官方文档链接 更新多维表格数据

调用代码示例

package com.lark.oapi.sample.apiall.bitablev1;

import com.lark.oapi.Client;

import com.lark.oapi.core.utils.Jsons;

import com.lark.oapi.service.bitable.v1.model.*;

import java.util.HashMap;

import com.lark.oapi.core.request.RequestOptions;

// SDK 使用文档:https://github.com/larksuite/oapi-sdk-java/tree/v2_main

// 开发者复制该Demo后,需要修改Demo里面的"appID", "appSecret"为自己应用的appId,appSecret.

public class UpdateAppTableRecordSample {

public static void main(String arg[]) throws Exception {

// 构建client

Client client = Client.newBuilder("appId", "appSecret")

.disableTokenCache() //如需SDK自动管理租户Token的获取与刷新,可删除该行

.build();

// 创建请求对象

UpdateAppTableRecordReq req = UpdateAppTableRecordReq.newBuilder()

.appToken("")

.tableId("")

.recordId("")

.userIdType("")

.appTableRecord(AppTableRecord.newBuilder()

.fields()

.build())

.build();

// 发起请求

// 如开启了Sdk的token管理功能,就无需调用 RequestOptions.newBuilder().tenantAccessToken("t-xxx").build()来设置租户token了

UpdateAppTableRecordResp resp = client.bitable().appTableRecord().update(req, RequestOptions.newBuilder()

.tenantAccessToken("")

.build());

// 处理服务端错误

if(!resp.success()) {

System.out.println(String.format("code:%s,msg:%s,reqId:%s", resp.getCode(), resp.getMsg(), resp.getRequestId()));

return;

}

// 业务数据处理

System.out.println(Jsons.DEFAULT.toJson(resp.getData()));

}

}

3. 项目实战

3.1 工具类

先封装通用工具类,以及时获取必须的Token:

/**

* 飞书应用权限工具类

* @author: Sharry

* @createTime: 2023-12-21 10:29

* @version: Version-1.0

*/

public class FeiShuUtils {

public static String getAccessToken(String appId, String appSecret) throws Exception {

String res = null;

// 创建一个 URL 对象

URL url = new URL("https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal");

// 打开一个 HTTP 连接

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

// 设置连接超时时间

connection.setConnectTimeout(5000);

// 设置读取超时时间

connection.setReadTimeout(5000);

// 设置请求方法为 POST

connection.setRequestMethod("POST");

// 设置 doOutput 属性为 true

connection.setDoOutput(true);

// 设置通用的请求属性

connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");

// 设置请求体

JSONObject jsonObject = new JSONObject();

jsonObject.put("app_id", appId);

jsonObject.put("app_secret", appSecret);

connection.getOutputStream().write(jsonObject.toJSONString().getBytes());

// 发送请求

connection.connect();

// 获取响应码

int responseCode = connection.getResponseCode();

// 如果响应码为 200,则表示请求成功

if (responseCode == 200) {

// 获取响应内容

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

String line;

StringBuilder response = new StringBuilder();

while ((line = reader.readLine()) != null) {

response.append(line);

}

reader.close();

// 打印响应内容

res = response.toString();

} else {

}

// 关闭连接

connection.disconnect();

return res;

}

/**

* 获取租户 tenant_access_token

*/

public static String getAppAccessToken(String appId, String appSecret) throws Exception {

JSONObject jsonObject = JSONObject.parseObject(getAccessToken(appId, appSecret));

return jsonObject.getString("tenant_access_token");

}

}

3.2 业务实战

这一小节记录我个人的业务实战代码示例,仅供参考,代码已脱敏。 其中,有了上面章节单条新增的基础,实际业务中我们可以使用批量接口来提高效率。一次调用,多处更新。

import com.larksuite.oapi.service.bitable.v2.BitableService;

import com.larksuite.oapi.service.bitable.v2.model.BatchUpdateAppTableRecordReq;

import com.larksuite.oapi.service.bitable.v2.model.BatchUpdateAppTableRecordResp;

import com.larksuite.oapi.service.bitable.v2.model.AppTableRecord;

import com.larksuite.oapi.service.bitable.v2.model.RequestOptions;

import java.util.HashMap;

import java.util.Map;

public class BatchUpdateAppTableRecord {

public static void batchUpdateAppTableRecord(String appId, String appSecret)

throws Exception {

// Create a client

Client client = Client.newBuilder("appId", "appSecret")

.disableTokenCache()

.build();

// Create a request

BatchUpdateAppTableRecordReq req = BatchUpdateAppTableRecordReq.newBuilder()

.batchUpdateAppTableRecordReqBody(BatchUpdateAppTableRecordReqBody.newBuilder()

.records(new AppTableRecord[] {

AppTableRecord.newBuilder()

.fields(new HashMap < String, Object > () {})

.recordId("reclAqylTN")

.build()

})

.build())

.build();

// Schedule the task

BatchUpdateAppTableRecordResp resp = client.bitable().appTableRecord().batchUpdate(req, RequestOptions.newBuilder()

.tenantAccessToken("")

.build());

// Handle the response

if (!resp.success()) {

System.out.println(String.format("code:%s,msg:%s,reqId:%s", resp.getCode(), resp.getMsg(), resp.getRequestId()));

return;

}

// Do something with the response data

log.info("{}",Jsons.DEFAULT.toJson(resp.getData()));

}

}

4. 总结

总结 本文通过我个人实际工作的需求,记录了通过飞书官方文档,创建企业应用并将业务接入到飞书云文档并使用的过程。通过本文的记录,我们一起学习了:

飞书应用的创建及相关配置 通过应用调用飞书API,实现数据及时更新到飞书云文档 调用API的本质是HTTP请求,我们又复习了一遍日常生活中如何发起HTTP请求并根据文档接收数据

注意点 有几个值得注意的点

Token 的选用,一是要参考官方文档的建议,二是可以根据 “appId”、“appSecret” 调用官方 token_access_token 接口,结合权限情况及实际具体需求使用

权限:权限很重要,一定要仔细阅读官方文档的同时,和团队、领导等及时沟通,及时申请权限。否则,就算本地调试再6,生产环境没有权限也是不行的

文档 token: 文档的 token 在文档链接中,许多 API 都会直接用到,非常重要。需要在浏览器打开等方式在 url 等获取相关token

多维表格新增的字段一定要严格和该表格字段对应,否则新增的一行在文档无法正常显示,只能在后台通过删除API删除。推荐用Json工具处理

参考资料

飞书官方文档

推荐文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。