All Downloads are FREE. Search and download functionalities are using the official Maven repository.

love.forte.simbot.component.lovelycat.sender.LovelyCatSender.kt Maven / Gradle / Ivy

/*
 *
 *  * Copyright (c) 2021. ForteScarlet All rights reserved.
 *  * Project  simple-robot
 *  * File     MiraiAvatar.kt
 *  *
 *  * You can contact the author through the following channels:
 *  * github https://github.com/ForteScarlet
 *  * gitee  https://gitee.com/ForteScarlet
 *  * email  [email protected]
 *  * QQ     1149159218
 *
 */

package love.forte.simbot.component.lovelycat.sender

import catcode.CAT_HEAD
import catcode.CatCodeUtil
import catcode.codes.Nyanko
import love.forte.common.utils.Carrier
import love.forte.simbot.api.message.MessageContent
import love.forte.simbot.api.message.assists.Flag
import love.forte.simbot.api.message.events.GroupMsg
import love.forte.simbot.api.message.events.PrivateMsg
import love.forte.simbot.api.sender.Sender
import love.forte.simbot.component.lovelycat.LovelyCatApiTemplate
import love.forte.simbot.component.lovelycat.message.LovelyCatForSendMessageContent
import love.forte.simbot.component.lovelycat.message.event.GROUP_SUFFIX
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext


private object Empty


/**
 * 可爱猫送信器。
 */
