Skip to content
This repository has been archived by the owner on Jan 8, 2023. It is now read-only.

Commit

Permalink
fix: 优化代码逻辑和冗余,增加自定义回复( #5 )的可用情况
Browse files Browse the repository at this point in the history
  • Loading branch information
Nambers committed Jan 30, 2022
1 parent 555d68e commit 599c4a9
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 104 deletions.
6 changes: 3 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 - 2021. Eritque arcus and contributors.
* Copyright (c) 2020 - 2022. Eritque arcus and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
Expand All @@ -23,7 +23,7 @@ plugins {
}

group = "tech.eritquearcus"
version = "1.5.0"
version = "1.6.0"

repositories {
mavenLocal()
Expand All @@ -33,7 +33,7 @@ repositories {
}
dependencies {
// https://mvnrepository.com/artifact/org.json/json
implementation("org.json:json:20210307")
implementation("org.json:json:20211205")
implementation("com.google.code.gson:gson:2.8.9")

}
24 changes: 22 additions & 2 deletions src/main/kotlin/Config.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2021 Eritque arcus and contributors.
* Copyright (C) 2021-2022 Eritque arcus and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
Expand Down Expand Up @@ -46,4 +46,24 @@ data class TulingRequest(
val userId: String,
val userIdName: String
)
}
}

internal val errCode = mapOf(
"5000" to "无解析结果",
"6000" to "暂不支持该功能",
"4000" to "请求参数格式错误",
"4001" to "加密方式错误",
"4002" to "无功能权限",
"4003" to "该apikey没有可用请求次数",
"4005" to "无功能权限",
"4007" to "apikey不合法",
"4100" to "userid获取失败",
"4200" to "上传格式错误",
"4300" to "批量操作超过限制",
"4400" to "没有上传合法userid",
"4500" to "userid申请个数超过限制",
"4600" to "输入内容为空",
"4602" to "输入文本内容超长(上限150)",
"7002" to "上传信息失败",
"8008" to "服务器错误"
)
156 changes: 61 additions & 95 deletions src/main/kotlin/PluginMain.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2021 Eritque arcus and contributors.
* Copyright (C) 2021-2022 Eritque arcus and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
Expand All @@ -23,6 +23,7 @@ import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.event.events.FriendMessageEvent
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.event.events.MessageEvent
import net.mamoe.mirai.event.globalEventChannel
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.data.Image.Key.queryUrl
Expand All @@ -40,29 +41,26 @@ import java.nio.charset.StandardCharsets

