Skip to content

Commit

Permalink
feat: support message card
Browse files Browse the repository at this point in the history
  • Loading branch information
mazhe-nerd committed Apr 6, 2023
1 parent 1a9bc32 commit 16aa4a5
Show file tree
Hide file tree
Showing 7 changed files with 341 additions and 2 deletions.
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,74 @@ const res = await client. request({
params: {},
});
````
#### Message Card
When sending [message card](https://open.feishu.cn/document/ukTMukTMukTM/uczM3QjL3MzN04yNzcDN), it will first be in the [message card builder](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/message-card-builder) to build a message card template, get the generated template json, replace the content-related parts with data, and use the result as a parameter to support the message card api. Such as sending a simple message card with `title` and `content`:
```typescript
client.im.message.create({
params: {
receive_id_type: 'chat_id',
},
data: {
receive_id: 'your receive_id',
content: JSON.stringify({
"config": {
"wide_screen_mode": true
},
"elements": [
{
"tag": "markdown",
"content": "Card Content"
}
],
"header": {
"template": "blue",
"title": {
"content": "Card Title",
"tag": "plain_text"
}
}
}
),
msg_type: 'interactive'
}
})
```
![](doc/msg-card.png)
There will be a problem: **If the content of the message card is relatively rich, the generated template json is relatively large, and there will be more content that needs to be filled with data, and manual maintenance is more cumbersome**. To solve this problem, The Open-Platform provides the ability of [Template Message](https://open.feishu.cn/document/tools-and-resources/message-card-builder#3e1f2c7c).When sending a message card, you only need to provide the template id and the data content of the template. The sdk encapsulates this ability in terms of calling, and the interface that supports message cards will synchronously add a ByCard calling method, only need to pass `template_id` and `template_variable`. The above call can be rewritten as:
```typescript
client.im.message.createByCard({
params: {
receive_id_type: 'chat_id',
},
data: {
receive_id: 'your receive_id',
template_id: 'your template_id',
template_variable: {
content: "Card Content",
title: "Card Title"
}
}
});
```
If you want to quickly experience Message Card, you can use a basic card built into the sdk:
```typescript
import * as lark from '@larksuiteoapi/node-sdk';

client.im.message.create({
params: {
receive_id_type: 'chat_id',
},
data: {
receive_id: 'your receive_id',
content: lark.messageCard.defaultCard({
title: 'Card Title',
content: 'Card Content'
}),
msg_type: 'interactive'
}
})
```
![](doc/msg-card.png)
#### Configure request options
If you want to modify the parameters of the request during the API call, such as carrying some headers, custom tenantToken, etc., you can use the second parameter of the request method to modify:
Expand Down
69 changes: 69 additions & 0 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,75 @@ const res = await client.request({
params: {},
});
```
#### 消息卡片
在发送[消息卡片](https://open.feishu.cn/document/ukTMukTMukTM/uczM3QjL3MzN04yNzcDN)信息时,会先在[消息卡片搭建工具](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/message-card-builder)中搭建出消息卡片的模版,拿到生成的模版json,用数据替换其中内容相关的部分,将结果作为支持消息卡片api的参数来使用。如发送一个简单的具有`title``content`的消息卡片:
```typescript
client.im.message.create({
params: {
receive_id_type: 'chat_id',
},
data: {
receive_id: 'your receive_id',
content: JSON.stringify({
"config": {
"wide_screen_mode": true
},
"elements": [
{
"tag": "markdown",
"content": "Card Content"
}
],
"header": {
"template": "blue",
"title": {
"content": "Card Title",
"tag": "plain_text"
}
}
}
),
msg_type: 'interactive'
}
})
```
![](doc/msg-card.png)
这样使用会有一个问题:**如果消息卡片内容比较丰富,生成的模版json比较大,与之相关需要数据填充的内容部分也会比较多,手动维护比较繁琐**。针对这个问题,开放平台提供了[模版消息](https://open.feishu.cn/document/tools-and-resources/message-card-builder#3e1f2c7c)的能力,发送消息卡片时只需要提供模版id和模版的数据内容即可。sdk对这个能力进行了调用上的封装,支持消息卡片的接口会同步的增加一个ByCard的调用方式,只需要传递`template_id``template_variable`即可。如上面的调用可以改写成:
```typescript
client.im.message.createByCard({
params: {
receive_id_type: 'chat_id',
},
data: {
receive_id: 'your receive_id',
template_id: 'your template_id',
template_variable: {
content: "Card Content",
title: "Card Title"
}
}
});
```
如果想要快速体验消息卡片,可以使用sdk中内置的一个基础卡片:
```typescript
import * as lark from '@larksuiteoapi/node-sdk';

client.im.message.create({
params: {
receive_id_type: 'chat_id',
},
data: {
receive_id: 'your receive_id',
content: lark.messageCard.defaultCard({
title: 'Card Title',
content: 'Card Content'
}),
msg_type: 'interactive'
}
})
```
效果同上:
![](doc/msg-card.png)

#### 配置请求选项
如果想在api调用过程中修改请求的参数,如携带一些header,自定义tenantToken等,则可以使用请求方法的第二个参数来进行修改:
Expand Down
176 changes: 176 additions & 0 deletions code-gen/client-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59961,6 +59961,182 @@ export default abstract class Client {
throw e;
});
},
/**
* {@link https://open.feishu.cn/api-explorer?project=im&resource=message&apiName=create&version=v1 click to debug }
*
* {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create document }
*
* 通过模版消息卡片发送消息
*
* 注意事项:;- 需要开启[机器人能力](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-enable-bot-ability) ;- 给用户发送消息,需要机器人对用户有[可用性](https://open.feishu.cn/document/home/introduction-to-scope-and-authorization/availability);- 给群组发送消息,需要机器人在群组中
*/
createByCard: async (
payload?: {
data: {
receive_id: string;
uuid?: string;
template_id: string;
template_variable?: Record<string, any>;
};
params: {
receive_id_type:
| "open_id"
| "user_id"
| "union_id"
| "email"
| "chat_id";
};
},
options?: IRequestOptions
) => {
const { headers, params, data, path } =
await this.formatPayload(payload, options);

const { template_id, template_variable, ...rest } = data;
const targetData = {
msg_type: "interactive",
content: JSON.stringify({
type: "template",
data: {
template_id: template_id,
template_variable: template_variable,
},
}),
...rest,
};

return this.httpInstance
.request<
any,
{
code?: number;
msg?: string;
data?: {
message_id?: string;
root_id?: string;
parent_id?: string;
msg_type?: string;
create_time?: string;
update_time?: string;
deleted?: boolean;
updated?: boolean;
chat_id?: string;
sender?: {
id: string;
id_type: string;
sender_type: string;
tenant_key?: string;
};
body?: { content: string };
mentions?: Array<{
key: string;
id: string;
id_type: string;
name: string;
tenant_key?: string;
}>;
upper_message_id?: string;
};
}
>({
url: fillApiPath(
`${this.domain}/open-apis/im/v1/messages`,
path
),
method: "POST",
data: targetData,
params,
headers,
})
.catch((e) => {
this.logger.error(formatErrors(e));
throw e;
});
},
/**
* {@link https://open.feishu.cn/api-explorer?project=im&resource=message&apiName=reply&version=v1 click to debug }
*
* {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/reply document }
*
* 通过模版消息卡片回复消息
*
* 注意事项:;- 需要开启[机器人能力](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-enable-bot-ability) ;- 回复私聊消息,需要机器人对用户有[可用性](https://open.feishu.cn/document/home/introduction-to-scope-and-authorization/availability);- 回复群组消息,需要机器人在群中
*/
replyByCard: async (
payload?: {
data: {
uuid?: string;
template_id: string;
template_variable?: Record<string, any>;
};
path: { message_id: string };
},
options?: IRequestOptions
) => {
const { headers, params, data, path } =
await this.formatPayload(payload, options);

const { template_id, template_variable, ...rest } = data;
const targetData = {
msg_type: "interactive",
content: JSON.stringify({
type: "template",
data: {
template_id: template_id,
template_variable: template_variable,
},
}),
...rest,
};

return this.httpInstance
.request<
any,
{
code?: number;
msg?: string;
data?: {
message_id?: string;
root_id?: string;
parent_id?: string;
msg_type?: string;
create_time?: string;
update_time?: string;
deleted?: boolean;
updated?: boolean;
chat_id?: string;
sender?: {
id: string;
id_type: string;
sender_type: string;
tenant_key?: string;
};
body?: { content: string };
mentions?: Array<{
key: string;
id: string;
id_type: string;
name: string;
tenant_key?: string;
}>;
upper_message_id?: string;
};
}
>({
url: fillApiPath(
`${this.domain}/open-apis/im/v1/messages/:message_id/reply`,
path
),
method: "POST",
data: targetData,
params,
headers,
})
.catch((e) => {
this.logger.error(formatErrors(e));
throw e;
});
},
},
/**
* 消息 - 表情回复
Expand Down
Binary file added doc/msg-card.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export { IHandles as EventHandles } from './code-gen/events-template';
export { AESCipher } from './utils/aes-cipher';
// default http client & types
export { default as defaultHttpInstance } from './http';
export { HttpInstance, HttpRequestOptions } from './typings/http';
export { HttpInstance, HttpRequestOptions } from './typings/http';
export * as messageCard from './utils/message-card';
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@larksuiteoapi/node-sdk",
"version": "1.14.0",
"version": "1.15.0",
"description": "larksuite open sdk for nodejs",
"keywords": [
"feishu",
Expand Down
25 changes: 25 additions & 0 deletions utils/message-card.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const defaultCard = (variables: {
title: string;
content: string;
}) => {
const { title, content } = variables;

return JSON.stringify({
"config": {
"wide_screen_mode": true
},
"elements": [
{
"tag": "markdown",
"content": content
}
],
"header": {
"template": "blue",
"title": {
"content": title,
"tag": "plain_text"
}
}
})
}

0 comments on commit 16aa4a5

Please sign in to comment.