gm-mcp 1.0.10 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/helpers/search-like.d.ts +1 -0
- package/dist/helpers/search-like.js +40 -0
- package/dist/index.js +12 -0
- package/dist/services/constants/report-columns.d.ts +150 -0
- package/dist/services/constants/report-columns.js +963 -0
- package/dist/services/lark-base.service.d.ts +5 -0
- package/dist/services/lark-base.service.js +33 -0
- package/dist/services/lark.service.d.ts +37 -0
- package/dist/services/lark.service.js +33 -3
- package/dist/services/types/lark.type.d.ts +4 -0
- package/dist/services/types/lark.type.js +2 -0
- package/dist/test.js +30 -1
- package/dist/tools/lark-tool.d.ts +6 -0
- package/dist/tools/lark-tool.js +62 -0
- package/package.json +1 -1
- package/src/helpers/search-like.ts +39 -0
- package/src/index.ts +18 -0
- package/src/services/constants/report-columns.ts +962 -0
- package/src/services/lark-base.service.ts +18 -0
- package/src/services/lark.service.ts +34 -3
- package/src/services/types/lark.type.ts +4 -0
- package/src/test.ts +39 -1
- package/src/tools/lark-tool.ts +60 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { LarkRecord } from "./types/lark.type";
|
|
3
|
+
import { getLarkTenantAccessToken } from "./lark.service";
|
|
4
|
+
|
|
5
|
+
export async function fetchReportRecords(p: { view_id: string; field_names: string[] }) {
|
|
6
|
+
const access_token = await getLarkTenantAccessToken();
|
|
7
|
+
const appToken = "V5akbIXqfaBvXqs8twfl6rALgLd";
|
|
8
|
+
const tableId = "tblQGKjGd8MnK5qs";
|
|
9
|
+
const url = `https://open.larksuite.com/open-apis/bitable/v1/apps/${appToken}/tables/${tableId}/records/search`;
|
|
10
|
+
return axios
|
|
11
|
+
.post<{ data: { items: LarkRecord[] } }>(url, p, {
|
|
12
|
+
params: { page_size: 500 },
|
|
13
|
+
headers: {
|
|
14
|
+
Authorization: "Bearer " + access_token,
|
|
15
|
+
},
|
|
16
|
+
})
|
|
17
|
+
.then((res) => res.data.data.items);
|
|
18
|
+
}
|
|
@@ -7,13 +7,15 @@ import { getEnv } from "../env";
|
|
|
7
7
|
// const LARK_X3_GROUP_ID = 'oc_bb4e5b8dd8ada38127c790fa368c02b9';
|
|
8
8
|
// Group dan choi front end
|
|
9
9
|
|
|
10
|
+
const DEBT_COLLECTION_CARD_ID = "ctp_AAXr3Fr7xcjr";
|
|
11
|
+
|
|
10
12
|
const larkClient = new lark.Client({
|
|
11
13
|
appId: getEnv().LARK_APP_ID,
|
|
12
14
|
appSecret: getEnv().LARK_APP_SECRET,
|
|
13
15
|
disableTokenCache: true,
|
|
14
16
|
});
|
|
15
17
|
|
|
16
|
-
async function
|
|
18
|
+
export async function getLarkTenantAccessToken() {
|
|
17
19
|
const url = "https://open.larksuite.com/open-apis/auth/v3/tenant_access_token/internal";
|
|
18
20
|
return axios
|
|
19
21
|
.post<{
|
|
@@ -68,7 +70,7 @@ async function getAccessToken() {
|
|
|
68
70
|
|
|
69
71
|
// Split later
|
|
70
72
|
export async function sendStatisticX3Message(data: { date: string; content: string }) {
|
|
71
|
-
const access_token = await
|
|
73
|
+
const access_token = await getLarkTenantAccessToken();
|
|
72
74
|
const { date, content } = data;
|
|
73
75
|
const messageContent = {
|
|
74
76
|
type: "template",
|
|
@@ -96,9 +98,38 @@ export async function sendStatisticX3Message(data: { date: string; content: stri
|
|
|
96
98
|
);
|
|
97
99
|
}
|
|
98
100
|
|
|
101
|
+
export async function sendReportOpsGroup(data: { title: string; message_content: string }) {
|
|
102
|
+
const access_token = await getLarkTenantAccessToken();
|
|
103
|
+
const { title, message_content } = data;
|
|
104
|
+
const messageContent = {
|
|
105
|
+
type: "template",
|
|
106
|
+
data: {
|
|
107
|
+
template_id: getEnv().LARK_X3_TEMPLATE_ID,
|
|
108
|
+
// template_id: 'ctp_AAdI5Sp48YUT',
|
|
109
|
+
template_variable: {
|
|
110
|
+
title,
|
|
111
|
+
message_content,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
return larkClient.im.message.create(
|
|
116
|
+
{
|
|
117
|
+
params: {
|
|
118
|
+
receive_id_type: "chat_id",
|
|
119
|
+
},
|
|
120
|
+
data: {
|
|
121
|
+
receive_id: getEnv().LARK_X3_GROUP_ID,
|
|
122
|
+
msg_type: "interactive",
|
|
123
|
+
content: JSON.stringify(messageContent),
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
lark.withTenantToken(access_token)
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
99
130
|
export async function sendLarkTextMessage(p: { message_content: { text: string }; receive_id: string }) {
|
|
100
131
|
const { message_content, receive_id } = p;
|
|
101
|
-
const access_token = await
|
|
132
|
+
const access_token = await getLarkTenantAccessToken();
|
|
102
133
|
return larkClient.im.message.create(
|
|
103
134
|
{
|
|
104
135
|
params: {
|
package/src/test.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { ensureEnvVariables, getEnv } from "./env";
|
|
2
|
+
import { searchLike } from "./helpers/search-like";
|
|
3
|
+
import { REPORT_COLUMS } from "./services/constants/report-columns";
|
|
4
|
+
import { fetchReportRecords } from "./services/lark-base.service";
|
|
2
5
|
import { sendLarkTextMessage, sendMessageToX3Group } from "./services/lark.service";
|
|
3
6
|
import {
|
|
4
7
|
statisticX3RangeTool,
|
|
@@ -7,10 +10,45 @@ import {
|
|
|
7
10
|
statisticX3WeekTool,
|
|
8
11
|
statisticX3YesterdayTool,
|
|
9
12
|
} from "./tools";
|
|
13
|
+
import { debtCollectionRateTool } from "./tools/lark-tool";
|
|
10
14
|
|
|
11
15
|
async function setupTest() {
|
|
12
16
|
ensureEnvVariables();
|
|
13
|
-
const
|
|
17
|
+
const compnay = "BGG";
|
|
18
|
+
const month = "12/2025";
|
|
19
|
+
const res = await debtCollectionRateTool({ sendMessageToLark: false, companyName: compnay, monthDate: month });
|
|
20
|
+
console.log(res);
|
|
21
|
+
|
|
22
|
+
// const fieldNames = REPORT_COLUMS.map((item) => item.field_name);
|
|
23
|
+
// try {
|
|
24
|
+
// const records = await fetchReportRecords({ view_id: "vewI23hNnx", field_names: fieldNames });
|
|
25
|
+
// // console.log(records);
|
|
26
|
+
|
|
27
|
+
// // Find by name first
|
|
28
|
+
// const companyNames = records.map((item) => (item.fields["CÔNG TY"] || "") as string);
|
|
29
|
+
// // console.log(companyNames);
|
|
30
|
+
// const searchTems = "DENKO";
|
|
31
|
+
// const monthTerm = "12";
|
|
32
|
+
// const foundName = searchLike(searchTems, companyNames)[0];
|
|
33
|
+
// const companiesMatchName = records.filter((item) => item.fields["CÔNG TY"] === foundName);
|
|
34
|
+
// // console.log(companiesMatchName);
|
|
35
|
+
|
|
36
|
+
// // Find by pay period
|
|
37
|
+
// const foundMonth = searchLike(
|
|
38
|
+
// monthTerm,
|
|
39
|
+
// companiesMatchName.map((item) => item.fields["KỲ LƯƠNG"])
|
|
40
|
+
// )[0];
|
|
41
|
+
// console.log(foundMonth);
|
|
42
|
+
|
|
43
|
+
// const finalCompnay = companiesMatchName.find((item) => item.fields["KỲ LƯƠNG"] === foundMonth);
|
|
44
|
+
// console.log(finalCompnay);
|
|
45
|
+
|
|
46
|
+
// // console.log(companyCandidates);
|
|
47
|
+
// } catch (e) {
|
|
48
|
+
// console.log(e);
|
|
49
|
+
// }
|
|
50
|
+
|
|
51
|
+
// const sendMessageToLark = getEnv().SEND_MESSAGE_TO_LARK;
|
|
14
52
|
|
|
15
53
|
// const reuslt = await statisticX3TodayTool({ sendMessageToLark: false });
|
|
16
54
|
// console.log(reuslt);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types";
|
|
2
|
+
import { extractMonth } from "../helpers";
|
|
3
|
+
import { searchLike } from "../helpers/search-like";
|
|
4
|
+
import { REPORT_COLUMS } from "../services/constants/report-columns";
|
|
5
|
+
import { fetchReportRecords } from "../services/lark-base.service";
|
|
6
|
+
import { sendReportOpsGroup } from "../services/lark.service";
|
|
7
|
+
|
|
8
|
+
const companyKey = "CÔNG TY";
|
|
9
|
+
const preiodKey = "KỲ LƯƠNG";
|
|
10
|
+
const debtCollectionRateKey = "TỈ LỆ THU NỢ";
|
|
11
|
+
|
|
12
|
+
export async function debtCollectionRateTool(options: {
|
|
13
|
+
sendMessageToLark: boolean;
|
|
14
|
+
companyName: string;
|
|
15
|
+
monthDate: string;
|
|
16
|
+
}): Promise<CallToolResult> {
|
|
17
|
+
const { sendMessageToLark, companyName, monthDate } = options;
|
|
18
|
+
const monthParts = extractMonth(monthDate);
|
|
19
|
+
if (monthParts === null) {
|
|
20
|
+
return { content: [{ type: "text", text: `${monthDate} is invalid` }] };
|
|
21
|
+
}
|
|
22
|
+
const { month, year } = monthParts;
|
|
23
|
+
const fieldNames = REPORT_COLUMS.map((item) => item.field_name);
|
|
24
|
+
try {
|
|
25
|
+
const records = await fetchReportRecords({ view_id: "vewI23hNnx", field_names: fieldNames });
|
|
26
|
+
// console.log(records);
|
|
27
|
+
|
|
28
|
+
// Find by name first
|
|
29
|
+
const companyNames = records.map((item) => (item.fields["CÔNG TY"] || "") as string);
|
|
30
|
+
// console.log(companyNames);
|
|
31
|
+
// const searchTems = "DENKO";
|
|
32
|
+
// const monthTerm = "12";
|
|
33
|
+
const foundName = searchLike(companyName, companyNames)[0];
|
|
34
|
+
const companiesMatchName = records.filter((item) => item.fields["CÔNG TY"] === foundName);
|
|
35
|
+
// console.log(companiesMatchName);
|
|
36
|
+
|
|
37
|
+
// Find by pay period
|
|
38
|
+
const foundMonth = searchLike(
|
|
39
|
+
month.toString(),
|
|
40
|
+
companiesMatchName.map((item) => item.fields["KỲ LƯƠNG"])
|
|
41
|
+
)[0];
|
|
42
|
+
console.log(foundMonth);
|
|
43
|
+
const finalCompnay = companiesMatchName.find((item) => item.fields["KỲ LƯƠNG"] === foundMonth);
|
|
44
|
+
|
|
45
|
+
if (sendMessageToLark) {
|
|
46
|
+
await sendReportOpsGroup({
|
|
47
|
+
title: "Tỉ lệ thu nợ",
|
|
48
|
+
message_content: [
|
|
49
|
+
`Công ty: ${finalCompnay?.fields[companyKey] || "N/A"}`,
|
|
50
|
+
`Kỳ lương: ${finalCompnay?.fields[preiodKey] || "N/A"}`,
|
|
51
|
+
`Tỷ lệ thu nợ: ${Number(finalCompnay?.fields[debtCollectionRateKey]) * 100}%`,
|
|
52
|
+
].join("<hr>"),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return { content: [{ type: "text", text: JSON.stringify(finalCompnay) }] };
|
|
56
|
+
// console.log(finalCompnay);
|
|
57
|
+
} catch (e) {
|
|
58
|
+
return { content: [{ type: "text", text: JSON.stringify(e) }] };
|
|
59
|
+
}
|
|
60
|
+
}
|