refactor ExtraAction to TelegramExtensions, some coeur startup changes

- refactor ExtraAction to TelegramExtensions
  - make exec a TelegramBot extension
  - refactor isUserInGroup to Chat extension hasMember and memberHasPermission
  - added LimBoUser and LimboChat for capability
- deleted TelegramUpdatesListener, and make EventListenerManager implemented UpdatesListener
- change some value definition, change startup and exit process in MornyCoeur
  - removed updatesListener, extract its manager to eventManager in Coeur
  - added account.shutdown before other's
  - moved Morny's startup/exit report to Coeur
  - change exitCleanup thread name from "morny-exiting" to "system-exit"
This commit is contained in:
A.C.Sukazyo Eyre 2023-09-23 21:44:06 +08:00
parent 511036e2ce
commit bfacb0d039
Signed by: Eyre_S
GPG Key ID: C17CE40291207874
33 changed files with 199 additions and 205 deletions

View File

@ -8,7 +8,7 @@ MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s
VERSION = 1.0.0-RC5 VERSION = 1.0.0-RC5
USE_DELTA = true USE_DELTA = true
VERSION_DELTA = scala2 VERSION_DELTA = scala3
CODENAME = beiping CODENAME = beiping

View File

@ -3,11 +3,10 @@ package cc.sukazyo.cono.morny
import cc.sukazyo.cono.morny.bot.command.MornyCommands import cc.sukazyo.cono.morny.bot.command.MornyCommands
import cc.sukazyo.cono.morny.daemon.MornyDaemons import cc.sukazyo.cono.morny.daemon.MornyDaemons
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger} import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
import cc.sukazyo.cono.morny.MornyCoeur.THREAD_MORNY_EXIT import cc.sukazyo.cono.morny.MornyCoeur.THREAD_SERVER_EXIT
import cc.sukazyo.cono.morny.bot.api.TelegramUpdatesListener import cc.sukazyo.cono.morny.bot.api.EventListenerManager
import cc.sukazyo.cono.morny.bot.event.{MornyEventListeners, MornyOnInlineQuery, MornyOnTelegramCommand, MornyOnUpdateTimestampOffsetLock} import cc.sukazyo.cono.morny.bot.event.{MornyEventListeners, MornyOnInlineQuery, MornyOnTelegramCommand, MornyOnUpdateTimestampOffsetLock}
import cc.sukazyo.cono.morny.bot.query.MornyQueries import cc.sukazyo.cono.morny.bot.query.MornyQueries
import cc.sukazyo.cono.morny.util.tgapi.ExtraAction
import com.pengrad.telegrambot.TelegramBot import com.pengrad.telegrambot.TelegramBot
import com.pengrad.telegrambot.request.GetMe import com.pengrad.telegrambot.request.GetMe
@ -16,7 +15,7 @@ import scala.util.boundary.break
object MornyCoeur { object MornyCoeur {
val THREAD_MORNY_EXIT = "morny-exiting" val THREAD_SERVER_EXIT = "system-exit"
} }
@ -50,18 +49,18 @@ class MornyCoeur (using val config: MornyConfig) {
/** current Morny's [[MornyTrusted]] instance */ /** current Morny's [[MornyTrusted]] instance */
val trusted: MornyTrusted = MornyTrusted() val trusted: MornyTrusted = MornyTrusted()
/** current Morny's [[ExtraAction]] toolset */
val extra: ExtraAction = ExtraAction as __loginResult.account
private val updatesListener: TelegramUpdatesListener = TelegramUpdatesListener()
val daemons: MornyDaemons = MornyDaemons() val daemons: MornyDaemons = MornyDaemons()
updatesListener.manager register MornyOnUpdateTimestampOffsetLock() //noinspection ScalaWeakerAccess
val eventManager: EventListenerManager = EventListenerManager()
eventManager register MornyOnUpdateTimestampOffsetLock()
val commands: MornyCommands = MornyCommands() val commands: MornyCommands = MornyCommands()
//noinspection ScalaWeakerAccess //noinspection ScalaWeakerAccess
val queries: MornyQueries = MornyQueries() val queries: MornyQueries = MornyQueries()
updatesListener.manager register MornyOnTelegramCommand(using commands) eventManager register MornyOnTelegramCommand(using commands)
updatesListener.manager register MornyOnInlineQuery(using queries) eventManager register MornyOnInlineQuery(using queries)
val events: MornyEventListeners = MornyEventListeners(using updatesListener.manager) //noinspection ScalaUnusedSymbol
val events: MornyEventListeners = MornyEventListeners(using eventManager)
/** inner value: about why morny exit, used in [[daemon.MornyReport]]. */ /** inner value: about why morny exit, used in [[daemon.MornyReport]]. */
private var whileExit_reason: AnyRef|Null = _ private var whileExit_reason: AnyRef|Null = _
@ -72,11 +71,12 @@ class MornyCoeur (using val config: MornyConfig) {
daemons.start() daemons.start()
logger info "start telegram event listening" logger info "start telegram event listening"
account setUpdatesListener updatesListener account setUpdatesListener eventManager
if config.commandLoginRefresh then if config.commandLoginRefresh then
logger info "resetting telegram command list" logger info "resetting telegram command list"
commands.automaticTGListUpdate() commands.automaticTGListUpdate()
daemons.reporter.reportCoeurMornyLogin()
logger info "Coeur start complete." logger info "Coeur start complete."
///<<< BLOCK END instance configure & startup stage 2 ///<<< BLOCK END instance configure & startup stage 2
@ -87,13 +87,17 @@ class MornyCoeur (using val config: MornyConfig) {
} }
private def exitCleanup (): Unit = { private def exitCleanup (): Unit = {
daemons.reporter.reportCoeurExit()
account.shutdown()
logger info "stopped bot account"
daemons.stop() daemons.stop()
if config.commandLogoutClear then if config.commandLogoutClear then
commands.automaticTGListRemove() commands.automaticTGListRemove()
logger info "done exit cleanup"
} }
private def configure_exitCleanup (): Unit = { private def configure_exitCleanup (): Unit = {
Runtime.getRuntime.addShutdownHook(new Thread(() => exitCleanup(), THREAD_MORNY_EXIT)) Runtime.getRuntime.addShutdownHook(new Thread(() => exitCleanup(), THREAD_SERVER_EXIT))
} }
def exit (status: Int, reason: AnyRef): Unit = def exit (status: Int, reason: AnyRef): Unit =

View File

@ -1,13 +1,17 @@
package cc.sukazyo.cono.morny package cc.sukazyo.cono.morny
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.{LimboChat, LimboUser}
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Chat.*
import com.pengrad.telegrambot.model.ChatMember.Status import com.pengrad.telegrambot.model.ChatMember.Status
import com.pengrad.telegrambot.TelegramBot
class MornyTrusted (using coeur: MornyCoeur)(using config: MornyConfig) { class MornyTrusted (using coeur: MornyCoeur)(using config: MornyConfig) {
def isTrusted (userId: Long): Boolean = def isTrusted (userId: Long): Boolean =
given TelegramBot = coeur.account
if userId == config.trustedMaster then true if userId == config.trustedMaster then true
else if config.trustedChat == -1 then false else if config.trustedChat == -1 then false
else coeur.extra isUserInGroup(userId, config.trustedChat, Status.administrator) else LimboChat(config.trustedChat) memberHasPermission(LimboUser(userId), Status.administrator)
def isTrusted_dinnerReader (userId: Long): Boolean = def isTrusted_dinnerReader (userId: Long): Boolean =
if userId == config.trustedMaster then true if userId == config.trustedMaster then true

View File

@ -1,9 +1,8 @@
package cc.sukazyo.cono.morny.bot.api package cc.sukazyo.cono.morny.bot.api
import cc.sukazyo.cono.morny.MornyCoeur
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
trait EventListener (using MornyCoeur) { trait EventListener () {
def onMessage (using Update): Boolean = false def onMessage (using Update): Boolean = false
def onEditedMessage (using Update): Boolean = false def onEditedMessage (using Update): Boolean = false

View File

@ -5,11 +5,12 @@ import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.UpdatesListener
import scala.collection.mutable import scala.collection.mutable
import scala.language.postfixOps import scala.language.postfixOps
class EventListenerManager (using coeur: MornyCoeur) { class EventListenerManager (using coeur: MornyCoeur) extends UpdatesListener {
private val listeners = mutable.Queue.empty[EventListener] private val listeners = mutable.Queue.empty[EventListener]
@ -76,8 +77,13 @@ class EventListenerManager (using coeur: MornyCoeur) {
} }
def publishUpdate (using Update): Unit = { import java.util
EventRunner().start() import scala.jdk.CollectionConverters.*
override def process (updates: util.List[Update]): Int = {
for (update <- updates.asScala)
EventRunner(using update).start()
UpdatesListener.CONFIRMED_UPDATES_ALL
} }
} }

View File

@ -1,20 +0,0 @@
package cc.sukazyo.cono.morny.bot.api
import cc.sukazyo.cono.morny.MornyCoeur
import com.pengrad.telegrambot.UpdatesListener
import com.pengrad.telegrambot.model.Update
import java.util
import scala.jdk.CollectionConverters.*
class TelegramUpdatesListener (using MornyCoeur) extends UpdatesListener {
val manager = EventListenerManager()
override def process (updates: util.List[Update]): Int = {
for (update <- updates.asScala)
manager.publishUpdate(using update)
UpdatesListener.CONFIRMED_UPDATES_ALL
}
}

View File

@ -4,6 +4,7 @@ import cc.sukazyo.cono.morny.Log.logger
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.data.TelegramStickers import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.{Chat, Update} import com.pengrad.telegrambot.model.{Chat, Update}
import com.pengrad.telegrambot.request.{DeleteMessage, GetChatMember, SendSticker} import com.pengrad.telegrambot.request.{DeleteMessage, GetChatMember, SendSticker}
@ -36,19 +37,19 @@ class DirectMsgClear (using coeur: MornyCoeur) extends ISimpleCommand {
if (isTrusted || _isReplyTrusted) { if (isTrusted || _isReplyTrusted) {
coeur.extra exec DeleteMessage( coeur.account exec DeleteMessage(
event.message.chat.id, event.message.replyToMessage.messageId event.message.chat.id, event.message.replyToMessage.messageId
) )
def _isPrivate: Boolean = event.message.chat.`type` == Chat.Type.Private def _isPrivate: Boolean = event.message.chat.`type` == Chat.Type.Private
def _isPermission: Boolean = def _isPermission: Boolean =
(coeur.extra exec GetChatMember(event.message.chat.id, event.message.from.id)) (coeur.account exec GetChatMember(event.message.chat.id, event.message.from.id))
.chatMember.canDeleteMessages .chatMember.canDeleteMessages
if (_isPrivate || _isPermission) { if (_isPrivate || _isPermission) {
coeur.extra exec DeleteMessage(event.message.chat.id, event.message.messageId) coeur.account exec DeleteMessage(event.message.chat.id, event.message.messageId)
} }
} else coeur.extra exec SendSticker( } else coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_403 TelegramStickers ID_403
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)

View File

@ -7,6 +7,7 @@ import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.CommonEncrypt import cc.sukazyo.cono.morny.util.CommonEncrypt
import cc.sukazyo.cono.morny.util.CommonEncrypt.* import cc.sukazyo.cono.morny.util.CommonEncrypt.*
import cc.sukazyo.cono.morny.util.ConvertByteHex.toHex import cc.sukazyo.cono.morny.util.ConvertByteHex.toHex
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.{PhotoSize, Update} import com.pengrad.telegrambot.model.{PhotoSize, Update}
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.{GetFile, SendDocument, SendMessage, SendSticker} import com.pengrad.telegrambot.request.{GetFile, SendDocument, SendMessage, SendSticker}
@ -47,7 +48,7 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
val mod_uppercase = if (args.length > 1) { val mod_uppercase = if (args.length > 1) {
if (args.length < 3 && _is_mod_u(args(1))) true if (args.length < 3 && _is_mod_u(args(1))) true
else else
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_404 TelegramStickers ID_404
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -73,7 +74,7 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
val _r = event.message.replyToMessage val _r = event.message.replyToMessage
if ((_r ne null) && (_r.document ne null)) { if ((_r ne null) && (_r.document ne null)) {
try {XFile( try {XFile(
coeur.account getFileContent (coeur.extra exec GetFile(_r.document.fileId)).file, coeur.account getFileContent (coeur.account exec GetFile(_r.document.fileId)).file,
_r.document.fileName _r.document.fileName
)} catch case e: IOException => )} catch case e: IOException =>
logger warn s"NetworkRequest error: TelegramFileAPI:\n\t${e.getMessage}" logger warn s"NetworkRequest error: TelegramFileAPI:\n\t${e.getMessage}"
@ -91,7 +92,7 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
if (_photo_origin eq null) throw IllegalArgumentException("no photo from api.") if (_photo_origin eq null) throw IllegalArgumentException("no photo from api.")
import cc.sukazyo.cono.morny.util.UseRandom.rand_id import cc.sukazyo.cono.morny.util.UseRandom.rand_id
XFile( XFile(
coeur.account getFileContent (coeur.extra exec GetFile(_photo_origin.fileId)).file, coeur.account getFileContent (coeur.account exec GetFile(_photo_origin.fileId)).file,
s"photo$rand_id.png" s"photo$rand_id.png"
) )
} catch } catch
@ -107,7 +108,7 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
} else if ((_r ne null) && (_r.text ne null)) { } else if ((_r ne null) && (_r.text ne null)) {
XText(_r.text) XText(_r.text)
} else { } else {
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
"<i><u>null</u></i>" "<i><u>null</u></i>"
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId) ).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
@ -153,7 +154,7 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
_tool_b64d.decode, _tool_b64d.decode,
CommonEncrypt.lint_base64FileName CommonEncrypt.lint_base64FileName
) } catch case _: IllegalArgumentException => ) } catch case _: IllegalArgumentException =>
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_404 // todo: is here better erro notify? TelegramStickers ID_404 // todo: is here better erro notify?
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -163,7 +164,7 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
case "sha256" => genResult_hash(input, SHA256) case "sha256" => genResult_hash(input, SHA256)
case "sha512" => genResult_hash(input, SHA512) case "sha512" => genResult_hash(input, SHA512)
case _ => case _ =>
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_404 TelegramStickers ID_404
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -173,13 +174,13 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
// output // output
result match result match
case _file: EXFile => case _file: EXFile =>
coeur.extra exec SendDocument( coeur.account exec SendDocument(
event.message.chat.id, event.message.chat.id,
_file.result _file.result
).fileName(_file.resultName).replyToMessageId(event.message.messageId) ).fileName(_file.resultName).replyToMessageId(event.message.messageId)
case _text: EXTextLike => case _text: EXTextLike =>
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
s"<pre><code>${h(_text.text)}</code></pre>" s"<pre><code>${h(_text.text)}</code></pre>"
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId) ).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
@ -211,7 +212,7 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
* </blockquote> * </blockquote>
*/ */
private def echoHelp(chat: Long, replyTo: Int): Unit = private def echoHelp(chat: Long, replyTo: Int): Unit =
coeur.extra exec SendMessage( coeur.account exec SendMessage(
chat, chat,
s"""<b><u>base64</u></b>, b64 s"""<b><u>base64</u></b>, b64
|<b><u>base64url</u></b>, base64u, b64u |<b><u>base64url</u></b>, base64u, b64u

View File

@ -2,6 +2,7 @@ package cc.sukazyo.cono.morny.bot.command
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.data.TelegramStickers import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.request.SendSticker import com.pengrad.telegrambot.request.SendSticker
@ -21,12 +22,12 @@ class EventHack (using coeur: MornyCoeur) extends ITelegramCommand {
val x_mode = if (command.args nonEmpty) command.args(0) else "" val x_mode = if (command.args nonEmpty) command.args(0) else ""
def done_ok = def done_ok =
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_WAITING TelegramStickers ID_WAITING
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
def done_forbiddenForAny = def done_forbiddenForAny =
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_403 TelegramStickers ID_403
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)

View File

@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.bot.command
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.util.tgapi.{InputCommand, Standardize} import cc.sukazyo.cono.morny.util.tgapi.{InputCommand, Standardize}
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramUserInformation import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramUserInformation
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.{GetChatMember, SendMessage} import com.pengrad.telegrambot.request.{GetChatMember, SendMessage}
@ -21,7 +22,7 @@ class GetUsernameAndId (using coeur: MornyCoeur) extends ITelegramCommand {
val args = command.args val args = command.args
if (args.length > 1) if (args.length > 1)
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
"[Unavailable] Too much arguments." "[Unavailable] Too much arguments."
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -31,7 +32,7 @@ class GetUsernameAndId (using coeur: MornyCoeur) extends ITelegramCommand {
if (args nonEmpty) { if (args nonEmpty) {
try args(0) toLong try args(0) toLong
catch case e: NumberFormatException => catch case e: NumberFormatException =>
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
s"[Unavailable] ${e.getMessage}" s"[Unavailable] ${e.getMessage}"
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -42,7 +43,7 @@ class GetUsernameAndId (using coeur: MornyCoeur) extends ITelegramCommand {
val response = coeur.account execute GetChatMember(event.message.chat.id, userId) val response = coeur.account execute GetChatMember(event.message.chat.id, userId)
if (response.chatMember eq null) if (response.chatMember eq null)
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
"[Unavailable] user not found." "[Unavailable] user not found."
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -51,13 +52,13 @@ class GetUsernameAndId (using coeur: MornyCoeur) extends ITelegramCommand {
val user = response.chatMember.user val user = response.chatMember.user
if (user.id == Standardize.CHANNEL_SPEAKER_MAGIC_ID) if (user.id == Standardize.CHANNEL_SPEAKER_MAGIC_ID)
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
"<code>$__channel_identify</code>" "<code>$__channel_identify</code>"
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
return; return;
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
TelegramUserInformation getFormattedInformation user TelegramUserInformation getFormattedInformation user
).replyToMessageId(event.message.messageId()).parseMode(ParseMode HTML) ).replyToMessageId(event.message.messageId()).parseMode(ParseMode HTML)

View File

@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.bot.command
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.data.ip186.IP186QueryHandler import cc.sukazyo.cono.morny.data.ip186.IP186QueryHandler
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.SendMessage import com.pengrad.telegrambot.request.SendMessage
@ -34,7 +35,7 @@ class IP186Query (using coeur: MornyCoeur) {
if (command.args isEmpty) if (command.args isEmpty)
if event.message.replyToMessage eq null then null else event.message.replyToMessage.text if event.message.replyToMessage eq null then null else event.message.replyToMessage.text
else if (command.args.length > 1) else if (command.args.length > 1)
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
"[Unavailable] Too much arguments." "[Unavailable] Too much arguments."
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -42,7 +43,7 @@ class IP186Query (using coeur: MornyCoeur) {
else command.args(0) else command.args(0)
if (target eq null) if (target eq null)
coeur.extra exec new SendMessage( coeur.account exec new SendMessage(
event.message.chat.id, event.message.chat.id,
"[Unavailable] No ip defined." "[Unavailable] No ip defined."
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -57,7 +58,7 @@ class IP186Query (using coeur: MornyCoeur) {
case Subs.WHOIS.cmd => IP186QueryHandler.query_whoisPretty(target) case Subs.WHOIS.cmd => IP186QueryHandler.query_whoisPretty(target)
case _ => throw IllegalArgumentException(s"Unknown 186-IP query method ${command.command}") case _ => throw IllegalArgumentException(s"Unknown 186-IP query method ${command.command}")
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
s"""${h(response.url)} s"""${h(response.url)}
|<code>${h(response.body)}</code>""" |<code>${h(response.body)}</code>"""
@ -65,7 +66,7 @@ class IP186Query (using coeur: MornyCoeur) {
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId) ).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
} catch case e: Exception => } catch case e: Exception =>
coeur.extra exec new SendMessage( coeur.account exec new SendMessage(
event.message().chat().id(), event.message().chat().id(),
s"""[Exception] in query: s"""[Exception] in query:
|<code>${h(e.getMessage)}</code>""" |<code>${h(e.getMessage)}</code>"""

View File

@ -4,6 +4,7 @@ import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.data.TelegramStickers import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.Log.logger import cc.sukazyo.cono.morny.Log.logger
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.{BotCommand, DeleteMyCommands, Update} import com.pengrad.telegrambot.model.{BotCommand, DeleteMyCommands, Update}
import com.pengrad.telegrambot.request.{SendSticker, SetMyCommands} import com.pengrad.telegrambot.request.{SendSticker, SetMyCommands}
@ -75,7 +76,7 @@ class MornyCommands (using coeur: MornyCoeur) {
private def nonCommandExecutable (using command: InputCommand, event: Update): Boolean = { private def nonCommandExecutable (using command: InputCommand, event: Update): Boolean = {
if command.target eq null then false if command.target eq null then false
else else
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_404 TelegramStickers ID_404
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -85,14 +86,14 @@ class MornyCommands (using coeur: MornyCoeur) {
def automaticTGListUpdate (): Unit = { def automaticTGListUpdate (): Unit = {
val listing = commands_toTelegramList val listing = commands_toTelegramList
automaticTGListRemove() automaticTGListRemove()
coeur.extra exec SetMyCommands(listing:_*) coeur.account exec SetMyCommands(listing:_*)
logger info logger info
s"""automatic updated telegram command list : s"""automatic updated telegram command list :
|${commandsTelegramList_toString(listing)}""".stripMargin |${commandsTelegramList_toString(listing)}""".stripMargin
} }
def automaticTGListRemove (): Unit = { def automaticTGListRemove (): Unit = {
coeur.extra exec DeleteMyCommands() coeur.account exec DeleteMyCommands()
logger info "cleaned up command list" logger info "cleaned up command list"
} }

View File

@ -3,6 +3,7 @@ import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.bot.command.ICommandAlias.ListedAlias import cc.sukazyo.cono.morny.bot.command.ICommandAlias.ListedAlias
import cc.sukazyo.cono.morny.data.TelegramStickers import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.request.SendSticker import com.pengrad.telegrambot.request.SendSticker
@ -18,7 +19,7 @@ class MornyHellos (using coeur: MornyCoeur) {
override val description: String = "检查是否在线" override val description: String = "检查是否在线"
override def execute (using command: InputCommand, event: Update): Unit = override def execute (using command: InputCommand, event: Update): Unit =
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_ONLINE_STATUS_RETURN TelegramStickers ID_ONLINE_STATUS_RETURN
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -33,7 +34,7 @@ class MornyHellos (using coeur: MornyCoeur) {
override val description: String = "打招呼" override val description: String = "打招呼"
override def execute (using command: InputCommand, event: Update): Unit = override def execute (using command: InputCommand, event: Update): Unit =
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_HELLO TelegramStickers ID_HELLO
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)

View File

@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.bot.command
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.data.MornyInformation.{getAboutPic, getMornyAboutLinksHTML} import cc.sukazyo.cono.morny.data.MornyInformation.{getAboutPic, getMornyAboutLinksHTML}
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.SendPhoto import com.pengrad.telegrambot.request.SendPhoto
@ -16,7 +17,7 @@ class MornyInfoOnStart (using coeur: MornyCoeur) extends ISimpleCommand {
override def execute (using command: InputCommand, event: Update): Unit = { override def execute (using command: InputCommand, event: Update): Unit = {
coeur.extra exec new SendPhoto( coeur.account exec new SendPhoto(
event.message.chat.id, event.message.chat.id,
getAboutPic getAboutPic
).caption( ).caption(

View File

@ -6,6 +6,7 @@ import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.util.CommonFormat.{formatDate, formatDuration} import cc.sukazyo.cono.morny.util.CommonFormat.{formatDate, formatDuration}
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.{SendMessage, SendPhoto, SendSticker} import com.pengrad.telegrambot.request.{SendMessage, SendPhoto, SendSticker}
@ -47,7 +48,7 @@ class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand {
} }
private def echoInfo (chatId: Long, replyTo: Int): Unit = { private def echoInfo (chatId: Long, replyTo: Int): Unit = {
coeur.extra exec new SendPhoto( coeur.account exec new SendPhoto(
chatId, chatId,
getAboutPic getAboutPic
).caption( ).caption(
@ -92,15 +93,15 @@ class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand {
val send_mid = SendMessage(send_chat, mid) val send_mid = SendMessage(send_chat, mid)
val send_sticker = SendSticker(send_chat, file_id) val send_sticker = SendSticker(send_chat, file_id)
if (send_replyTo != -1) send_mid.replyToMessageId(send_replyTo) if (send_replyTo != -1) send_mid.replyToMessageId(send_replyTo)
val result_send_mid = coeur.extra exec send_mid val result_send_mid = coeur.account exec send_mid
send_sticker.replyToMessageId(result_send_mid.message.messageId) send_sticker.replyToMessageId(result_send_mid.message.messageId)
coeur.extra exec send_sticker coeur.account exec send_sticker
} }
private[command] def echoVersion (using event: Update): Unit = { private[command] def echoVersion (using event: Update): Unit = {
val versionDeltaHTML = if (MornySystem.isUseDelta) s"-δ<code>${h(MornySystem.VERSION_DELTA)}</code>" else "" val versionDeltaHTML = if (MornySystem.isUseDelta) s"-δ<code>${h(MornySystem.VERSION_DELTA)}</code>" else ""
val versionGitHTML = if (MornySystem.isGitBuild) s"git $getVersionGitTagHTML" else "" val versionGitHTML = if (MornySystem.isGitBuild) s"git $getVersionGitTagHTML" else ""
coeur.extra exec new SendMessage( coeur.account exec new SendMessage(
event.message.chat.id, event.message.chat.id,
// language=html // language=html
s"""version: s"""version:
@ -117,7 +118,7 @@ class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand {
private[command] def echoRuntime (using event: Update): Unit = { private[command] def echoRuntime (using event: Update): Unit = {
def sysprop (p: String): String = System.getProperty(p) def sysprop (p: String): String = System.getProperty(p)
coeur.extra exec new SendMessage( coeur.account exec new SendMessage(
event.message.chat.id, event.message.chat.id,
/* language=html */ /* language=html */
s"""system: s"""system:
@ -144,7 +145,7 @@ class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand {
} }
private def echo404 (using event: Update): Unit = private def echo404 (using event: Update): Unit =
coeur.extra exec new SendSticker( coeur.account exec new SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_404 TelegramStickers ID_404
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)

View File

@ -6,6 +6,7 @@ import cc.sukazyo.cono.morny.Log.logger
import cc.sukazyo.cono.morny.daemon.MornyReport import cc.sukazyo.cono.morny.daemon.MornyReport
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.* import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.*
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.request.SendSticker import com.pengrad.telegrambot.request.SendSticker
@ -26,7 +27,7 @@ class MornyManagers (using coeur: MornyCoeur) {
if (coeur.trusted isTrusted user.id) { if (coeur.trusted isTrusted user.id) {
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_EXIT TelegramStickers ID_EXIT
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -35,7 +36,7 @@ class MornyManagers (using coeur: MornyCoeur) {
} else { } else {
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_403 TelegramStickers ID_403
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -63,14 +64,14 @@ class MornyManagers (using coeur: MornyCoeur) {
logger info s"call save from command by ${user toLogTag}" logger info s"call save from command by ${user toLogTag}"
coeur.saveDataAll() coeur.saveDataAll()
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_SAVED TelegramStickers ID_SAVED
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
} else { } else {
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_403 TelegramStickers ID_403
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)

View File

@ -3,6 +3,7 @@ import cc.sukazyo.cono.morny.data.MornyJrrp
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.* import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.*
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.SendMessage import com.pengrad.telegrambot.request.SendMessage
@ -24,7 +25,7 @@ class MornyOldJrrp (using coeur: MornyCoeur) extends ITelegramCommand {
case _ => "..." case _ => "..."
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
// language=html // language=html
f"${user.fullnameRefHTML} 在(utc的)今天的运气指数是———— <code>$jrrp%.2f%%</code> ${h(ending)}" f"${user.fullnameRefHTML} 在(utc的)今天的运气指数是———— <code>$jrrp%.2f%%</code> ${h(ending)}"

View File

@ -4,6 +4,7 @@ import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.data.{NbnhhshQuery, TelegramStickers} import cc.sukazyo.cono.morny.data.{NbnhhshQuery, TelegramStickers}
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.{SendMessage, SendSticker} import com.pengrad.telegrambot.request.{SendMessage, SendSticker}
@ -32,7 +33,7 @@ class Nbnhhsh (using coeur: MornyCoeur) extends ITelegramCommand {
else null else null
if (queryTarget == null) if (queryTarget == null)
coeur.extra exec SendSticker( coeur.account exec SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_404 TelegramStickers ID_404
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -67,13 +68,13 @@ class Nbnhhsh (using coeur: MornyCoeur) extends ITelegramCommand {
logger debug s"**exec as ${_word.name}" logger debug s"**exec as ${_word.name}"
} }
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
message toString message toString
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId) ).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
} catch case e: IOException => { } catch case e: IOException => {
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.chat.id,
s"""[Exception] in query: s"""[Exception] in query:
|${h(e.getMessage)} |${h(e.getMessage)}

View File

@ -2,6 +2,7 @@ package cc.sukazyo.cono.morny.bot.command
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.SendMessage import com.pengrad.telegrambot.request.SendMessage
@ -16,7 +17,7 @@ class Testing (using coeur: MornyCoeur) extends ISimpleCommand {
override def execute (using command: InputCommand, event: Update): Unit = { override def execute (using command: InputCommand, event: Update): Unit = {
coeur.extra exec new SendMessage( coeur.account exec new SendMessage(
event.message.chat.id, event.message.chat.id,
// language=html // language=html
"<b>Just</b> a TEST command." "<b>Just</b> a TEST command."

View File

@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.bot.command
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.data.TelegramStickers import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.{Message, Update} import com.pengrad.telegrambot.model.{Message, Update}
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.{SendMessage, SendSticker} import com.pengrad.telegrambot.request.{SendMessage, SendSticker}
@ -48,7 +49,7 @@ class 喵呜 (using coeur: MornyCoeur) {
override val paramRule: String = "" override val paramRule: String = ""
override val description: String = "抽取一个神秘盒子" override val description: String = "抽取一个神秘盒子"
override def execute (using command: InputCommand, event: Update): Unit = { override def execute (using command: InputCommand, event: Update): Unit = {
coeur.extra exec new SendSticker( coeur.account exec new SendSticker(
event.message.chat.id, event.message.chat.id,
TelegramStickers ID_PROGYNOVA TelegramStickers ID_PROGYNOVA
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
@ -58,7 +59,7 @@ class 喵呜 (using coeur: MornyCoeur) {
private def replyingSet (whileRec: String, whileNew: String)(using event: Update): Unit = { private def replyingSet (whileRec: String, whileNew: String)(using event: Update): Unit = {
val isNew = event.message.replyToMessage == null val isNew = event.message.replyToMessage == null
val target = if (isNew) event.message else event.message.replyToMessage val target = if (isNew) event.message else event.message.replyToMessage
coeur.extra exec new SendMessage( coeur.account exec new SendMessage(
event.message.chat.id, event.message.chat.id,
if (isNew) whileNew else whileRec if (isNew) whileNew else whileRec
).replyToMessageId(target.messageId).parseMode(ParseMode HTML) ).replyToMessageId(target.messageId).parseMode(ParseMode HTML)

View File

@ -4,6 +4,7 @@ import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.UseMath.over import cc.sukazyo.cono.morny.util.UseMath.over
import cc.sukazyo.cono.morny.util.UseRandom.* import cc.sukazyo.cono.morny.util.UseRandom.*
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.request.SendMessage import com.pengrad.telegrambot.request.SendMessage
@ -17,7 +18,7 @@ class 私わね (using coeur: MornyCoeur) extends ISimpleCommand {
if ((1 over 521) chance_is true) { if ((1 over 521) chance_is true) {
val text = "/打假" val text = "/打假"
coeur.extra exec new SendMessage( coeur.account exec new SendMessage(
event.message.chat.id, event.message.chat.id,
text text
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)

View File

@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.bot.event
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.bot.api.EventListener import cc.sukazyo.cono.morny.bot.api.EventListener
import cc.sukazyo.cono.morny.bot.query.{InlineQueryUnit, MornyQueries} import cc.sukazyo.cono.morny.bot.query.{InlineQueryUnit, MornyQueries}
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.InlineQueryResult import com.pengrad.telegrambot.model.request.InlineQueryResult
import com.pengrad.telegrambot.request.AnswerInlineQuery import com.pengrad.telegrambot.request.AnswerInlineQuery
@ -28,7 +29,7 @@ class MornyOnInlineQuery (using queryManager: MornyQueries) (using coeur: MornyC
if (results isEmpty) return false if (results isEmpty) return false
coeur.extra exec AnswerInlineQuery( coeur.account exec AnswerInlineQuery(
update.inlineQuery.id, resultAnswers toArray:_* update.inlineQuery.id, resultAnswers toArray:_*
).cacheTime(cacheTime).isPersonal(isPersonal) ).cacheTime(cacheTime).isPersonal(isPersonal)
true true

View File

@ -4,6 +4,7 @@ import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.bot.api.EventListener import cc.sukazyo.cono.morny.bot.api.EventListener
import cc.sukazyo.cono.morny.data.TelegramStickers import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.* import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.*
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.{Chat, Message, Update, User} import com.pengrad.telegrambot.model.{Chat, Message, Update, User}
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.{ForwardMessage, GetChat, SendMessage, SendSticker} import com.pengrad.telegrambot.request.{ForwardMessage, GetChat, SendMessage, SendSticker}
@ -32,7 +33,7 @@ class OnCallMe (using coeur: MornyCoeur) extends EventListener {
case _ => case _ =>
return false return false
coeur.extra exec SendSticker( coeur.account exec SendSticker(
update.message.chat.id, update.message.chat.id,
TelegramStickers ID_SENT TelegramStickers ID_SENT
).replyToMessageId(update.message.messageId) ).replyToMessageId(update.message.messageId)
@ -41,7 +42,7 @@ class OnCallMe (using coeur: MornyCoeur) extends EventListener {
} }
private def requestItem (user: User, itemHTML: String, extra: String|Null = null): Unit = private def requestItem (user: User, itemHTML: String, extra: String|Null = null): Unit =
coeur.extra exec SendMessage( coeur.account exec SendMessage(
me, me,
s"""request $itemHTML s"""request $itemHTML
|from ${user.fullnameRefHTML}${if extra == null then "" else "\n"+extra}""" |from ${user.fullnameRefHTML}${if extra == null then "" else "\n"+extra}"""
@ -54,8 +55,8 @@ class OnCallMe (using coeur: MornyCoeur) extends EventListener {
if (coeur.trusted isTrusted_dinnerReader req.from.id) { if (coeur.trusted isTrusted_dinnerReader req.from.id) {
// todo: have issues // todo: have issues
// i dont want to test it anymore... it might be deprecated soon // i dont want to test it anymore... it might be deprecated soon
lastDinnerData = (coeur.extra exec GetChat(coeur.config.dinnerChatId)).chat.pinnedMessage lastDinnerData = (coeur.account exec GetChat(coeur.config.dinnerChatId)).chat.pinnedMessage
val sendResp = coeur.extra exec ForwardMessage( val sendResp = coeur.account exec ForwardMessage(
req.from.id, req.from.id,
lastDinnerData.forwardFromChat.id, lastDinnerData.forwardFromChat.id,
lastDinnerData.forwardFromMessageId lastDinnerData.forwardFromMessageId
@ -63,7 +64,7 @@ class OnCallMe (using coeur: MornyCoeur) extends EventListener {
import cc.sukazyo.cono.morny.util.CommonFormat.{formatDate, formatDuration} import cc.sukazyo.cono.morny.util.CommonFormat.{formatDate, formatDuration}
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
def lastDinner_dateMillis: Long = lastDinnerData.forwardDate longValue; def lastDinner_dateMillis: Long = lastDinnerData.forwardDate longValue;
coeur.extra exec SendMessage( coeur.account exec SendMessage(
req.from.id, req.from.id,
"<i>on</i> <code>%s [UTC+8]</code>\n- <code>%s</code> <i>before</i>".formatted( "<i>on</i> <code>%s [UTC+8]</code>\n- <code>%s</code> <i>before</i>".formatted(
h(formatDate(lastDinner_dateMillis, 8)), h(formatDate(lastDinner_dateMillis, 8)),
@ -72,7 +73,7 @@ class OnCallMe (using coeur: MornyCoeur) extends EventListener {
).parseMode(ParseMode HTML).replyToMessageId(sendResp.message.messageId) ).parseMode(ParseMode HTML).replyToMessageId(sendResp.message.messageId)
isAllowed = true isAllowed = true
} else { } else {
coeur.extra exec SendSticker( coeur.account exec SendSticker(
req.from.id, req.from.id,
TelegramStickers ID_403 TelegramStickers ID_403
).replyToMessageId(req.messageId) ).replyToMessageId(req.messageId)
@ -87,6 +88,6 @@ class OnCallMe (using coeur: MornyCoeur) extends EventListener {
private def requestCustom (message: Message): Unit = private def requestCustom (message: Message): Unit =
requestItem(message.from, "<u>[???]</u>") requestItem(message.from, "<u>[???]</u>")
coeur.extra exec ForwardMessage(me, message.chat.id, message.messageId) coeur.account exec ForwardMessage(me, message.chat.id, message.messageId)
} }

View File

@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.bot.event
import cc.sukazyo.cono.morny.bot.api.EventListener import cc.sukazyo.cono.morny.bot.api.EventListener
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.data.TelegramStickers import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.{Chat, Message, MessageEntity, Update} import com.pengrad.telegrambot.model.{Chat, Message, MessageEntity, Update}
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.{GetChat, SendMessage, SendSticker} import com.pengrad.telegrambot.request.{GetChat, SendMessage, SendSticker}
@ -60,7 +61,7 @@ class OnCallMsgSend (using coeur: MornyCoeur) extends EventListener {
if !(message.text startsWith "*msg") then return false if !(message.text startsWith "*msg") then return false
if (!(coeur.trusted isTrusted message.from.id)) if (!(coeur.trusted isTrusted message.from.id))
coeur.extra exec SendSticker( coeur.account exec SendSticker(
message.chat.id, message.chat.id,
TelegramStickers ID_403 TelegramStickers ID_403
).replyToMessageId(message.messageId) ).replyToMessageId(message.messageId)
@ -74,12 +75,12 @@ class OnCallMsgSend (using coeur: MornyCoeur) extends EventListener {
val sendResponse = coeur.account execute messageToSend.toSendMessage() val sendResponse = coeur.account execute messageToSend.toSendMessage()
if (sendResponse isOk) { if (sendResponse isOk) {
coeur.extra exec SendSticker( coeur.account exec SendSticker(
update.message.chat.id, update.message.chat.id,
TelegramStickers ID_SENT TelegramStickers ID_SENT
).replyToMessageId(update.message.messageId) ).replyToMessageId(update.message.messageId)
} else { } else {
coeur.extra exec SendMessage( coeur.account exec SendMessage(
update.message.chat.id, update.message.chat.id,
// language=html // language=html
s"""<b><u>${sendResponse.errorCode} FAILED</u></b> s"""<b><u>${sendResponse.errorCode} FAILED</u></b>
@ -113,12 +114,12 @@ class OnCallMsgSend (using coeur: MornyCoeur) extends EventListener {
s"""<i><u>${h(chat.id toString)}</u>@${h(chat.`type`.name)}</i>${if (chat.`type` != Chat.Type.Private) ":::" else ""} s"""<i><u>${h(chat.id toString)}</u>@${h(chat.`type`.name)}</i>${if (chat.`type` != Chat.Type.Private) ":::" else ""}
|${chat.typeTag} <b>${h(chat.safe_name)}</b> ${chat.safe_linkHTML}""" |${chat.typeTag} <b>${h(chat.safe_name)}</b> ${chat.safe_linkHTML}"""
.stripMargin .stripMargin
coeur.extra exec SendMessage( coeur.account exec SendMessage(
update.message.chat.id, update.message.chat.id,
getChatDescriptionHTML(targetChatResponse.chat) getChatDescriptionHTML(targetChatResponse.chat)
).parseMode(ParseMode HTML).replyToMessageId(update.message.messageId) ).parseMode(ParseMode HTML).replyToMessageId(update.message.messageId)
} else { } else {
coeur.extra exec SendMessage( coeur.account exec SendMessage(
update.message.chat.id, update.message.chat.id,
// language=html // language=html
s"""<b><u>${targetChatResponse.errorCode} FAILED</u></b> s"""<b><u>${targetChatResponse.errorCode} FAILED</u></b>
@ -131,7 +132,7 @@ class OnCallMsgSend (using coeur: MornyCoeur) extends EventListener {
val testSendResponse = coeur.account execute messageToSend.toSendMessage(update.message.chat.id) val testSendResponse = coeur.account execute messageToSend.toSendMessage(update.message.chat.id)
.replyToMessageId(update.message.messageId) .replyToMessageId(update.message.messageId)
if (!(testSendResponse isOk)) if (!(testSendResponse isOk))
coeur.extra exec SendMessage( coeur.account exec SendMessage(
update.message.chat.id, update.message.chat.id,
// language=html // language=html
s"""<b><u>${testSendResponse.errorCode}</u> FAILED</b> s"""<b><u>${testSendResponse.errorCode}</u> FAILED</b>
@ -144,7 +145,7 @@ class OnCallMsgSend (using coeur: MornyCoeur) extends EventListener {
} }
private def answer404 (using update: Update): Boolean = private def answer404 (using update: Update): Boolean =
coeur.extra exec SendSticker( coeur.account exec SendSticker(
update.message.chat.id, update.message.chat.id,
TelegramStickers ID_404 TelegramStickers ID_404
).replyToMessageId(update.message.messageId) ).replyToMessageId(update.message.messageId)

View File

@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.bot.event
import cc.sukazyo.cono.morny.bot.api.EventListener import cc.sukazyo.cono.morny.bot.api.EventListener
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.bot.event.OnQuestionMarkReply.isAllMessageMark import cc.sukazyo.cono.morny.bot.event.OnQuestionMarkReply.isAllMessageMark
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.request.SendMessage import com.pengrad.telegrambot.request.SendMessage
@ -19,7 +20,7 @@ class OnQuestionMarkReply (using coeur: MornyCoeur) extends EventListener {
if (1 over 8) chance_is false then return false if (1 over 8) chance_is false then return false
if !isAllMessageMark(using event.message.text) then return false if !isAllMessageMark(using event.message.text) then return false
coeur.extra exec SendMessage( coeur.account exec SendMessage(
event.message.chat.id, event.message.text event.message.chat.id, event.message.text
).replyToMessageId(event.message.messageId) ).replyToMessageId(event.message.messageId)
true true

View File

@ -2,6 +2,7 @@ package cc.sukazyo.cono.morny.bot.event
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.bot.api.EventListener import cc.sukazyo.cono.morny.bot.api.EventListener
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.request.SendMessage import com.pengrad.telegrambot.request.SendMessage
@ -30,7 +31,7 @@ class OnUserRandom (using coeur: MornyCoeur) extends EventListener {
if result == null then return false if result == null then return false
coeur.extra exec SendMessage( coeur.account exec SendMessage(
update.message.chat.id, result update.message.chat.id, result
).replyToMessageId(update.message.messageId) ).replyToMessageId(update.message.messageId)
true true

View File

@ -5,6 +5,7 @@ import cc.sukazyo.cono.morny.bot.api.EventListener
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.* import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.*
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
import cc.sukazyo.cono.morny.util.UniversalCommand import cc.sukazyo.cono.morny.util.UniversalCommand
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.SendMessage import com.pengrad.telegrambot.request.SendMessage
@ -58,7 +59,7 @@ class OnUserSlashAction (using coeur: MornyCoeur) extends EventListener {
origin origin
else update.message.replyToMessage else update.message.replyToMessage
coeur.extra exec SendMessage( coeur.account exec SendMessage(
update.message.chat.id, update.message.chat.id,
"%s %s%s %s %s!".format( "%s %s%s %s %s!".format(
origin.sender_firstnameRefHTML, origin.sender_firstnameRefHTML,

View File

@ -2,6 +2,7 @@ package cc.sukazyo.cono.morny.daemon
import cc.sukazyo.cono.morny.Log.logger import cc.sukazyo.cono.morny.Log.logger
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
@ -38,7 +39,7 @@ class EventHacker (using coeur: MornyCoeur) {
else return false else return false
logger debug s"hacked event by $x" logger debug s"hacked event by $x"
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
coeur.extra exec SendMessage( coeur.account exec SendMessage(
x.from_chat, x.from_chat,
// language=html // language=html
s"<code>${h(GsonBuilder().setPrettyPrinting().create.toJson(update))}</code>" s"<code>${h(GsonBuilder().setPrettyPrinting().create.toJson(update))}</code>"

View File

@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.daemon
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger} import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.daemon.MedicationTimer.calcNextRoutineTimestamp import cc.sukazyo.cono.morny.daemon.MedicationTimer.calcNextRoutineTimestamp
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.pengrad.telegrambot.model.{Message, MessageEntity} import com.pengrad.telegrambot.model.{Message, MessageEntity}
import com.pengrad.telegrambot.request.{EditMessageText, SendMessage} import com.pengrad.telegrambot.request.{EditMessageText, SendMessage}
import com.pengrad.telegrambot.response.SendResponse import com.pengrad.telegrambot.response.SendResponse
@ -49,7 +50,7 @@ class MedicationTimer (using coeur: MornyCoeur) extends Thread {
} }
private def sendNotification(): Unit = { private def sendNotification(): Unit = {
val sendResponse: SendResponse = coeur.extra exec SendMessage(notify_toChat, NOTIFY_MESSAGE) val sendResponse: SendResponse = coeur.account exec SendMessage(notify_toChat, NOTIFY_MESSAGE)
if sendResponse isOk then lastNotify_messageId = sendResponse.message.messageId if sendResponse isOk then lastNotify_messageId = sendResponse.message.messageId
else lastNotify_messageId = null else lastNotify_messageId = null
} }
@ -66,7 +67,7 @@ class MedicationTimer (using coeur: MornyCoeur) extends Thread {
val entities = ArrayBuffer.empty[MessageEntity] val entities = ArrayBuffer.empty[MessageEntity]
if edited.entities ne null then entities ++= edited.entities if edited.entities ne null then entities ++= edited.entities
entities += MessageEntity(MessageEntity.Type.italic, edited.text.length + "\n-- ".length, editTime.length) entities += MessageEntity(MessageEntity.Type.italic, edited.text.length + "\n-- ".length, editTime.length)
coeur.extra exec EditMessageText( coeur.account exec EditMessageText(
notify_toChat, notify_toChat,
edited.messageId, edited.messageId,
edited.text + s"\n-- $editTime --" edited.text + s"\n-- $editTime --"

View File

@ -13,21 +13,19 @@ class MornyDaemons (using val coeur: MornyCoeur) {
logger info "ALL Morny Daemons starting..." logger info "ALL Morny Daemons starting..."
// TrackerDataManager.init(); // TrackerDataManager.init();
medicationTimer.start() medicationTimer.start()
reporter.onMornyLogin()
logger info "Morny Daemons started." logger info "Morny Daemons started."
} }
def stop (): Unit = { def stop (): Unit = {
logger.info("ALL Morny Daemons stopping...") logger.info("stopping All Morny Daemons...")
// TrackerDataManager.DAEMON.interrupt(); // TrackerDataManager.DAEMON.interrupt();
medicationTimer.interrupt() medicationTimer.interrupt()
// TrackerDataManager.trackingLock.lock(); // TrackerDataManager.trackingLock.lock();
try { medicationTimer.join() } try { medicationTimer.join() }
catch case e: InterruptedException => catch case e: InterruptedException =>
e.printStackTrace(System.out) e.printStackTrace(System.out)
reporter.onMornyExit() logger.info("stopped ALL Morny Daemons.")
logger.info("ALL Morny Daemons STOPPED.")
} }
} }

View File

@ -2,11 +2,11 @@ package cc.sukazyo.cono.morny.daemon
import cc.sukazyo.cono.morny.{MornyCoeur, MornyConfig} import cc.sukazyo.cono.morny.{MornyCoeur, MornyConfig}
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger} import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
import cc.sukazyo.cono.morny.bot.command.MornyInformation
import cc.sukazyo.cono.morny.data.MornyInformation.getVersionAllFullTagHTML import cc.sukazyo.cono.morny.data.MornyInformation.getVersionAllFullTagHTML
import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.* import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.*
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.model.User import com.pengrad.telegrambot.model.User
@ -17,7 +17,7 @@ class MornyReport (using coeur: MornyCoeur) {
private def executeReport[T <: BaseRequest[T, R], R<: BaseResponse] (report: T): Unit = { private def executeReport[T <: BaseRequest[T, R], R<: BaseResponse] (report: T): Unit = {
try { try {
coeur.extra exec report coeur.account exec report
} catch case e: EventRuntimeException.ActionFailed => { } catch case e: EventRuntimeException.ActionFailed => {
logger warn logger warn
s"""cannot execute report to telegram: s"""cannot execute report to telegram:
@ -56,7 +56,7 @@ class MornyReport (using coeur: MornyCoeur) {
).parseMode(ParseMode HTML)) ).parseMode(ParseMode HTML))
} }
def onMornyLogin(): Unit = { def reportCoeurMornyLogin(): Unit = {
executeReport(SendMessage( executeReport(SendMessage(
coeur.config.reportToChat, coeur.config.reportToChat,
// language=html // language=html
@ -99,7 +99,7 @@ class MornyReport (using coeur: MornyCoeur) {
echo dropRight 1 toString echo dropRight 1 toString
} }
def onMornyExit (): Unit = { def reportCoeurExit (): Unit = {
val causedTag = coeur.exitReason match val causedTag = coeur.exitReason match
case u: User => u.fullnameRefHTML case u: User => u.fullnameRefHTML
case n if n == null => "UNKNOWN reason" case n if n == null => "UNKNOWN reason"

View File

@ -1,88 +0,0 @@
package cc.sukazyo.cono.morny.util.tgapi;
import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException;
import com.pengrad.telegrambot.TelegramBot;
import com.pengrad.telegrambot.model.Chat;
import com.pengrad.telegrambot.model.ChatMember;
import com.pengrad.telegrambot.model.User;
import com.pengrad.telegrambot.request.BaseRequest;
import com.pengrad.telegrambot.request.GetChatMember;
import com.pengrad.telegrambot.response.BaseResponse;
public class ExtraAction {
private final TelegramBot bot;
public ExtraAction (TelegramBot bot) {
this.bot = bot;
}
public static ExtraAction as (TelegramBot bot) {
return new ExtraAction(bot);
}
public boolean isUserInGroup (User user, Chat chat) {
return isUserInGroup(user.id(), chat.id());
}
public <T extends BaseRequest<T, R>, R extends BaseResponse> R exec (T req) {
return exec(req, "");
}
public <T extends BaseRequest<T, R>, R extends BaseResponse> R exec (T req, String errorMessage) {
final R resp = bot.execute(req);
if (!resp.isOk()) throw new EventRuntimeException.ActionFailed(
(errorMessage.isEmpty() ? String.valueOf(resp.errorCode()) : errorMessage),
resp
);
return resp;
}
public boolean isUserInGroup (User user, Chat chat, ChatMember.Status permissionLevel) {
return isUserInGroup(user.id(), chat.id(), permissionLevel);
}
public boolean isUserInGroup (long userId, long chatId) {
return isUserInGroup(userId, chatId, ChatMember.Status.restricted);
}
public boolean isUserInGroup (long userId, long chatId, ChatMember.Status permissionLevel) {
final ChatMember chatMember = exec(new GetChatMember(chatId, userId)).chatMember();
return
chatMember != null &&
UserPermissionLevel.as(chatMember.status()).hasPermission(UserPermissionLevel.as(permissionLevel));
}
}
enum UserPermissionLevel {
CREATOR(3),
ADMINISTRATOR(2),
MEMBER(1),
RESTRICTED(0),
LEFT(-1),
KICKED(-2);
final int permissionLevel;
UserPermissionLevel (int permissionLevel) {
this.permissionLevel = permissionLevel;
}
static UserPermissionLevel as (ChatMember.Status status) {
return switch (status) {
case creator -> CREATOR;
case administrator -> ADMINISTRATOR;
case member -> MEMBER;
case restricted -> RESTRICTED;
case left -> LEFT;
case kicked -> KICKED;
};
}
boolean hasPermission (UserPermissionLevel required) {
return this.permissionLevel >= required.permissionLevel;
}
}

View File

@ -0,0 +1,68 @@
package cc.sukazyo.cono.morny.util.tgapi
import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException
import com.pengrad.telegrambot.TelegramBot
import com.pengrad.telegrambot.model.{Chat, ChatMember, User}
import com.pengrad.telegrambot.request.{BaseRequest, GetChatMember}
import com.pengrad.telegrambot.response.BaseResponse
import scala.annotation.targetName
object TelegramExtensions {
object Bot { extension (bot: TelegramBot) {
def exec [T <: BaseRequest[T, R], R <: BaseResponse] (request: T, onError_message: String = ""): R = {
val response = bot execute request
if response isOk then return response
throw EventRuntimeException.ActionFailed(
if onError_message isEmpty then response.errorCode toString else onError_message,
response
)
}
}}
object Chat { extension (chat: Chat) {
def hasMember (user: User) (using TelegramBot): Boolean =
memberHasPermission(user, ChatMember.Status.member)
def memberHasPermission (user: User, permission: ChatMember.Status) (using bot: TelegramBot): Boolean = {
//noinspection ScalaUnusedSymbol
enum UserPermissionLevel(val level: Int):
private case CREATOR extends UserPermissionLevel(10)
private case ADMINISTRATOR extends UserPermissionLevel(3)
private case MEMBER extends UserPermissionLevel(1)
private case RESTRICTED extends UserPermissionLevel(-1)
private case LEFT extends UserPermissionLevel(-3)
private case KICKED extends UserPermissionLevel(-5)
@targetName("equalOrGreaterThan")
def >= (another: UserPermissionLevel): Boolean = this.level >= another.level
object UserPermissionLevel:
def apply(status: ChatMember.Status): UserPermissionLevel =
status match
case ChatMember.Status.creator => CREATOR
case ChatMember.Status.administrator => ADMINISTRATOR
case ChatMember.Status.member => MEMBER
case ChatMember.Status.restricted => RESTRICTED
case ChatMember.Status.left => LEFT
case ChatMember.Status.kicked => KICKED
def apply (chatMember: ChatMember): UserPermissionLevel = apply(chatMember.status)
import Bot.*
val chatMember: ChatMember = (bot exec GetChatMember(chat.id, user.id)).chatMember
if chatMember eq null then false
else UserPermissionLevel(chatMember) >= UserPermissionLevel(permission)
}
}}
class LimboUser (id: Long) extends User(id)
class LimboChat (val _id: Long) extends Chat() {
override val id: java.lang.Long = _id
}
}