object PluginMain : KotlinPlugin(
JvmPluginDescription(
id = "tech.eritquearcus.TuLingBot",
name = "TuLingBot",
version = "1.5.0"
id = "tech.eritquearcus.TuLingBot", name = "TuLingBot", version = "1.6.0"
)
) {
private fun TulingRequest.Perception.toRequest(uinfo: TulingRequest.UserInfo): TulingRequest =
TulingRequest(
this,
when {
private fun TulingRequest.Perception?.toRequest(uinfo: TulingRequest.UserInfo): TulingRequest? =
if (this == null) null
else TulingRequest(
this, when {
this.inputText != null -> 0
this.inputImage != null -> 1
this.inputMedia != null -> 2
else -> throw IllegalArgumentException("")
else -> throw IllegalArgumentException("Unreachable")
}, uinfo
)

private suspend fun SingleMessage.toRequest(uinfo: TulingRequest.UserInfo): TulingRequest =
when (this) {
is PlainText -> TulingRequest.Perception(inputText = TulingRequest.Perception.InputText(this.content))
is Image -> TulingRequest.Perception(inputImage = TulingRequest.Perception.InputImage(this.queryUrl()))
is OnlineAudio -> TulingRequest.Perception(inputMedia = TulingRequest.Perception.InputMedia(this.urlForDownload))
else -> throw IllegalArgumentException("")
}.toRequest(uinfo)
private suspend fun SingleMessage.toRequest(uinfo: TulingRequest.UserInfo): TulingRequest? = when (this) {
is PlainText -> TulingRequest.Perception(inputText = TulingRequest.Perception.InputText(this.content))
is Image -> TulingRequest.Perception(inputImage = TulingRequest.Perception.InputImage(this.queryUrl()))
is OnlineAudio -> TulingRequest.Perception(inputMedia = TulingRequest.Perception.InputMedia(this.urlForDownload))
else -> null
}.toRequest(uinfo)

private fun sendJson(out: String, debug: Boolean?): String {
val url = URL("http://openapi.tuling123.com/openapi/api/v2")
Expand All @@ -73,99 +71,67 @@ object PluginMain : KotlinPlugin(
http.setRequestProperty("Accept", "application/json")
http.doOutput = true
http.connect()
if (debug == true)
logger.info("图灵发送:\n$out")
if (debug == true) logger.info("图灵发送:\n$out")
http.outputStream.use { os -> os.write(out.encodeToByteArray()) }
val re = InputStreamReader(http.inputStream, StandardCharsets.UTF_8).readText()
if (debug == true)
logger.info("图灵返回:\n$re")
if (debug == true) logger.info("图灵返回:\n$re")
return re
}

private fun MessageChain.containKey(l: List<String>, bot: Bot): List<SingleMessage> {
l.forEach {
if (it == "@bot" && this.contains(At(bot)))
return this.toMutableList().apply {
this.remove(At(bot))
this.removeAt(0)
}
else if (this.contentToString().startsWith(it))
return this.toMutableList().apply {
this.removeAt(0)
this[0] = PlainText(this[0].contentToString().replace(it, ""))
}
if (it == "@bot" && this.contains(At(bot))) return this.toMutableList().apply {
this.remove(At(bot))
this.removeAt(0)
}
else if (this.contentToString().startsWith(it)) return this.toMutableList().apply {
this.removeAt(0)
this[0] = PlainText(this[0].contentToString().replace(it, ""))
}
}
return emptyList()
}

override fun onEnable() {
TuringConfig.reload()
if(apikey.isEmpty())
logger.warning("未填写apikey,请到${configFolder.absolutePath}/config.yml文件下填写")
globalEventChannel().filter{ apikey.isNotEmpty() }.subscribeAlways<GroupMessageEvent> {
//群消息
val uinfo = TulingRequest.UserInfo(
apikey,
this.group.id.toString(),
this.sender.id.toString(),
this.senderName
)
var reS = ""
(if (groupKeyword.isEmpty())
this.message.toList()
else
this.message.containKey(groupKeyword, this.bot).let {
if (it.isEmpty())
return@subscribeAlways
else
return@let it
private suspend fun MessageEvent.getResult(keyWords: List<String>) {
var reS = ""
val uinfo = TulingRequest.UserInfo(
apikey, null, this.sender.id.toString(), this.sender.nick
)
run out@{
(if (groupKeyword.isEmpty()) this.message.toList()
else this.message.containKey(keyWords, this.bot).let {
if (it.isEmpty()) return
else return@let it
}).forEach {
if (it.content.isBlank() || it.content.isEmpty()) return@forEach
val text = Gson().toJson(it.toRequest(uinfo).apply {
if (this == null) {
logger.warning("遇到不能处理的消息类型: ${it.javaClass.name}")
return@forEach // equal to `continue`
}
})
.forEach {
if (it.content.isBlank() || it.content.isEmpty())
return@forEach
val text = Gson().toJson(it.toRequest(uinfo))
val j = sendJson(text, debug)
val code = JSONObject(j).getJSONObject("intent").getInt("code")
reS += if(overLimitReply.isNotEmpty() && code == 4003)
overLimitReply.random()
else
(JSONObject(j).getJSONArray("results")[0] as JSONObject).getJSONObject("values")
.getString("text")
}
this.group.sendMessage(At(this.sender) + reS)
val j = sendJson(text, debug)
val code = JSONObject(j).getJSONObject("intent").getInt("code")
if (code != 0) {
logger.error("图灵服务返回异常: code: $code, msg: ${errCode.getOrDefault(code.toString(), "未知异常")}")
reS = if (overLimitReply.isNotEmpty()) overLimitReply.random()
else errCode.getOrDefault(code.toString(), "未知异常")
return@out // equal to `break`
} else (JSONObject(j).getJSONArray("results")[0] as JSONObject).getJSONObject("values")
.getString("text")
}
}
this.subject.sendMessage((if (this is GroupMessageEvent) At(this.sender) else PlainText("")) + reS.trim())
}

globalEventChannel().filter{ apikey.isNotEmpty() }.subscribeAlways<FriendMessageEvent> {
val uinfo = TulingRequest.UserInfo(
apikey,
null,
this.sender.id.toString(),
this.sender.nick
)
var reS = ""
(if (friendKeyword.isEmpty())
this.message.toList()
else
this.message.containKey(friendKeyword, this.bot).let {
if (it.isEmpty())
return@subscribeAlways
else
return@let it
})
.forEach {
if (it.content.isBlank() || it.content.isEmpty())
return@forEach
val text = Gson().toJson(it.toRequest(uinfo))
val j = sendJson(text, debug)

val code = JSONObject(j).getJSONObject("intent").getInt("code")
reS += if(overLimitReply.isNotEmpty() && code == 4003)
overLimitReply.random()
else
(JSONObject(j).getJSONArray("results")[0] as JSONObject).getJSONObject("values")
.getString("text")
}
this.sender.sendMessage(reS.trim())
override fun onEnable() {
TuringConfig.reload()
if (apikey.isEmpty()) logger.warning("未填写apikey,请到${configFolder.absolutePath}/config.yml文件下填写")
globalEventChannel().filter { apikey.isNotEmpty() }.subscribeAlways<GroupMessageEvent> {
this.getResult(groupKeyword)
}
globalEventChannel().filter { apikey.isNotEmpty() }.subscribeAlways<FriendMessageEvent> {
this.getResult(friendKeyword)
}
}
}
25 changes: 21 additions & 4 deletions src/main/kotlin/TuringConfig.kt
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
/*
* Copyright (C) 2021-2022 Eritque arcus and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version(in your opinion).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package tech.eritquearcus.tuling

import net.mamoe.mirai.console.data.AutoSavePluginConfig
import net.mamoe.mirai.console.data.ValueDescription
import net.mamoe.mirai.console.data.value

object TuringConfig:AutoSavePluginConfig("config") {
@ValueDescription("图灵机器人密钥")
@ValueDescription("图灵机器人Apikey")
val apikey:String by value()

@ValueDescription("唤起关键词(群组)")
@ValueDescription("唤起关键词(群组)")
val groupKeyword:List<String> by value()

@ValueDescription("唤起关键词(私聊)")
@ValueDescription("唤起关键词(私聊)")
val friendKeyword:List<String> by value()

@ValueDescription("是否输出debug信息")
val debug:Boolean by value(false)

@ValueDescription("请求次数超限后的自定义回复")
@ValueDescription("图灵服务不可用时的自定义回复")
val overLimitReply:List<String> by value()
}

0 comments on commit 599c4a9

Please sign in to comment.