public class LovelyCatSender(
    private val botId: String,
    private val api: LovelyCatApiTemplate,
    private val def: Sender,
) : Sender {
    override val coroutineContext: CoroutineContext
        get() = EmptyCoroutineContext

    /**
     * 通过携带 catCode 的文本消息进行发送消息发送。
     */
    private fun sendMsg(target: String, msg: String) {
        val needAtCode: MutableList = mutableListOf()
        var atAll = false

        // msgList
        CatCodeUtil.split(msg) {
            if (startsWith(CAT_HEAD)) {
                // is cat
                val neko = Nyanko.byCode(this)
                when (neko.type) {
                    // at.
                    "at" -> {
                        neko["all"]?.takeIf { it == "true" }?.let {
                            atAll = true
                        }

                        neko["code"]?.let {
                            if (it == "all") atAll = true
                            else needAtCode.add(it)
                        }

                    }
                    // send img
                    "image" -> {
                        // maybe... local file to base64
                        val path = neko["file"] ?: neko["url"]
                        ?: throw IllegalArgumentException("cannot found param 'path' or 'url' in $neko.")
                        api.sendImageMsg(botId, target, path)
                    }

                    // send video
                    "video" -> {
                        // 只支持本地文件。
                        val path = neko["file"] ?: throw IllegalArgumentException("cannot found param 'path' in $neko.")
                        api.sendVideoMsg(botId, target, path)
                    }

                    // send file video
                    "file" -> {
                        val path = neko["file"] ?: throw IllegalArgumentException("cannot found param 'path' in $neko.")
                        api.sendFileMsg(botId, target, path)
                    }

                    // send card
                    "card" -> {
                        val content =
                            neko["content"] ?: throw IllegalArgumentException("cannot found param 'content' in $neko.")
                        api.sendCardMsg(botId, target, content)
                    }

                    "link", "share" -> {
                        /*
                        title, 文本型, , 链接标题
                        text, 文本型, , 链接内容
                        target_url, 文本型, 可空, 跳转链接
                        pic_url, 文本型, 可空, 图片的链接
                        icon_url, 文本型, 可空, 图标的链接
                         */

                        val title =
                            neko["title"] ?: throw IllegalArgumentException("cannot found param 'title' in $neko.")
                        val text = neko["text"] ?: throw IllegalArgumentException("cannot found param 'text' in $neko.")
                        val targetUrl = neko["target"]
                        val pic = neko["pic"]
                        val icon = neko["icon"]

                        api.sendLinkMsg(botId, target, title, text, targetUrl, pic, icon)
                    }
                    else -> {
                        // ignore?
                    }

                }

                Empty
            } else {
                needAtCode.takeIf { it.isNotEmpty() }?.let {
                    val ats = needAtCode.joinToString(",")
                    needAtCode.clear()
                    api.sendGroupMsgAndAt(botId, target, ats, null, this)
                } ?: run {
                    if (atAll) {
                        api.modifyGroupNotice(botId, target, this.takeIf { it.isNotBlank() } ?: "@全体成员")
                        atAll = false
                    } else {
                        api.sendTextMsg(botId, target, this)
                    }
                }

                Empty
            }
        }


        // need at.
        needAtCode.takeIf { it.isNotEmpty() }?.let {
            api.sendGroupMsgAndAt(botId, target, it.joinToString(","), null, " ")
        }
        // }
    }


    /**
     * 基于 [MessageContent] 发送一个消息。
     */
    private fun sendMsg(target: String, msg: MessageContent) {
        if (msg is LovelyCatForSendMessageContent) {
            // 先发image
            // 然后发at + msg
            val images = msg.image
            if (images.isNotEmpty()) {
                // not empty
                images.forEach {
                    api.sendImageMsg(botId, target, it)
                }
            }
            val msgText = msg.text
            val atAll = msg.atAll
            if (atAll) {
                api.modifyGroupNotice(botId, target, msgText)
            } else {
                val ats = msg.at
                if (ats.isNotEmpty()) {
                    api.sendGroupMsgAndAt(botId, target, ats.joinToString(","), null, msgText)
                } else {
                    api.sendTextMsg(botId, target, msgText)
                }
            }

            return
        }


        val needAtCode: MutableList = mutableListOf()
        var atAll = false

        msg.cats.forEach { neko ->
            when (neko.type) {
                "at" -> {
                    neko["all"]?.takeIf { it == "true" }?.let {
                        atAll = true
                    }

                    neko["code"]?.let {
                        if (it == "all") atAll = true
                        else needAtCode.add(it)
                    }
                }
                // send img
                "image" -> {
                    // maybe... local file to base64
                    val path = neko["file"] ?: neko["url"]
                    ?: throw IllegalArgumentException("cannot found param 'file' or 'url' in $neko.")
                    api.sendImageMsg(botId, target, path)
                }

                // send video
                "video" -> {
                    // 只支持本地文件。
                    val path = neko["file"] ?: throw IllegalArgumentException("cannot found param 'file' in $neko.")
                    api.sendVideoMsg(botId, target, path)
                }

                // send file video
                "file" -> {
                    val path = neko["file"] ?: throw IllegalArgumentException("cannot found param 'file' in $neko.")
                    api.sendFileMsg(botId, target, path)
                }

                // send card
                "card" -> {
                    val content =
                        neko["content"] ?: throw IllegalArgumentException("cannot found param 'content' in $neko.")
                    api.sendCardMsg(botId, target, content)
                }

                "link", "share" -> {
                    val title = neko["title"] ?: throw IllegalArgumentException("cannot found param 'title' in $neko.")
                    val text = neko["text"] ?: throw IllegalArgumentException("cannot found param 'text' in $neko.")
                    val targetUrl = neko["target"]
                    val pic = neko["pic"]
                    val icon = neko["icon"]

                    api.sendLinkMsg(botId, target, title, text, targetUrl, pic, icon)
                }

                // text.
                "text" -> {
                    val textMsg = neko["text"] ?: ""

                    needAtCode.takeIf { it.isNotEmpty() }?.let {
                        val ats = needAtCode.joinToString(",")
                        needAtCode.clear()
                        api.sendGroupMsgAndAt(botId, target, ats, null, textMsg)
                    } ?: run {
                        if (atAll) {
                            api.modifyGroupNotice(botId, target, textMsg.takeIf { it.isNotBlank() } ?: "@全体成员")
                            atAll = false
                        } else {
                            api.sendTextMsg(botId, target, textMsg)
                        }
                    }
                }

                else -> {
                    // ignore?
                }
            }
        }

        // need at.
        needAtCode.takeIf { it.isNotEmpty() }?.let {
            api.sendGroupMsgAndAt(botId, target, it.joinToString(","), null, " ")
        }
    }


    /**
     * 发送一条群消息。 回执必然为空。
     *
     */
    override suspend fun groupMsg(
        parent: String?,
        group: String,
        msg: String,
    ): Carrier> {
        sendMsg(group, msg)
        return Carrier.empty()
    }

    override suspend fun groupMsg(group: Long, msg: String): Carrier> =
        sendGroupMsg("$group$GROUP_SUFFIX", msg)


    /**
     * 发送一条群消息。回执必然为空。
     *
     */
    override suspend fun groupMsg(group: String, msg: MessageContent): Carrier> {
        sendMsg(group, msg)
        return Carrier.empty()
    }

    override suspend fun groupMsg(group: Long, msg: MessageContent): Carrier> =
        sendGroupMsg("$group$GROUP_SUFFIX", msg)


    /**
     * 发送一条私聊消息。 回执必然为空。
     *
     */
    override suspend fun privateMsg(
        code: String,
        group: String?,
        msg: String,
    ): Carrier> {
        sendMsg(code, msg)
        return Carrier.empty()
    }

    override suspend fun privateMsg(
        code: String,
        msg: MessageContent,
    ): Carrier> {
        sendMsg(code, msg)
        return Carrier.empty()
    }

    /**
     * 发布群公告。微信发送群公告会at全体成员。
     * @param group 群号
     * @param title 标题
     * @param text   正文
     *
     * @param popUp  不支持
     * @param top    不支持
     * @param toNewMember 不支持
     * @param confirm 不支持
     * @return 是否发布成功
     */
    override suspend fun groupNotice(
        group: String,
        title: String?,
        text: String?,
        popUp: Boolean,
        top: Boolean,
        toNewMember: Boolean,
        confirm: Boolean,
    ): Carrier {
        // compute total length.
        val length = (title?.length ?: 0) + (text?.length ?: 0)

        return length.takeIf { it > 0 }?.let { len ->

            val sb = StringBuilder(len)

            title?.let { sb.append(it).appendLine() }
            text?.let { sb.append(it) }

            val result = api.modifyGroupNotice(botId, group, sb.toString())
            Carrier.get(result.result?.lowercase() == "ok")

        } ?: Carrier.get(false)
    }

    override suspend fun groupNotice(
        group: Long,
        title: String?,
        text: String?,
        popUp: Boolean,
        top: Boolean,
        toNewMember: Boolean,
        confirm: Boolean,
    ): Carrier =
        sendGroupNotice("$group$GROUP_SUFFIX", title, text, popUp, top, toNewMember, confirm)


    /**
     * 不支持群签到。
     */
    @Deprecated("Not support")
    @Suppress("DEPRECATION")
    override fun sendGroupSign(group: String, title: String, message: String): Carrier {
        return def.sendGroupSign(group, title, message)
    }

    @Deprecated("Not support")
    @Suppress("DEPRECATION", "DeprecatedCallableAddReplaceWith")
    override fun sendGroupSign(group: Long, title: String, message: String): Carrier =
        sendGroupSign("$group$GROUP_SUFFIX", title, message)

}








© 2015 - 2025 Weber Informatics LLC | Privacy Policy