背景

由于业务需求,目前开发的系统中需要调用飞书的接口,打通飞书和该系统,实现统一管理员工的目的。
这次主要开发的接口是获取飞书部门和员工列表的接口、通过企业自建应用发送飞书消息的接口、获取飞书打卡日报的接口。开发过程中还是挺烦躁的,飞书提供的SDK还不完善,部分接口是未封装的,需要map接收然后转化数据格式,开发文档中也没有提供SDK的说明,需要的接口都是自己在类里面找到的。

开发流程

pom文件引入依赖

<dependency>
	<groupId>com.larksuite.oapi</groupId>
	<artifactId>larksuite-oapi</artifactId>
	<version>1.0.5</version>
</dependency>

java 对接RocketMQ Java 对接企飞_请求参数


上图可知,飞书的SDK能够支持的服务只有4个

java 对接RocketMQ Java 对接企飞_开发文档_02


上图的项目结构中我们可以看到,提供的服务在service中,由于官方文档中没有提供那个功能需要调用的接口代码,所以需要我们自己去这写服务代码中找到需要的接口,下面我将用获取部门的接口为例,来说一下如何找到自己需要的接口。

获取部门列表接口开发(有SDK接口可调用)

java 对接RocketMQ Java 对接企飞_App_03


从开发文档中我们可以看到获取部门信息列表的接口请求路径是https://open.feishu.cn/open-apis/contact/v3/departments

由项目结构的contact可知,通讯录相关的接口应该是在这个目录下,于是我们进入这个目录。

java 对接RocketMQ Java 对接企飞_请求参数_04


由于上图的红框中代码basepath等于"contact/v3",我们需要请求的地址也是有这个的,所以确定我们找对了地方

java 对接RocketMQ Java 对接企飞_开发文档_05


通过页面搜索功能,终于找到了对应的请求方法,看样子,就是这个接口了。

java 对接RocketMQ Java 对接企飞_java_06


由上图可知,我们需要的这个接口在一个内部类里面,因此我们需要先生成一个这个内部类的对象。

java 对接RocketMQ Java 对接企飞_java 对接RocketMQ_07


通过idea提示可以看到,这个地方是return了这个类对象的,跳过去看看

java 对接RocketMQ Java 对接企飞_App_08


这可以看到,是一个list方法生成出来的,而且是Departments的对象调用的,ok,那我们再去看如何生成Departments对象

java 对接RocketMQ Java 对接企飞_开发文档_09


在这个类的构造方法中我们可以看到,生成ContactService对象的时候就帮我们new号了对象,所以我们直接用get方法获取就可以了。

那调用路径我们走通了,即下图代码

response = contactService.getDepartments().list().execute();

还有问题,new ContactService时需要提供Config对象,继续找

// 企业自建应用的配置
    // AppID、AppSecret: "开发者后台" -> "凭证与基础信息" -> 应用凭证(App ID、App Secret)
    // VerificationToken、EncryptKey:"开发者后台" -> "事件订阅" -> 事件订阅(Verification Token、Encrypt Key)。
    public static final AppSettings appSettings = Config.createInternalAppSettings("AppID", "AppSecret", "VerificationToken", "EncryptKey");

    // 当前访问的是飞书,使用默认存储,更多可选配置,请看:README.zh.md->高级使用->如何构建整体配置(Config)。
    public static final Config config = new Config(Domain.FeiShu, appSettings, new DefaultStore());

在github上飞书提供的README.zh.md里找到的,就直接用了,懒得去代码里找了

把上面代码的AppID和AppSecret换成我们自建应用的就好了,另外两个参数我没有,直接设置未null;

此时我们知道了如何请求这个接口,但是请求参数还没设置

java 对接RocketMQ Java 对接企飞_请求参数_10


通过开发文档我们可以看到需要的请求参数,然后根据上面的方法设置就好了,所以最终代码是这样的:

response = contactService.getDepartments().list().setDepartmentIdType("department_id")
							.setParentDepartmentId(id).setPageToken(pageToken).setFetchChild(true).execute();

这样,我们请求部门列表的接口就完成了。

打卡数据获取(无SDK接口调用)

做这个接口的时候我也有点懵,这没给我可调用的接口我咋弄啊。。。

后来,我在GitHub上看到了他们的示例代码里,看到了

java 对接RocketMQ Java 对接企飞_java 对接RocketMQ_11


索嘎,原生模式

原生模式发送请求得到数据也很简单,但是!!!!后续的数据处理真的头大。

Map<String, Object> message = new HashMap<>();
message.put(EnumsFeishuCheckInDayData.user_ids.name(), userIds);
message.put(EnumsFeishuCheckInDayData.check_date_from.name(), startTime);
message.put(EnumsFeishuCheckInDayData.check_date_to.name(), endTime);
Request<Map<String, Object>, Map<String, Object>> request = Request.newRequest(EnumFeishuUrl.CheckResults.getUrl(),
                "POST", AccessTokenType.Tenant, message, new HashMap<>());
Response<Map<String, Object>> response = Api.send(config, request);

上面就是请求接口的代码了,很简单,主要是使用Request<Map<String, Object>, Map<String, Object>>这个类做一个请求,然后使用Api.send发送出去,得到返回结果就行。
Request.newRequest的参数是:请求地址、请求类型、令牌类型、输入参数、输出参数

  • 1、这里的令牌类型由于是企业自建应用,所以使用AccessTokenType.Tenant,它有3个取值:AccessTokenType.App / AccessTokenType.Tenant / AccessTokenType.User,从名字上来看就能理解什么意思。
  • 2、输入参数很容易理解,就是我们的请求参数,用map装就好
  • 3、输出参数这里需要注意,这个对象是接收返回值的,经过我的实验,输出参数不同,获得的返回值也不同,but我自己建的对象发过去没转过来,可能是我技术不过关,建的对象不对吧。。。所以我选择了用map接收返回值
    (还是想吐槽一下,没有文档可以参考,全靠自己摸索,飞书可真有你的)
    然后噩梦就来了,我需要把map转化为我自己服务端的对象,比较痛苦,就不展示了。
总结

Java端调用飞书的接口熟练了还是挺简单,但是我刚开始开发的时候,看开发文档一脸懵逼,网上也没有这方面的文章(这也是我写这篇的初衷),全是自己摸索着来,还是比较痛苦的。