feat: add qq music api search
This commit is contained in:
9 files changed
+194
-4
No files matched your search
@@ -61,7 +61,8 @@ val DEFAULT_CONFIG = Config(
|
|||||||
admins = listOf(3458671395L),
|
admins = listOf(3458671395L),
|
||||||
enableAntiRevoke = true,
|
enableAntiRevoke = true,
|
||||||
llamaUrl = "http://127.0.0.1",
|
llamaUrl = "http://127.0.0.1",
|
||||||
llamaModel = "llama3.1"
|
llamaModel = "llama3.1",
|
||||||
|
qqMusicApiUrl = "http://127.0.0.1:3200"
|
||||||
)
|
)
|
||||||
|
|
||||||
val configManager = ConfigManager()
|
val configManager = ConfigManager()
|
||||||
@@ -101,5 +102,6 @@ val commands = listOf(
|
|||||||
NiuziBankCommand(), WithdrawCommand(),
|
NiuziBankCommand(), WithdrawCommand(),
|
||||||
BankTransferCommand(), CreateBankAccountCommand(),
|
BankTransferCommand(), CreateBankAccountCommand(),
|
||||||
BankBalanceCommand(), DepositCommand(),
|
BankBalanceCommand(), DepositCommand(),
|
||||||
DMSearchCommand(), LlamaCommand()
|
DMSearchCommand(), LlamaCommand(),
|
||||||
|
QQMusicCommand()
|
||||||
)
|
)
|
||||||
@@ -11,12 +11,20 @@ import cn.rtast.fancybot.configManager
|
|||||||
import cn.rtast.fancybot.entity.music.Search
|
import cn.rtast.fancybot.entity.music.Search
|
||||||
import cn.rtast.fancybot.entity.music.SearchedResult
|
import cn.rtast.fancybot.entity.music.SearchedResult
|
||||||
import cn.rtast.fancybot.entity.music.SongUrl
|
import cn.rtast.fancybot.entity.music.SongUrl
|
||||||
|
import cn.rtast.fancybot.entity.music.qq.CoverImage
|
||||||
|
import cn.rtast.fancybot.entity.music.qq.QMSearchResult
|
||||||
|
import cn.rtast.fancybot.entity.music.qq.QQMSearch
|
||||||
import cn.rtast.fancybot.util.Http
|
import cn.rtast.fancybot.util.Http
|
||||||
|
import cn.rtast.fancybot.util.str.encodeToBase64
|
||||||
|
import cn.rtast.fancybot.util.str.formatToMinutes
|
||||||
import cn.rtast.rob.entity.GroupMessage
|
import cn.rtast.rob.entity.GroupMessage
|
||||||
import cn.rtast.rob.enums.MusicShareType
|
import cn.rtast.rob.enums.MusicShareType
|
||||||
import cn.rtast.rob.util.BaseCommand
|
import cn.rtast.rob.util.BaseCommand
|
||||||
import cn.rtast.rob.util.ob.MessageChain
|
import cn.rtast.rob.util.ob.MessageChain
|
||||||
|
import cn.rtast.rob.util.ob.NodeMessageChain
|
||||||
import cn.rtast.rob.util.ob.OneBotListener
|
import cn.rtast.rob.util.ob.OneBotListener
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
import java.net.URI
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
class MusicCommand : BaseCommand() {
|
class MusicCommand : BaseCommand() {
|
||||||
@@ -121,7 +129,7 @@ class MusicCommand : BaseCommand() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val keyword = args.joinToString(" ")
|
val keyword = args.joinToString(" ")
|
||||||
val result = searchSong(keyword).result.songs.asSequence().first().id
|
val result = searchSong(keyword).result.songs.first().id
|
||||||
val msg = MessageChain.Builder()
|
val msg = MessageChain.Builder()
|
||||||
.addMusicShare(MusicShareType.Netease, result.toString())
|
.addMusicShare(MusicShareType.Netease, result.toString())
|
||||||
.build()
|
.build()
|
||||||
@@ -152,3 +160,93 @@ class MusicPlayUrlCommand : BaseCommand() {
|
|||||||
listener.sendGroupMessage(message.groupId, msg)
|
listener.sendGroupMessage(message.groupId, msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class QQMusicCommand : BaseCommand() {
|
||||||
|
override val commandNames = listOf("qm", "/qqm", "qqm", "/qm", "q点歌")
|
||||||
|
|
||||||
|
private val qqMusicApiUrl = configManager.qqMusicApiUrl
|
||||||
|
|
||||||
|
private val recordMap = mutableMapOf<Long, List<QMSearchResult>>()
|
||||||
|
|
||||||
|
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
message.reply("发送`/qm <关键词>`即可搜索qq音乐的音乐哦")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.recordMap.forEach { (key, results) ->
|
||||||
|
val validResults = results.filter { result ->
|
||||||
|
Instant.now().epochSecond - result.timestamp <= 30
|
||||||
|
}
|
||||||
|
if (validResults.isEmpty()) {
|
||||||
|
recordMap.remove(key)
|
||||||
|
} else {
|
||||||
|
recordMap[key] = validResults
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val method = args.first()
|
||||||
|
when (method) {
|
||||||
|
"p" -> {
|
||||||
|
try {
|
||||||
|
val index = args.last().toInt()
|
||||||
|
val result = recordMap[message.sender.userId]!![index]
|
||||||
|
val msg = MessageChain.Builder()
|
||||||
|
.addMusicShare(MusicShareType.QQ, result.id.toString())
|
||||||
|
.build()
|
||||||
|
listener.sendGroupMessage(message.groupId, msg)
|
||||||
|
} catch (_: Exception) {
|
||||||
|
message.reply("回复错误已清除本次搜索结果")
|
||||||
|
}
|
||||||
|
recordMap.remove(message.sender.userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
try {
|
||||||
|
val keyword = args.joinToString(" ")
|
||||||
|
val response = Http.get<QQMSearch>(
|
||||||
|
"$qqMusicApiUrl/getSearchByKey",
|
||||||
|
mapOf("key" to keyword)
|
||||||
|
).response.data.song.list
|
||||||
|
val tempResultList = mutableListOf<QMSearchResult>()
|
||||||
|
response.forEach {
|
||||||
|
val coverUrl = Http.get<CoverImage>(
|
||||||
|
"$qqMusicApiUrl/getImageUrl",
|
||||||
|
mapOf("id" to it.albumMid)
|
||||||
|
)
|
||||||
|
val tempSearchResult = QMSearchResult(
|
||||||
|
it.songId, it.songName, it.singer.joinToString(", ") { join -> join.name },
|
||||||
|
it.interval, it.songMid, Instant.now().epochSecond, coverUrl.response.data.imageUrl
|
||||||
|
)
|
||||||
|
tempResultList.add(tempSearchResult)
|
||||||
|
}
|
||||||
|
recordMap[message.sender.userId] = tempResultList
|
||||||
|
val nodeMsg = NodeMessageChain.Builder()
|
||||||
|
val headerMsg = MessageChain.Builder()
|
||||||
|
.addText("发送 `qm p <序号>`即可返回对应的歌曲")
|
||||||
|
.addNewLine()
|
||||||
|
.addText("你有30秒的时间进行操作")
|
||||||
|
.build()
|
||||||
|
nodeMsg.addMessageChain(headerMsg, message.sender.userId)
|
||||||
|
tempResultList.forEachIndexed { index, it ->
|
||||||
|
try {
|
||||||
|
val imageBase64 = URI(it.albumUrl).toURL().readBytes().encodeToBase64()
|
||||||
|
val msg = MessageChain.Builder()
|
||||||
|
.addImage(imageBase64, true)
|
||||||
|
.addText("序号: $index")
|
||||||
|
.addNewLine()
|
||||||
|
.addText("歌曲名: ${it.name}")
|
||||||
|
.addNewLine()
|
||||||
|
.addText("歌手: ${it.singers}")
|
||||||
|
.addNewLine()
|
||||||
|
.addText("时长: ${it.interval.formatToMinutes()}")
|
||||||
|
.build()
|
||||||
|
nodeMsg.addMessageChain(msg, message.sender.userId)
|
||||||
|
} catch (_: FileNotFoundException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message.reply(nodeMsg.build())
|
||||||
|
} catch (_: Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,4 +32,5 @@ data class Config(
|
|||||||
val enableAntiRevoke: Boolean,
|
val enableAntiRevoke: Boolean,
|
||||||
val llamaUrl: String,
|
val llamaUrl: String,
|
||||||
val llamaModel: String,
|
val llamaModel: String,
|
||||||
|
val qqMusicApiUrl: String
|
||||||
)
|
)
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2024 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2024/9/25
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.fancybot.entity.music.qq
|
||||||
|
|
||||||
|
data class CoverImage(
|
||||||
|
val response: Response
|
||||||
|
) {
|
||||||
|
data class Response(
|
||||||
|
val data: Data
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Data(
|
||||||
|
val imageUrl: String
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2024 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2024/9/25
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.fancybot.entity.music.qq
|
||||||
|
|
||||||
|
data class QMSearchResult(
|
||||||
|
val id: Long,
|
||||||
|
val name: String,
|
||||||
|
val singers: String,
|
||||||
|
val interval: Int,
|
||||||
|
val mid: String,
|
||||||
|
val timestamp: Long,
|
||||||
|
val albumUrl: String
|
||||||
|
)
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2024 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2024/9/25
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.fancybot.entity.music.qq
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class QQMSearch(
|
||||||
|
val response: Response,
|
||||||
|
) {
|
||||||
|
data class Response(
|
||||||
|
val data: Data
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Data(
|
||||||
|
val song: Songs
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Songs(
|
||||||
|
val list: List<Song>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Song(
|
||||||
|
@SerializedName("albummid")
|
||||||
|
val albumMid: String,
|
||||||
|
val interval: Int,
|
||||||
|
@SerializedName("songmid")
|
||||||
|
val songMid: String,
|
||||||
|
@SerializedName("songid")
|
||||||
|
val songId: Long,
|
||||||
|
@SerializedName("songname")
|
||||||
|
val songName: String,
|
||||||
|
val singer: List<Singer>,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Singer(
|
||||||
|
val name: String
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -32,4 +32,5 @@ class ConfigManager : JsonFileHandler<Config>("config.json") {
|
|||||||
val enableAntiRevoke get() = this.read<Config>().enableAntiRevoke
|
val enableAntiRevoke get() = this.read<Config>().enableAntiRevoke
|
||||||
val llamaUrl get() = this.read<Config>().llamaUrl
|
val llamaUrl get() = this.read<Config>().llamaUrl
|
||||||
val llamaModel get() = this.read<Config>().llamaModel
|
val llamaModel get() = this.read<Config>().llamaModel
|
||||||
|
val qqMusicApiUrl get() = this.read<Config>().qqMusicApiUrl
|
||||||
}
|
}
|
||||||
@@ -40,3 +40,9 @@ fun Int.formatNumberEnglish(): String {
|
|||||||
else -> this.toString()
|
else -> this.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Int.formatToMinutes(): String {
|
||||||
|
val minutes = this / 60
|
||||||
|
val remainingSeconds = this % 60
|
||||||
|
return "$minutes:${if (remainingSeconds < 10) "0" else ""}$remainingSeconds"
|
||||||
|
}
|
||||||
@@ -24,5 +24,6 @@
|
|||||||
],
|
],
|
||||||
"enableAntiRevoke": true,
|
"enableAntiRevoke": true,
|
||||||
"llamaUrl": "http://127.0.0.1",
|
"llamaUrl": "http://127.0.0.1",
|
||||||
"llamaModel": "llama3.1"
|
"llamaModel": "llama3.1",
|
||||||
|
"qqMusicApiUrl": "http://127.0.0.1:3200"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user