forked from CrazyCreativeDream/Real-Coze-API
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.js
More file actions
155 lines (136 loc) · 5.74 KB
/
index.js
File metadata and controls
155 lines (136 loc) · 5.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { SocksProxyAgent } from 'socks-proxy-agent';
import Crypto from 'crypto';
import setUpDev from './src/setUpDev.js';
import CozeWebsocketGuard from './src/CozeWebsocketGuard.js';
import PostNewChat from './src/PostNewChat.js';
import TempDataGuard from './src/TempDataGuard.js';
import getUploadAuth from './src/getUploadAuth.js';
import UploadFile from './src/UploadFile.js';
const md5 = Crypto.createHash('md5');
const asleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
const GnerateUUID = () => {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == "x" ? r : (r & 3 | 8);
return v.toString(16);
});
}
function RealCozeAPI(config) {
const handleError = (err) => {
return {
success: false,
data: {},
errmsg: err
}
}
if (!config.session) return handleError("缺失session,请查看项目文档以获取更多信息")
if (!config.bot) return handleError("缺失bot配置信息,请查看项目文档以获取更多信息")
config.tmppath = config.tmppath || "./temp"
if (!!config.proxy) {
if (!config.proxy.match(/^socks/)) return handleError("代理必须为SOCKS型,使用HTTP代理会出现重复重定向问题")
config.proxy = new SocksProxyAgent(config.proxy)
} else {
config.proxy = null
}
this.BotConfig = config.bot
this.ChatHistory = JSON.parse(this.BotConfig.work_info.message_info)
delete this.BotConfig.work_info.message_info
const cookies = `sessionid=${config.session}`;
this.device_id = Math.abs(Date.now() ^ 268435456 * Math.random())
this.BotConfig.device_id = this.device_id.toString()
const temp = new TempDataGuard(config.tmppath)
this.connect = async () => {
return new Promise(async (resolve, reject) => {
this.CozePlayGroundData = temp.get('PlayGroundData');
if (!this.CozePlayGroundData) {
this.CozePlayGroundData = await setUpDev(cookies, config.proxy)
if (!this.CozePlayGroundData.success) return handleError(this.CozePlayGroundData.data.message)
temp.set('PlayGroundData', this.CozePlayGroundData);
}
this.access_key = md5.update("".concat(this.CozePlayGroundData.data.product_id).concat(this.CozePlayGroundData.data.app_key).concat(this.device_id, "f8a69f1719916z")).digest('hex');
//这是Coze混淆前端的一个签名算法
this.CozeResponse = new CozeWebsocketGuard(`${this.CozePlayGroundData.data.domain}/ws/v2?device_platform=web&version_code=10000&access_key=${this.access_key}&fpid=${this.CozePlayGroundData.data.product_id}&aid=${this.CozePlayGroundData.data.app_id}&device_id=${this.device_id}&xsack=0&xaack=0&xsqos=0&qos_sdk_version=2&language=zh-CN`)
while (!this.CozeResponse.ready) await asleep(300)
resolve({
success: true
})
})
}
this.disconnect = () => {
this.CozeResponse.close()
delete this.CozeResponse
}
this.generateChatHistory = (InputChatHistory, HistoryType, role) => {
role = role || 2
switch (HistoryType) {
case 'image':
return [{
role,
content: JSON.stringify({
image_list: [
{
key: InputChatHistory
}
]
}),
contentType: 6
}]
case 'file':
return [{
role,
content: JSON.stringify({
file_list: [
{
key: InputChatHistory
}
]
}),
contentType: 9
}]
default:
return [{
role,
content: InputChatHistory,
contentType: 1
}]
}
}
this.send = async (InputChatHistory, callback, subscribeRole) => {
subscribeRole = subscribeRole || [1]
return new Promise(async (resolve, reject) => {
const ChatUUID = GnerateUUID()
this.CozeResponse.addMessageListener(ChatUUID, (data) => {
if (subscribeRole.includes(data.reply_type)) callback({
success: true,
data
});
if (!data.continue && data.reply_type === 1) resolve(data)
})
const PostResult = await PostNewChat(
cookies,
config.proxy,
Object.assign({}, this.BotConfig, { "push_uuid": ChatUUID }),
this.ChatHistory.concat(InputChatHistory)
)
if (!PostResult.success) {
callback({
success: false,
data: {},
errmsg: PostResult
})
this.CozeResponse.removeMessageListener(ChatUUID)
reject(PostResult)
}
})
}
this.uploadFile = async (file, fileExtension) => {
let UploadAuth = temp.get('UploadAuthToken');
if (!UploadAuth || new Date(UploadAuth.data.auth.expired_time) < Date.now()) {
UploadAuth = await getUploadAuth(cookies, config.proxy)
if (!UploadAuth.success) return handleError(UploadAuth.data.message)
temp.set('UploadAuthToken', UploadAuth);
}
return UploadFile(cookies, config.proxy, file, fileExtension, UploadAuth.data)
}
}
export default RealCozeAPI