feat: 支持claude单人对话;注意:需要重新设置slack权限和配置插件

This commit is contained in:
ikechan8370 2023-04-16 19:12:56 +08:00
parent 3dee3ccec7
commit c1599e4f34
4 changed files with 115 additions and 33 deletions

View file

@ -216,7 +216,8 @@ export class chatgpt extends plugin {
// slackChannelId: Config.slackChannelId
// })
// await client.endConversation()
await e.reply('由于Slack官方限制结束Claude对话请前往网站或客户端执行/reset。', true)
await redis.del(`CHATGPT:SLACK_CONVERSATION:${e.sender.user_id}`)
await e.reply('claude对话已结束')
return
}
let ats = e.message.filter(m => m.type === 'at')
@ -353,7 +354,7 @@ export class chatgpt extends plugin {
async endAllConversations (e) {
let use = await redis.get('CHATGPT:USE') || 'api'
if (use === 'claude') {
await e.reply('由于Slack官方限制结束Claude对话请前往网站或客户端执行/reset。', true)
await e.reply('claude暂不支持结束全部对话', true)
return
}
let deleted = 0
@ -1389,7 +1390,7 @@ export class chatgpt extends plugin {
slackUserToken: Config.slackUserToken,
slackChannelId: Config.slackChannelId
})
let text = await client.sendMessage(prompt)
let text = await client.sendMessage(prompt, e)
return {
text
}

View file

@ -458,9 +458,9 @@ export function supportGuoba () {
component: 'Input'
},
{
field: 'slackChannelId',
label: 'Slack私聊频道号',
bottomHelpMessage: '在Slack中与Claude机器人私聊的频道号。如果页面URL为https://app.slack.com/client/TXXXXXXXX/DXXXXXXXXX/则频道号就是DXXXXXXXXX',
field: 'slackClaudeUserId',
label: 'Slack成员id',
bottomHelpMessage: '在Slack中点击Claude头像查看详情其中的成员ID复制过来',
component: 'Input'
},
{

View file

@ -94,8 +94,9 @@ const defaultConfig = {
ttsRegex: '/匹配规则/匹配模式',
slackUserToken: '',
slackBotUserToken: '',
slackChannelId: '',
// slackChannelId: '',
slackSigningSecret: '',
slackClaudeUserId: '',
version: 'v2.5.3'
}
const _path = process.cwd()

View file

@ -29,40 +29,120 @@ export class SlackClaudeClient {
}
}
async sendMessage (prompt) {
let sendResponse = await this.app.client.chat.postMessage({
as_user: true,
text: `${prompt}`,
async sendMessage (prompt, e, t = 0) {
if (t > 10) {
return 'claude 未响应'
}
let qq = e.sender.user_id
let channels = await this.app.client.conversations.list({
token: this.config.slackUserToken,
channel: this.config.slackChannelId
types: 'public_channel,private_channel'
})
let ts = sendResponse.ts
let response = '_Typing…_'
let tryTimes = 0
while (response.trim().endsWith('_Typing…_')) {
let replies = await this.app.client.conversations.history({
let channel = channels.channels.filter(c => c.name === '' + qq)
if (!channel || channel.length === 0) {
let createChannelResponse = await this.app.client.conversations.create({
token: this.config.slackUserToken,
channel: this.config.slackChannelId,
limit: 1,
oldest: ts
name: qq + '',
is_private: true
})
if (replies.messages.length > 0 && replies.messages[0].bot_profile) {
response = replies.messages[0].text
if (Config.debug) {
let text = response.replace('_Typing…_', '')
if (text) {
logger.info(response.replace('_Typing…_', ''))
channel = createChannelResponse.channel
await this.app.client.conversations.invite({
token: this.config.slackUserToken,
channel: channel.id,
users: 'U053NDP2YRF'
})
await delay(1000)
} else {
channel = channel[0]
}
let conversationId = await redis.get(`CHATGPT:SLACK_CONVERSATION:${qq}`)
if (!conversationId) {
let sendResponse = await this.app.client.chat.postMessage({
as_user: true,
text: `<@${Config.slackClaudeUserId}> ${prompt}`,
token: this.config.slackUserToken,
channel: channel.id
})
let ts = sendResponse.ts
let response = '_Typing…_'
let tryTimes = 0
while (response.trim().endsWith('_Typing…_')) {
let replies = await this.app.client.conversations.replies({
token: this.config.slackUserToken,
channel: channel.id,
limit: 1000,
ts: ts
})
await await redis.set(`CHATGPT:SLACK_CONVERSATION:${qq}`, `${ts}`)
if (replies.messages.length > 0) {
let formalMessages = replies.messages.filter(m => m.text.indexOf('Acceptable Use Policy') === -1)
if (!formalMessages[formalMessages.length - 1].bot_profile) {
// 问题的下一句不是bot回复的这属于意料之外的问题可能是多人同时问问题导致 再问一次吧
return await this.sendMessage(prompt, e, t + 1)
}
let reply = formalMessages[formalMessages.length - 1]
if (reply.text !== `<@${Config.slackClaudeUserId}> ${prompt}`) {
response = reply.text
if (Config.debug) {
let text = response.replace('_Typing…_', '')
if (text) {
logger.info(response.replace('_Typing…_', ''))
}
}
}
}
await delay(500)
tryTimes++
if (tryTimes > 10 && response === '_Typing…_') {
// 过了5秒还没任何回复就重新发一下试试
logger.warn('claude没有响应重试中')
return await this.sendMessage(prompt, e, t + 1)
}
}
await delay(500)
tryTimes++
if (tryTimes > 10 && response === '_Typing…_') {
// 过了5秒还没任何回复就重新发一下试试
logger.warn('claude没有响应重试中')
return await this.sendMessage(prompt)
return response
} else {
await this.app.client.chat.postMessage({
as_user: true,
text: `<@${Config.slackClaudeUserId}> ${prompt}`,
token: this.config.slackUserToken,
channel: channel.id,
thread_ts: conversationId
})
let response = '_Typing…_'
let tryTimes = 0
while (response.trim().endsWith('_Typing…_')) {
let replies = await this.app.client.conversations.replies({
token: this.config.slackUserToken,
channel: channel.id,
limit: 1000,
ts: conversationId
})
if (replies.messages.length > 0) {
let formalMessages = replies.messages.filter(m => m.text.indexOf('Acceptable Use Policy') === -1)
if (!formalMessages[formalMessages.length - 1].bot_profile) {
// 问题的下一句不是bot回复的这属于意料之外的问题可能是多人同时问问题导致 再问一次吧
return await this.sendMessage(prompt, e, t + 1)
}
let reply = formalMessages[formalMessages.length - 1]
if (reply.text !== `<@${Config.slackClaudeUserId}> ${prompt}`) {
response = reply.text
if (Config.debug) {
let text = response.replace('_Typing…_', '')
if (text) {
logger.info(response.replace('_Typing…_', ''))
}
}
}
}
await delay(500)
tryTimes++
if (tryTimes > 10 && response === '_Typing…_') {
// 过了5秒还没任何回复就重新发一下试试
logger.warn('claude没有响应重试中')
return await this.sendMessage(prompt, e, t + 1)
}
}
return response
}
return response
}
}