Skip to content

Commit

Permalink
build: 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
cssxsh committed Mar 18, 2023
1 parent a41a241 commit 9f4b5be
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 17 deletions.
Binary file added .github/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@
[![maven-central](https://img.shields.io/maven-central/v/xyz.cssxsh.mirai/mirai-new-bing)](https://search.maven.org/artifact/xyz.cssxsh.mirai/mirai-new-bing)
[![test](https://github.com/cssxsh/mirai-new-bing/actions/workflows/test.yml/badge.svg)](https://github.com/cssxsh/mirai-new-bing/actions/workflows/test.yml)

由于微软还未在中国大陆开放 `new bing` 的使用,以国内IP去访问 `bing` 会导致跳转 `404` 而无法使用
故需要配置代理 `proxy`

## 效果

![example](.github/screenshot.png)

## 配置

`bing.yml` 基本配置

* `proxy` 代理, 协议支持 `socks``http`, 例如 `socks://127.0.0.1:7890`
* `timeout` API超时时间
* `cookie` New Bing 网页 Cookie
* `chat_prefix` 触发前缀, 默认 `bing`
* `show_source_attributions` 输出来源信息, 默认 `true`

## 安装

### MCL 指令安装
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/xyz/cssxsh/bing/NewBingChat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public data class NewBingChat(
val conversationId: String = "",
@SerialName("conversationSignature")
val conversationSignature: String = "",
@SerialName("uuid")
val uuid: String = "",
@SerialName("index")
var index: Int
)
15 changes: 9 additions & 6 deletions src/main/kotlin/xyz/cssxsh/bing/NewBingClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ public open class NewBingClient(@PublishedApi internal val config: NewBingConfig
}
}
}
protected open val format: Json = Json
protected open val format: Json = Json {
ignoreUnknownKeys = true
}
protected val shared: MutableSharedFlow<Pair<String, JsonObject>> = MutableSharedFlow()
@PublishedApi internal val uuid: UUID = UUID.randomUUID()
@PublishedApi internal val logger: Logger = LoggerFactory.getLogger(this::class.java)

public open suspend fun create(): NewBingChat {
val uuid: UUID = UUID.randomUUID()
val response = http.get("https://www.bing.com/turing/conversation/create") {
header("x-ms-client-request-id", uuid)
header("x-ms-useragent", config.device)
Expand All @@ -72,10 +74,13 @@ public open class NewBingClient(@PublishedApi internal val config: NewBingConfig
conversation.result.message ?: conversation.result.value
}

logger.debug(response.toString())

return NewBingChat(
clientId = conversation.clientId,
conversationId = conversation.conversationId,
conversationSignature = conversation.conversationSignature,
uuid = uuid.toString(),
index = 0
)
}
Expand All @@ -102,7 +107,7 @@ public open class NewBingClient(@PublishedApi internal val config: NewBingConfig
2 -> {
if (logger.isDebugEnabled) logger.debug(item.toString())
launch {
shared.emit(chat.clientId to item)
shared.emit(chat.uuid to item)
}
}
3 -> {
Expand Down Expand Up @@ -190,13 +195,11 @@ public open class NewBingClient(@PublishedApi internal val config: NewBingConfig
}, block)
}

public suspend fun send(chat: NewBingChat, text: String): String {
public suspend fun send(chat: NewBingChat, text: String) {
websocket {
bind(chat = chat)
message(chat = chat, text = text)
handle(chat = chat)
}

return chat.clientId
}
}
29 changes: 29 additions & 0 deletions src/main/kotlin/xyz/cssxsh/bing/NewBingMessage.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package xyz.cssxsh.bing

import kotlinx.serialization.*

@Serializable
public data class NewBingMessage(
@SerialName("author")
val author: String = "",
@SerialName("contentOrigin")
val contentOrigin: String = "",
@SerialName("createdAt")
val createdAt: String = "",
@SerialName("messageId")
val messageId: String = "",
@SerialName("offense")
val offense: String = "",
@SerialName("privacy")
val privacy: String? = null,
@SerialName("requestId")
val requestId: String = "",
@SerialName("sourceAttributions")
val sourceAttributions: List<NewBingSourceAttribution> = emptyList(),
@SerialName("text")
val text: String = "",
@SerialName("timestamp")
val timestamp: String = "",
@SerialName("messageType")
val messageType: String = "",
)
13 changes: 13 additions & 0 deletions src/main/kotlin/xyz/cssxsh/bing/NewBingSourceAttribution.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package xyz.cssxsh.bing

import kotlinx.serialization.*

@Serializable
public data class NewBingSourceAttribution(
@SerialName("providerDisplayName")
val providerDisplayName: String = "",
@SerialName("searchQuery")
val searchQuery: String = "",
@SerialName("seeMoreUrl")
val seeMoreUrl: String = ""
)
5 changes: 4 additions & 1 deletion src/main/kotlin/xyz/cssxsh/mirai/bing/MiraiNewBingConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package xyz.cssxsh.mirai.bing
import net.mamoe.mirai.console.data.*
import xyz.cssxsh.bing.*

public object MiraiNewBingConfig : ReadOnlyPluginConfig("openai"), NewBingConfig {
public object MiraiNewBingConfig : ReadOnlyPluginConfig("bing"), NewBingConfig {
@ValueName("proxy")
override val proxy: String by value("socks://127.0.0.1:7890")

Expand Down Expand Up @@ -43,4 +43,7 @@ public object MiraiNewBingConfig : ReadOnlyPluginConfig("openai"), NewBingConfig

@ValueName("chat_prefix")
public val prefix: String by value("bing")

@ValueName("show_source_attributions")
public val source: Boolean by value(true)
}
32 changes: 22 additions & 10 deletions src/main/kotlin/xyz/cssxsh/mirai/bing/MiraiNewBingListener.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import kotlinx.coroutines.*
import kotlinx.serialization.json.*
import net.mamoe.mirai.console.command.CommandSender.Companion.toCommandSender
import net.mamoe.mirai.console.permission.*
import net.mamoe.mirai.console.permission.PermissionService.Companion.hasPermission
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.event.*
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.*
import xyz.cssxsh.bing.*
import kotlin.coroutines.*
Expand All @@ -16,19 +18,27 @@ internal object MiraiNewBingListener : SimpleListenerHost() {
private val client = object : NewBingClient(config = MiraiNewBingConfig) {
init {
launch {
shared.collect { (clientId, data) ->
shared.collect { (uuid, data) ->
val item = data["item"] as? JsonObject ?: return@collect
val messages = item["messages"] as? JsonArray ?: return@collect
for (message in messages) {
message as? JsonObject ?: continue
val author = message["author"]?.jsonPrimitive?.content ?: continue
if ("bot" != author) continue
val (id, _) = chats.entries.find { it.value.clientId == clientId } ?: continue
for (element in messages) {
val message = format.decodeFromJsonElement(NewBingMessage.serializer(), element)
if ("bot" != message.author) continue
if ("InternalSearchQuery" == message.messageType) continue
val (id, _) = chats.entries.find { it.value.uuid == uuid } ?: continue
val subject = contacts[id] ?: continue
val text = message["text"]?.jsonPrimitive?.content ?: continue

launch {
subject.sendMessage(text)
subject.sendMessage(buildMessageChain {
appendLine(message.text)
if (MiraiNewBingConfig.source && message.sourceAttributions.isEmpty().not()) {
appendLine()
var index = 1
for (attribution in message.sourceAttributions) {
appendLine("[^${index++}^] ${attribution.providerDisplayName} ${attribution.seeMoreUrl}")
}
}
})
}
}
}
Expand Down Expand Up @@ -56,13 +66,15 @@ internal object MiraiNewBingListener : SimpleListenerHost() {
suspend fun MessageEvent.handle() {
val content = message.contentToString()
if (content.startsWith(MiraiNewBingConfig.prefix).not()) return
val commander = toCommandSender()
if (commander.hasPermission(chat).not()) return

val id = toCommandSender().permitteeId.asString()
val id = commander.permitteeId.asString()
val cache = chats[id] ?: client.create()
chats[id] = cache
contacts[id] = subject
launch {
client.send(cache, content.removePrefix(MiraiNewBingConfig.prefix))
client.send(chat = cache, text = content.removePrefix(MiraiNewBingConfig.prefix))
}
}
}

0 comments on commit 9f4b5be

Please sign in to comment.