larksuite / node-sdk Goto Github PK
View Code? Open in Web Editor NEWlarksuite open sdk for nodejs
License: MIT License
larksuite open sdk for nodejs
License: MIT License
版本:^1.8.1
设置的自定义请求头不起作用
import { data } from '../../../env';
import * as lark from '@larksuiteoapi/node-sdk';
const client = new lark.Client({
appId: data.appId,
appSecret: data.appSecret,
});
class Feishu {
public accessToken = 't-g1041gdxODD4F2FX5VTFKDXFNG3DO24Z5MDPLBBF';
public getChatIdByRobotId() {
return client.im.chat.list(undefined, {
headers: {
Authorization: `Bearer ${this.accessToken}`,
},
}
// lark.withTenantToken(`Bearer ${this.accessToken}`)
);
}
}
const service = new Feishu();
service.getChatIdByRobotId();
使用client.bitable.appTableRecord.create click to debug。调试平台的接口是/open-apis/bitable/v1/apps/:app_token/tables/:table_id/records
但是实际页面请求https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal
curl 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal'
-H 'sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"'
-H 'Accept: application/json, text/plain, /'
-H 'Content-Type: application/json'
-H 'Referer: http://127.0.0.1:5173/'
-H 'sec-ch-ua-mobile: ?0'
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
-H 'sec-ch-ua-platform: "macOS"'
--data-raw '{"app_id":"app id","app_secret":"app secret"}'
--compressed
只要把类型17那个field注释掉就能创建成功,不然就会报400,code是99992402
const res = await this.larkClient.bitable.appTable.create({ path: { app_token: body.app_token, }, data: { table: { name:
结果 - ${new Date().valueOf()}, fields: [ { field_name: '接口', type: 1, }, { field_name: '影响程度', property: { options: [ { color: 0, name: 'P0', }, { color: 1, name: 'P1', }, { color: 2, name: 'P2', }, ], }, type: 3, }, { field_name: '修复优先级', property: { options: [ { color: 0, name: 'P0', }, { color: 1, name: 'P1', }, { color: 2, name: 'P2', }, ], }, type: 3, }, { field_name: '结果', property: { options: [ { color: 36, name: '通过', }, { color: 22, name: '失败', }, { color: 0, name: '无效', }, ], }, type: 3, }, // { // field_name: '截图', // type: 17, // }, { field_name: '备注', type: 1, }, { field_name: '场景', property: { options: [], }, type: 3, }, { field_name: '链接', type: 15, }, ], }, }, });
client.im.message.create 里面 data 的 content 参数格式必须是个 JSON.String 格式才可以,另外,如果要在 BOE 环境测试,要设置 初始化 Client 的时候,把 domain 切到 BOE 。这文档里写的操作说明太少了,不靠谱,至少应该找个新人按照这个跑一遍看下缺啥再补全了放出来。
写了个简单的图片批量上传脚本, 有比较奇怪的错误,想要求助一下。
client 其他的消息发送指令都正常使用没问题,就是图片上传这个有点异常。
@larksuiteoapi/node-sdk 版本 1.12.0
。
[error]: [
[
TypeError: source.on is not a function
at Function.DelayedStream.create (/Users/tzwm/projects/MTRPG-AI/node_modules/delayed-stream/lib/delayed_stream.js:33:10)
at FormData.CombinedStream.append (/Users/tzwm/projects/MTRPG-AI/node_modules/combined-stream/lib/combined_stream.js:45:37)
at FormData.append (/Users/tzwm/projects/MTRPG-AI/node_modules/@larksuiteoapi/node-sdk/node_modules/form-data/lib/form_data.js:75:3)
at build (/Users/tzwm/projects/MTRPG-AI/node_modules/@larksuiteoapi/node-sdk/node_modules/axios/lib/helpers/toFormData.js:63:16)
at each (/Users/tzwm/projects/MTRPG-AI/node_modules/@larksuiteoapi/node-sdk/node_modules/axios/lib/helpers/toFormData.js:58:9)
at Object.forEach (/Users/tzwm/projects/MTRPG-AI/node_modules/@larksuiteoapi/node-sdk/node_modules/axios/lib/utils.js:276:12)
at build (/Users/tzwm/projects/MTRPG-AI/node_modules/@larksuiteoapi/node-sdk/node_modules/axios/lib/helpers/toFormData.js:40:13)
at toFormData (/Users/tzwm/projects/MTRPG-AI/node_modules/@larksuiteoapi/node-sdk/node_modules/axios/lib/helpers/toFormData.js:67:3)
at Object.transformRequest (/Users/tzwm/projects/MTRPG-AI/node_modules/@larksuiteoapi/node-sdk/node_modules/axios/lib/defaults/index.js:80:14)
at transform (/Users/tzwm/projects/MTRPG-AI/node_modules/@larksuiteoapi/node-sdk/node_modules/axios/lib/core/transformData.js:18:15)
]
]
fs.readdir(directory, (err, files) => {
// 过滤出所有图片文件
const imageFiles = files.filter(file => {
const extension = file.split('.').pop()?.toLowerCase();
return extension === 'jpg' || extension === 'jpeg' || extension === 'png' || extension === 'gif';
});
// 输出所有图片文件的文件名
console.log('Image files in directory:');
imageFiles.forEach(file => {
console.log(file);
const buffer = fs.readFileSync(directory + "/" + file);
//console.log(buffer);
client.im.image.create({
"data": {
"image_type": "message",
"image": buffer,
}
}).then(res => {
console.log(res);
}).catch(err => console.log("errorrrrrrrr", err))
});
});
审批相关的事件推送目前还没有写定义,请问这部分支持是否有时间表?或者在 lark.EventDispatcher
中是否有自己写 sdk 中未定义的事件推送的方法?
网页在线调试中,可以更新对应多维表格数据。但本地代码调用API,返回Code :91403
经测试:网页在线调试里把tenant_access_token 换成代码请求的tenant_access_token ,返回值为 Code :91403
看上去应该是token被缓存了?没有及时更新导致鉴权失败。配置disableTokenCache:true。也没有起到作用。
求解何解决?
https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/:spreadsheetToken/values 这个 api nodejs sdk 没有
Line 75 in 1b2f108
目前的 Token 获取后都会存储在 Client.cache 中,其值源为:
其中 internalCache 是个全局单例,会造成 Token 在同一个进程的多个 Client 之间被错误复用(有一个 Token 后将不再获取,即便是调用的另一个 Client/Tenant)
同时,当试图关闭缓存以绕过问题时会发现:
||
,cache 字段实际上不能通过传 null 实现不缓存disableTokenCache
字段语义不符,会直接不获取 TokenClient.cache 调整为每次 Client 实例化时新初始化一个 DefaultCache,以保证 Client 间信息隔离
复现流程:
代码片段:
@Post()
async on_event(@Body() body,@Headers() headers){
const data = {
reqData:body,
headers
}
const { isChallenge, challenge } = generateChallenge(body, {
encryptKey: this.lark_dispatcher.encryptKey
});
if(isChallenge){
return challenge
}
const result = await this.lark_dispatcher.invoke(data)
if(result instanceof CardActionHandler)
return result
return {}
}
经过追踪,疑似checkIsEventValidated
函数中(
node-sdk/dispatcher/request-handle.ts
Line 104 in 6bf94c9
data
作了Hash运算,而此时的data中存在“headers”对象,因此Hash不一致后端服务是用的nestjs,支持吗接入吗?接入方式能给个简单的demo或者思路
https://github.com/larksuite/node-sdk/blob/main/client/token-manager.ts
如图,this.httpInstance
是axios
实例,但没有取返回结果中的data
字段而是直接对AxiosResponse
进行解构,导致无法取到tenant_access_token
。企业自建应用调用任何需要登录的SDK方法,如果不传租户信息,都会走到这一步从而导致后续接口调用报错。
我好像搜不到该群,顺便再问一个问题,该sdk似乎没有对飞书的重推机制进行事件去重,我好像没找到相应的代码
Originally posted by @Justin3go in #8 (comment)
接口:https://open.feishu.cn/open-apis/drive/v1/files/upload_all
请求体:{
file:fs.createReadStream(filePath),
file_name:'linux.png',
parent_node:'doxcnKaRoFFyXR0F0vitI6fCfixxxxx',
parent_type:"explorer",
size:9268
}
返回:{
"code": 1061001,
"msg": "unknown error.",
"error": {
"log_id": "202304162015407FE8A9174362798A6D6B"
}
}
在文档中有机器人相关接口 https://open.feishu.cn/document/ukTMukTMukTM/uAjMxEjLwITMx4CMyETM ,但是在 sdk 中并没有,是否可以更新一下。
我看到 sdk 大多数是根据 code-gen 生成的,但是并没有看到 code gen 生成的具体代码逻辑,这里能够开放一下方便提交 pr 吗
client.auth.auth.tenantAccessTokenInternal({
data: {
app_id: 'cli_xxxxxxxxx',
app_secret: 'CXTxxxxxxxxxxxxxxxxx',
},
},
lark.withTenantToken("")
).then(res => {
console.log(res);
});
根据app_id, app_secret获取tenantAccessToken,提示没有定义tenantAccessTokenInternal。我看node-sdk-main-branch的代码,里面确实没有定义tenantAccessTokenInternal。但这个调用我是参考的飞书服务器api文档
https://www.npmjs.com/package/@larksuiteoapi/node-sdk/v/1.5.0 npmjs.com 发布了1.5.0 版本
https://github.com/larksuite/node-sdk/blob/main/package.json#L3 main 分支是1.0.3
在之前的 issues 中有提到这个飞书内部群,不知道现在是否开放,如果开放了,求拉,感谢🙏
是飞书官方还是民间的 SDK 啊?
你好,请问这个sdk有jssdk方面的api吗?
比如👇这个:
https://open.feishu.cn/open-apis/jssdk/ticket/get
或者有没有直接能够通过url生成一个h5 js需要的config的接口?
The API bitable.appTableRecord.list
(and listWithIterator) returns a plain object in data.items.fields
, but the typescript declaration said it is a Map<string, ...>
, which is incorrect, it should be a Record<...>
.
fields: Map<string, string | boolean | {
text?: string;
link?: string;
} | {
location?: string;
pname?: string;
cityname?: string;
adname?: string;
address?: string;
name?: string;
full_address?: string;
} | Array<string> | Array<{
id?: string;
name?: string;
en_name?: string;
email?: string;
}> | Array<{
file_token?: string;
name?: string;
type?: string;
size?: number;
url?: string;
tmp_url?: string;
}>>
消息体的格式如下
{ "uuid": "54b83e3cac29aa5635a4b540ac8a9882", "event": { "app_id": "cli_a3210d06667a5062", "chat_type": "group", "employee_id": "xx", "is_mention": true, "message_id": "", "msg_type": "text", "open_chat_id": "xx", "open_id": "xx", "open_message_id": "om_6063760aecb6cac19dd3e6ac5dec5478", "parent_id": "", "root_id": "", "tenant_key": "xx", "text": "<at open_id=\"xx\">机器人</at> ddd", "text_without_at_bot": " ddd", "type": "message", "union_id": "on_cdff065033c515aa1abd4d67c3768c73", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_4_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.99 Safari/537.36 Lark/5.10.13 LarkLocale/zh_CN ttnet SDK-Version/5.10.49", "user_open_id": "xx" }, "token": "xx", "ts": "1672757393.949837", "type": "event_callback" }
这里 fields
类型和官方文档上不匹配,缺少了 number
类型
文档:
创建时间 | number | Unix 时间戳,单位是毫秒 |
---|---|---|
最后更新时间 | number | Unix 时间戳,单位是毫秒 |
fields: Record<string, string | boolean | {
text?: string;
link?: string;
} | {
location?: string;
pname?: string;
cityname?: string;
adname?: string;
address?: string;
name?: string;
full_address?: string;
} | Array<string> | Array<{
id?: string;
name?: string;
en_name?: string;
email?: string;
}> | Array<{
file_token?: string;
name?: string;
type?: string;
size?: number;
url?: string;
tmp_url?: string;
}>>;
另外,方不方便提供类型导出,有时候会使用到一些类型
见 https://github.com/larksuite/node-sdk/blob/main/client/token-manager.ts#L79
在配置 cache 时,过期时间是服务器得到的时间,但是请求 tenant_access_token 这个过程以及配置 cache 的这个过程也会浪费些许时间,导致 cache 晚于服务器的真正过期时间。
Bug 复现在我每天有 10 点和12点的两个定时任务,12点的定时任务,将拿到一个过期的 token 发送请求,请求失败。
期望:此时应该使得客户端 cache 的 token 过期删除,将会重新去拿新的 token。
所以需不需要配置过期时间时,比真正的过期时间短一点,或者可以配置参数传递。
const { tenant_access_token, expire } = await http
.post(
`${this.domain}/open-apis/auth/v3/tenant_access_token/internal`,
{
app_id: this.appId,
app_secret: this.appSecret,
}
)
.catch((e) => {
this.logger.error(e);
});
await this.cache?.set(
CTenantAccessToken,
tenant_access_token,
new Date().getTime() + expire * 1000
);
版本:1.17.1
复现代码:
const client = new lark.Client({
appId: 'sdfsdf',
appSecret: 'sdfsdfsdf'
});
// const tenantAccessToken = await client.tokenManager.getTenantAccessToken()
const result = await client.bitable.appTableRecord.list({
path: {
app_token: appToken,
table_id: tableId
}
})
[error]: [
TypeError: adapter is not a function
at dispatchRequest (/Users/elric/playground/daily-report-v2-worker/node_modules/axios/lib/core/dispatchRequest.js:58:10)
at Axios.request (/Users/elric/playground/daily-report-v2-worker/node_modules/axios/lib/core/Axios.js:109:15)
at Axios.httpMethod [as post] (/Users/elric/playground/daily-report-v2-worker/node_modules/axios/lib/core/Axios.js:144:19)
at Function.wrap (/Users/elric/playground/daily-report-v2-worker/node_modules/axios/lib/helpers/bind.js:9:15)
at TokenManager.<anonymous> (/Users/elric/playground/daily-report-v2-worker/node_modules/@larksuiteoapi/node-sdk/es/index.js:22372:18)
at Generator.next (<anonymous>)
at fulfilled (/Users/elric/playground/daily-report-v2-worker/node_modules/@larksuiteoapi/node-sdk/es/index.js:52:58)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
]
[mf:err] POST /: TypeError: Cannot destructure property 'tenant_access_token' of '(intermediate value)' as it is undefined.
at TokenManager.<anonymous> (/Users/elric/playground/daily-report-v2-worker/node_modules/@larksuiteoapi/node-sdk/es/index.js:22371:21)
at Generator.next (<anonymous>)
at fulfilled (/Users/elric/playground/daily-report-v2-worker/node_modules/@larksuiteoapi/node-sdk/es/index.js:52:58)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
axios在最近更新到了1.2.0版本(https://www.npmjs.com/package/axios?activeTab=versions)
在@larksuiteoapi/node-sdk的package.json中配置"axios": ">=0.27.0",
新部署的@larksuiteoapi/node-sdk环境,自动安装1.2.0版本的axios后,调用接口会返回乱码数据,测试代码:
const lark = require("@larksuiteoapi/node-sdk");
const client = new lark.Client({
appId: "********",
appSecret: "********",
});
client.im.chat.list({
params: {
page_size: 20,
},
})
.then((res) => {
console.log(res);
});
在代码里import * as lark from "https://esm.sh/@larksuiteoapi/[email protected]";
执行时报错
error: Uncaught SyntaxError: The requested module '/v128/[email protected]/denonext/axios.mjs' does not provide an export named 'AxiosError'
at <anonymous> (https://esm.sh/v128/@larksuiteoapi/[email protected]/denonext/node-sdk.mjs:3:74)
好像是这个版本 axios 不支持 esm
看起来目前没有支持全量的接口,比如招聘下面只有两个:获取职位详情、获取招聘人员。
response: Response {
size: 0,
timeout: 3000,
closeSpan: [AsyncFunction: fn],
[Symbol(Body internals)]: { body: [PassThrough], disturbed: false, error: null },
[Symbol(Response internals)]: {
url: 'https://fsopen.bytedance.net/open-apis/im/v1/messages?receive_id_type=user_id',
status: 400,
statusText: 'Bad Request',
headers: [Headers],
counter: 0
}
}
我查阅了飞书开发者文档和README,但不清楚如何获取接口。业务域.资源.方法,有与飞书文档的对应关系吗?例如发送消息接口。
初学者,想请通过这个项目学习typescript. 请问如何入手?
VS Code 打开了,却不知如何下手。还请不吝赐教!
使用下面api上传图片
larkClient.im.image.create({ data: { image_type: 'message', image: fs.readFileSync(path) }, })
图片大小1.5M,header信息如下:
'POST /open-apis/im/v1/images HTTP/1.1\r\n' +
'Accept: application/json, text/plain, /\r\n' +
'content-type: multipart/form-data; boundary=--------------------------547342431807760474424597\r\n' +
'Authorization: Bearer \r\n' +
'User-Agent: oapi-node-sdk/1.0.0\r\n' +
'Host: open.feishu.cn\r\n'
同一个图片作为file上传能够成功
只有drive.file.bitable_field_changed_v1
,没有drive.file.bitable_record_changed_v1
以前的 SDK 封装了 app_access_token、tenant_access_token 的获取,这个 SDK 是否有封装?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.