mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-22 11:14:55 +08:00
scaladoc update, and added Update.sourceTime
This commit is contained in:
parent
456273be96
commit
9cc8b49459
@ -8,7 +8,7 @@ object MornyConfiguration {
|
||||
val MORNY_CODE_STORE = "https://github.com/Eyre-S/Coeur-Morny-Cono"
|
||||
val MORNY_COMMIT_PATH = "https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s"
|
||||
|
||||
val VERSION = "2.0.0-alpha12"
|
||||
val VERSION = "2.0.0-alpha13"
|
||||
val VERSION_DELTA: Option[String] = None
|
||||
val CODENAME = "guanggu"
|
||||
|
||||
|
@ -3,3 +3,4 @@ addSbtPlugin("no.arktekk.sbt" % "aether-deploy" % "0.29.1")
|
||||
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0")
|
||||
addSbtPlugin("com.github.sbt" % "sbt-git" % "2.0.1")
|
||||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.5")
|
||||
//addSbtPlugin("com.glngn" % "sbt-alldocs" % "0.3.0")
|
||||
|
@ -24,7 +24,7 @@ object MornyCoeur {
|
||||
/** A tag that shows current [[MornyCoeur!]] is running under
|
||||
* test mode.
|
||||
*
|
||||
* @see [[MornyCoeur.testRun]] for more introduction for test mode.
|
||||
* @see *Test Mode* in [[MornyCoeur]] for more introduction for test mode.
|
||||
* @since 2.0.0
|
||||
*/
|
||||
object TestRun
|
||||
@ -88,7 +88,7 @@ object MornyCoeur {
|
||||
*
|
||||
* ## Lifecycle
|
||||
*
|
||||
* todo...
|
||||
* todo
|
||||
*
|
||||
* ## Test Mode
|
||||
*
|
||||
|
@ -4,7 +4,7 @@ trait EventListener () {
|
||||
|
||||
/** Determine if this event listener should be processed.
|
||||
*
|
||||
* Default implementation is it only be [[true]] when the event
|
||||
* Default implementation is it only be `true` when the event
|
||||
* is not ok yet (when [[EventEnv.isEventOk]] is false).
|
||||
*
|
||||
* Notice that: You should not override this method to filter some
|
||||
@ -13,7 +13,7 @@ trait EventListener () {
|
||||
* method is just for event low-level controls.
|
||||
*
|
||||
* @param env The [[EventEnv event variable]].
|
||||
* @return [[true]] if this event listener should run; [[false]]
|
||||
* @return `true` if this event listener should run; `false`
|
||||
* if it should not run.
|
||||
*/
|
||||
def executeFilter (using env: EventEnv): Boolean =
|
||||
|
@ -11,7 +11,7 @@ import com.pengrad.telegrambot.UpdatesListener
|
||||
import scala.collection.mutable
|
||||
import scala.language.postfixOps
|
||||
|
||||
/** Contains a [[mutable.Queue]] of [[EventListener]], and delivery telegram [[Update]].
|
||||
/** Contains a [[scala.collection.mutable.Queue]] of [[EventListener]], and delivery telegram [[Update]].
|
||||
*
|
||||
* Implemented [[process]] in [[UpdatesListener]] so it can directly used in [[com.pengrad.telegrambot.TelegramBot.setupListener]].
|
||||
*
|
||||
|
@ -2,16 +2,26 @@ package cc.sukazyo.cono.morny.core.bot.event
|
||||
|
||||
import cc.sukazyo.cono.morny.core.MornyCoeur
|
||||
import cc.sukazyo.cono.morny.core.bot.api.{EventEnv, EventListener}
|
||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Update.sourceTime
|
||||
import cc.sukazyo.cono.morny.util.EpochDateTime.EpochMillis
|
||||
|
||||
class MornyOnUpdateTimestampOffsetLock (using coeur: MornyCoeur) extends EventListener {
|
||||
|
||||
private def checkOutdated (timestamp: Int)(using event: EventEnv): Unit =
|
||||
if coeur.config.eventIgnoreOutdated && (timestamp < (coeur.coeurStartTimestamp/1000)) then
|
||||
event.setEventCanceled
|
||||
override def executeFilter (using env: EventEnv): Boolean =
|
||||
if (
|
||||
(env.update.message != null) ||
|
||||
(env.update.editedMessage != null) ||
|
||||
(env.update.channelPost != null) ||
|
||||
(env.update.editedChannelPost != null)
|
||||
)
|
||||
true
|
||||
else false
|
||||
|
||||
override def onMessage (using event: EventEnv): Unit = checkOutdated(event.update.message.date)
|
||||
override def onEditedMessage (using event: EventEnv): Unit = checkOutdated(event.update.editedMessage.date)
|
||||
override def onChannelPost (using event: EventEnv): Unit = checkOutdated(event.update.channelPost.date)
|
||||
override def onEditedChannelPost (using event: EventEnv): Unit = checkOutdated(event.update.editedChannelPost.date)
|
||||
override def on (using event: EventEnv): Unit =
|
||||
event.update.sourceTime match
|
||||
case Some(timestamp) =>
|
||||
if coeur.config.eventIgnoreOutdated && (EpochMillis.fromEpochSeconds(timestamp) < coeur.coeurStartTimestamp) then
|
||||
event.setEventCanceled
|
||||
case None =>
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import cats.effect.IO
|
||||
import cc.sukazyo.cono.morny.core.http.api.HttpService4Api
|
||||
import cc.sukazyo.cono.morny.data.TelegramImages
|
||||
import org.http4s.{HttpRoutes, MediaType}
|
||||
import org.http4s.dsl.impl./
|
||||
import org.http4s.dsl.io.*
|
||||
import org.http4s.headers.`Content-Type`
|
||||
|
||||
|
@ -11,7 +11,7 @@ import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtm
|
||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
|
||||
import cc.sukazyo.cono.morny.util.EpochDateTime.DurationMillis
|
||||
import cc.sukazyo.cono.morny.util.schedule.CronTask
|
||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Update.{extractSourceChat, extractSourceUser}
|
||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Update.{sourceChat, sourceUser}
|
||||
import cc.sukazyo.cono.morny.util.CommonEncrypt.hashId
|
||||
import cc.sukazyo.cono.morny.util.ConvertByteHex.toHex
|
||||
import com.cronutils.builder.CronBuilder
|
||||
@ -206,9 +206,9 @@ class MornyReport (using coeur: MornyCoeur) {
|
||||
override def atEventPost (using event: EventEnv): Unit = {
|
||||
import event.*
|
||||
eventTotal += 1
|
||||
event.update.extractSourceChat match
|
||||
event.update.sourceChat match
|
||||
case None =>
|
||||
event.update.extractSourceUser match
|
||||
event.update.sourceUser match
|
||||
case None =>
|
||||
case Some(user) =>
|
||||
event_from_user_action << hashId(user.id).toHex
|
||||
|
@ -11,18 +11,18 @@ import io.circe.{DecodingFailure, ParsingFailure}
|
||||
*
|
||||
* @see [[https://github.com/FixTweet/FixTweet/wiki/Status-Fetch-API]]
|
||||
*
|
||||
* @param code Status code, normally be [[200]], but can be 401
|
||||
* or [[404]] or [[500]] due to different reasons.
|
||||
* @param code Status code, normally be `200`, but can be 401
|
||||
* or `404` or `500` due to different reasons.
|
||||
*
|
||||
* Related to [[message]]
|
||||
* @param message Status message.
|
||||
*
|
||||
* - When [[code]] is [[200]], it should be `OK`
|
||||
* - When [[code]] is [[401]], it should be `PRIVATE_TWEET`,
|
||||
* - When [[code]] is `200`, it should be `OK`
|
||||
* - When [[code]] is `401`, it should be `PRIVATE_TWEET`,
|
||||
* while in practice, it seems PRIVATE_TWEET will
|
||||
* just return [[404]].
|
||||
* - When [[code]] is [[404]], it should be `NOT_FOUND`
|
||||
* - When [[code]] is [[500]], it should be `API_FILE`
|
||||
* just return `404`.
|
||||
* - When [[code]] is `404`, it should be `NOT_FOUND`
|
||||
* - When [[code]] is `500`, it should be `API_FILE`
|
||||
* @param tweet [[FXTweet]] content.
|
||||
* @since 1.3.0
|
||||
* @version 2023.11.21
|
||||
@ -86,7 +86,7 @@ object FXApi {
|
||||
* @throws DecodingFailure When cannot decode the API response to a [[FXApi]]
|
||||
* object. It might be some wrong with the [[FXApi]]
|
||||
* model, or the remote API spec changes.
|
||||
* @return a [[FXApi]] response object, with [[200]] or any other response code.
|
||||
* @return a [[FXApi]] response object, with `200` or any other response code.
|
||||
*/
|
||||
@throws[SttpClientException|ParsingFailure|DecodingFailure]
|
||||
def status (screen_name: Option[String], id: String, translate_to: Option[String] = None): FXApi =
|
||||
|
@ -12,8 +12,8 @@ class HackerEventHandler (using hacker: EventHacker)(using coeur: MornyCoeur) ex
|
||||
override def on (using event: EventEnv): Unit =
|
||||
given update: Update = event.update
|
||||
if hacker.trigger(
|
||||
update.extractSourceChat.map[Long](_.id).getOrElse(0),
|
||||
update.extractSourceUser.map[Long](_.id).getOrElse(0)
|
||||
update.sourceChat.map[Long](_.id).getOrElse(0),
|
||||
update.sourceUser.map[Long](_.id).getOrElse(0)
|
||||
) then
|
||||
event.setEventOk
|
||||
|
||||
|
@ -33,7 +33,7 @@ object CommonFormat {
|
||||
* @param utcOffset the hour offset of the time zone, the time-zone controls
|
||||
* which local time describe will use.
|
||||
*
|
||||
* for example, timestamp [[0]] describes 1970-1-1 00:00:00 in
|
||||
* for example, timestamp `0` describes 1970-1-1 00:00:00 in
|
||||
* UTC+0, so, use the `timestamp` `0` and `utfOffset` `0` will
|
||||
* returns `"1970-1-1 00:00:00:000"`; however, at the same time,
|
||||
* in UTC+8, the local time is 1970-1-1 08:00:00:000, so use
|
||||
|
@ -43,7 +43,7 @@ trait RoutineTask extends Task {
|
||||
*
|
||||
* @param previousRoutineScheduledTimeMillis The previous task routine's
|
||||
* scheduled time.
|
||||
* @return The next task routine's scheduled time, or [[null]] means end
|
||||
* @return The next task routine's scheduled time, or `null` means end
|
||||
* of the task.
|
||||
*/
|
||||
def nextRoutineTimeMillis (previousRoutineScheduledTimeMillis: EpochMillis): EpochMillis|Null
|
||||
|
@ -151,7 +151,7 @@ class Scheduler {
|
||||
schedule(task)
|
||||
this
|
||||
/** Add one task to scheduler task queue.
|
||||
* @return [[true]] if the task is added.
|
||||
* @return `true` if the task is added.
|
||||
*/
|
||||
def schedule (task: Task): Boolean =
|
||||
taskList.synchronized:
|
||||
@ -175,7 +175,7 @@ class Scheduler {
|
||||
* If the removal task is running, the method will wait for the current run
|
||||
* complete (and current run post effect complete), then do remove.
|
||||
*
|
||||
* @return [[true]] if the task is in task queue or is running, and have been
|
||||
* @return `true` if the task is in task queue or is running, and have been
|
||||
* succeed removed from task queue.
|
||||
*/
|
||||
def cancel (task: Task): Boolean =
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cc.sukazyo.cono.morny.util.tgapi
|
||||
|
||||
import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException
|
||||
import cc.sukazyo.cono.morny.util.EpochDateTime.{EpochMillis, EpochSeconds}
|
||||
import com.pengrad.telegrambot.TelegramBot
|
||||
import com.pengrad.telegrambot.model.*
|
||||
import com.pengrad.telegrambot.request.{BaseRequest, GetChatMember}
|
||||
@ -12,8 +13,31 @@ object TelegramExtensions {
|
||||
|
||||
object Bot { extension (bot: TelegramBot) {
|
||||
|
||||
/** Try sync execute a [[BaseRequest request]], and throws [[EventRuntimeException]]
|
||||
* when it fails.
|
||||
*
|
||||
* It will use [[Telegram.execute]] to execute the request, and check if the response is failed.
|
||||
*
|
||||
* If the request returned a [[BaseResponse response]], the [[BaseResponse.isOk]] will be checked.
|
||||
* if it is false, the method will ended with a [[EventRuntimeException.ActionFailed]], which
|
||||
* message is param [[onError_message]](or [[BaseResponse.errorCode]] if it is empty).
|
||||
*
|
||||
* If the request failed in the client (that means [[TelegramBot.execute]] call failed with Exceptions),
|
||||
* this method will ended with a [[EventRuntimeException.ClientFailed]].
|
||||
*
|
||||
* @param request The request needed to be run.
|
||||
* @param onError_message The exception message that will be thrown when the [[request]]'s
|
||||
* [[BaseResponse response]] is not ok([[BaseResponse.isOk isOk()]] == false)
|
||||
* @tparam T Type of the request
|
||||
* @tparam R Type of the response that request should returns.
|
||||
* @throws EventRuntimeException Whenever the request's response is not ok, or the request does not
|
||||
* return a response. See above for more info.
|
||||
* @return The succeed response (which is returned by [[TelegramBot.execute]]) as is.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@throws[EventRuntimeException]
|
||||
def exec [T <: BaseRequest[T, R], R <: BaseResponse] (request: T, onError_message: String = ""): R = {
|
||||
def exec [T <: BaseRequest[T, R], R <: BaseResponse] (request: BaseRequest[T, R], onError_message: String = ""): R = {
|
||||
try {
|
||||
val response = bot execute request
|
||||
if response isOk then return response
|
||||
@ -31,7 +55,41 @@ object TelegramExtensions {
|
||||
|
||||
object Update { extension (update: Update) {
|
||||
|
||||
def extractSourceChat: Option[Chat] =
|
||||
/** Get the [[Chat]] that the update comes from.
|
||||
*
|
||||
* For the update types that is non-chat related, or the update types that framework does not
|
||||
* supported yet, this method will return [[None]].
|
||||
*
|
||||
* ### Supported Update Types
|
||||
*
|
||||
* Belows are the supported update types that will return a valid [[Chat]].
|
||||
*
|
||||
* - [[Update.message]]: Chat that the message belongs.
|
||||
* - [[Update.editedMessage]]: Chat that the edited message belongs.
|
||||
* - [[Update.channelPost]]: Chat that the channel post message belongs.
|
||||
* - [[Update.editedChannelPost]]: Chat that the edited channel post message belongs.
|
||||
* - [[Update.callbackQuery]]: Chat that the callback query's source message (a callback query
|
||||
* is triggered from a inline message button, that inline message is the source message) belongs.
|
||||
* - [[Update.myChatMember]]: Chat that where member status of current bot changed there.
|
||||
* - [[Update.chatMember]]: Chat that any one user's member status changed there.
|
||||
* - [[Update.chatJoinRequest]]: Chat that the join request comes from.
|
||||
*
|
||||
* Belows are the known update types that is not chat related, so there's only a [[None]] returned.
|
||||
*
|
||||
* - [[Update.inlineQuery]]
|
||||
* - [[Update.chosenInlineResult]]
|
||||
* - [[Update.shippingQuery]]
|
||||
* - [[Update.preCheckoutQuery]]
|
||||
* - [[Update.poll]]
|
||||
* - [[Update.pollAnswer]]
|
||||
*
|
||||
* Supported up to Telegram Bot API 6.2
|
||||
*
|
||||
* @return An [[Option]] either contains a [[Chat]] that the update comes from, or [[None]] if there's
|
||||
* no user or update type is unsupported.
|
||||
* @since 2.0.0
|
||||
*/
|
||||
def sourceChat: Option[Chat] =
|
||||
if (update.message != null) Some(update.message.chat)
|
||||
else if (update.editedMessage != null) Some(update.editedMessage.chat)
|
||||
else if (update.channelPost != null) Some(update.channelPost.chat)
|
||||
@ -48,7 +106,42 @@ object TelegramExtensions {
|
||||
else if (update.chatJoinRequest != null) Some(update.chatJoinRequest.chat)
|
||||
else None
|
||||
|
||||
def extractSourceUser: Option[User] =
|
||||
/** Get the [[User]] that the update comes from.
|
||||
*
|
||||
* For the update types that is non-user related, or the update types that framework does not
|
||||
* supported yet, this method will return [[None]].
|
||||
*
|
||||
* ### Supported Update Types
|
||||
*
|
||||
* Belows are the supported update types that will return a valid [[User]].
|
||||
*
|
||||
* - [[Update.message]]: User that sent the message.
|
||||
* - [[Update.editedMessage]]: User that sent the message. Notice that is the user who ORIGINAL
|
||||
* SENT the message but NOT EDITED the message due to the API limitation, while in current Bot
|
||||
* API version (v7.0), editing other's message is not allowed so it should have no problem.
|
||||
* - [[Update.inlineQuery]]: User that executing the inline query.
|
||||
* - [[Update.chosenInlineResult]]: User that chosen the inline result of a inline query.
|
||||
* - [[Update.callbackQuery]]: User that triggered the callback query.
|
||||
* - [[Update.shippingQuery]]: User that sent the shipping query.
|
||||
* - [[Update.preCheckoutQuery]]: User that sent the pre-checkout query.
|
||||
* - [[Update.pollAnswer]]: User that answered a un-anonymous poll.
|
||||
* - [[Update.myChatMember]]: Current bot that my member status changed.
|
||||
* - [[Update.chatMember]]: User that their member status changed.
|
||||
* - [[Update.chatJoinRequest]]: User that sent a join request.
|
||||
*
|
||||
* Belows are the known update types that is not user related, so there's only a [[None]] returned.
|
||||
*
|
||||
* - [[Update.channelPost]]
|
||||
* - [[Update.editedChannelPost]]
|
||||
* - [[Update.poll]] <small>(odd, but it is no sender in the latest Bot API 7.0)</small>
|
||||
*
|
||||
* Supported up to Telegram Bot API 6.2
|
||||
*
|
||||
* @return An [[Option]] either contains a [[User]] that the update comes from, or [[None]] if there's
|
||||
* no user or update type is unsupported.
|
||||
* @since 2.0.0
|
||||
*/
|
||||
def sourceUser: Option[User] =
|
||||
if (update.message != null) Some(update.message.from)
|
||||
else if (update.editedMessage != null) Some(update.editedMessage.from)
|
||||
else if (update.channelPost != null) None
|
||||
@ -65,13 +158,113 @@ object TelegramExtensions {
|
||||
else if (update.chatJoinRequest != null) Some(update.chatJoinRequest.from)
|
||||
else None
|
||||
|
||||
/** Date time of the update.
|
||||
*
|
||||
* This date-time is guessed from the update content -- it may not response the accurate or even real
|
||||
* time when the update happens. Some update types contains no related time information, so it can only
|
||||
* returns [[None]].
|
||||
*
|
||||
* Telegram uses UNIX seconds as the time unit, and Java Telegram Bot API (which this project
|
||||
* dependents this) use [[Int]] to store it. so the returned time will be formatted to [[EpochSeconds]]
|
||||
* which also uses UNIX seconds as the time unit, and stored in type [[Int]].
|
||||
*
|
||||
* ### Supported Update Types
|
||||
*
|
||||
* Belows are the supported update types that will return a valid time.
|
||||
*
|
||||
* - [[Update.message]]: Time that the message is sent. Should be fixed and accurate.
|
||||
* - [[Update.editedMessage]]: Time that the message is edited. Can be changed when the message is
|
||||
* edited again, but should be the fixed editing time in the specific update.
|
||||
* - [[Update.channelPost]]: Time that the channel post message is sent. Should be fixed and accurate.
|
||||
* - [[Update.editedChannelPost]]: Time that the channel post message is edited. Same with
|
||||
* [[Update.editedMessage]]
|
||||
* - [[Update.myChatMember]]: Time that the member status of current bot changes done.
|
||||
* - [[Update.chatMember]]: Time that one user's member status changes done.
|
||||
* - [[Update.chatJoinRequest]]: Time that the join request is sent.
|
||||
*
|
||||
* Belows have no any time information, so there's only a [[None]] returned.
|
||||
*
|
||||
* - [[Update.inlineQuery]]
|
||||
* - [[Update.chosenInlineResult]]
|
||||
* - [[Update.callbackQuery]]
|
||||
* - [[Update.shippingQuery]]
|
||||
* - [[Update.preCheckoutQuery]]
|
||||
* - [[Update.poll]]
|
||||
* - [[Update.pollAnswer]]
|
||||
*
|
||||
* Supported up to Telegram Bot API 6.2
|
||||
*
|
||||
* @return An [[Option]] either contains a [[EpochSeconds]] that may be the time when update happens,
|
||||
* or [[None]] if there's unsupported.
|
||||
* @since 2.0.0
|
||||
*/
|
||||
def sourceTime: Option[EpochSeconds] =
|
||||
if (update.message != null) Some(update.message.date)
|
||||
else if (update.editedMessage != null) Some(update.editedMessage.editDate)
|
||||
else if (update.channelPost != null) Some(update.channelPost.date)
|
||||
else if (update.editedChannelPost != null) Some(update.editedChannelPost.editDate)
|
||||
else if (update.inlineQuery != null) None
|
||||
else if (update.chosenInlineResult != null) None
|
||||
else if (update.callbackQuery != null) None
|
||||
else if (update.shippingQuery != null) None
|
||||
else if (update.preCheckoutQuery != null) None
|
||||
else if (update.poll != null) None
|
||||
else if (update.pollAnswer != null) None
|
||||
else if (update.myChatMember != null) Some(update.myChatMember.date)
|
||||
else if (update.chatMember != null) Some(update.chatMember.date)
|
||||
else if (update.chatJoinRequest != null) Some(update.chatJoinRequest.date)
|
||||
else None
|
||||
|
||||
}}
|
||||
|
||||
object Chat { extension (chat: Chat) {
|
||||
|
||||
/** Check if a user is a member of this chat.
|
||||
*
|
||||
* It is equivalent to `memberHasPermission(user, ChatMember.Status.member)`.
|
||||
*
|
||||
* It checks if the user's member status is [[ChatMember.Status.member]], so if the member is in
|
||||
* this chat but they are been [[ChatMember.Status.restricted]], it will be treated as *not a member*.
|
||||
*
|
||||
* It needs to execute a request getting chat member, so it requires a live [[TelegramBot]] instance,
|
||||
* and the bot needs to be a member of this chat so that it can read the chat member.
|
||||
*
|
||||
* **Notice:** This method will execute a request to the Telegram Bot API, so it may be slow.
|
||||
*
|
||||
* @see [[memberHasPermission]]
|
||||
*
|
||||
* @param user The user that want to check if they are a member of this chat.
|
||||
* @return [[true]] when the user is a member of this chat, [[false]] otherwise.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
def hasMember (user: User) (using TelegramBot): Boolean =
|
||||
memberHasPermission(user, ChatMember.Status.member)
|
||||
|
||||
/** Check if a user has a permission level in this chat.
|
||||
*
|
||||
* It checks if the user's member status is equal or greater than the required permission level.
|
||||
*
|
||||
* Due to API does not implemented a permission level system, so inside this method, there's a
|
||||
* permission level table:
|
||||
*
|
||||
* | [[ChatMember.Status]] | Permission Level |
|
||||
* |----------------------|-----------------:|
|
||||
* | [[ChatMember.Status.creator]] | 10 |
|
||||
* | [[ChatMember.Status.administrator]] | 3 |
|
||||
* | [[ChatMember.Status.member]] | 1 |
|
||||
* | [[ChatMember.Status.restricted]] | -1 |
|
||||
* | [[ChatMember.Status.left]] | -3 |
|
||||
* | [[ChatMember.Status.kicked]] | -5 |
|
||||
*
|
||||
* **Notice:** This method will execute a request to the Telegram Bot API, so it may be slow.
|
||||
*
|
||||
* @param user The user that wanted to check if they have the permission.
|
||||
* @param permission The required permission level.
|
||||
* @param bot A live [[TelegramBot]] that will be used to execute the getChatMember request. It
|
||||
* should be a member of this chat so that can read the chat member for this method works.
|
||||
* @return [[true]] if the user have the permission or higher permission, [[false]] otherwise.
|
||||
*/
|
||||
def memberHasPermission (user: User, permission: ChatMember.Status) (using bot: TelegramBot): Boolean = {
|
||||
|
||||
//noinspection ScalaUnusedSymbol
|
||||
|
Loading…
Reference in New Issue
Block a user