Skip to content

Commit 4399f41

Browse files
committed
refactor: messages interfaces
- split ExtendedMessage to ThreadMessage, EffectableMessage and EffectableMessage - getMessageThreadId() implementation fix: - missed messageThreadId param for /sendPaidMedia
1 parent f1102b4 commit 4399f41

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+382
-159
lines changed

lib/lib.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111
}
1212

1313
group = "ru.raysmith"
14-
version = "1.0.0-beta.18"
14+
version = "1.0.0-beta.19"
1515

1616
java {
1717
toolchain {

lib/src/jvmMain/kotlin/ru/raysmith/tgbot/core/Bot.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@ import org.slf4j.Logger
77
import org.slf4j.LoggerFactory
88
import ru.raysmith.tgbot.core.handler.BaseEventHandlerFactory
99
import ru.raysmith.tgbot.core.handler.EventHandlerFactory
10+
import ru.raysmith.tgbot.core.handler.ILocationEventHandlerFactory
1011
import ru.raysmith.tgbot.core.handler.LocationEventHandlerFactory
1112
import ru.raysmith.tgbot.core.handler.base.CommandHandler
13+
import ru.raysmith.tgbot.core.handler.location.LocationCallbackQueryHandler
1214
import ru.raysmith.tgbot.exceptions.BotException
1315
import ru.raysmith.tgbot.model.network.updates.Update
1416
import ru.raysmith.tgbot.network.API
17+
import ru.raysmith.tgbot.network.BadBotTokenException
1518
import ru.raysmith.tgbot.network.TelegramApi
1619
import ru.raysmith.tgbot.network.TelegramApiException
17-
import ru.raysmith.tgbot.network.BadBotTokenException
1820
import ru.raysmith.tgbot.utils.datepicker.DatePicker
1921
import ru.raysmith.tgbot.utils.locations.LocationFlowContext
2022
import ru.raysmith.tgbot.utils.locations.LocationsWrapper
@@ -346,12 +348,9 @@ class Bot(
346348
is BaseEventHandlerFactory -> {
347349
it.handleCallbackQuery(alwaysAnswer, handler = { setupFeatures(datePicker, callFirst = true) })
348350
}
349-
350-
is LocationEventHandlerFactory<*> -> {
351-
it.handleCallbackQuery(alwaysAnswer, handler = { setupFeatures(datePicker, callFirst = true) })
352-
}
353-
354-
else -> return@add
351+
is ILocationEventHandlerFactory<*> -> it.handleCallbackQuery(alwaysAnswer, handler = {
352+
contextOf<LocationCallbackQueryHandler<*>>().setupFeatures(datePicker, callFirst = true)
353+
})
355354
}
356355
}
357356
return this

lib/src/jvmMain/kotlin/ru/raysmith/tgbot/core/ChatIdHolder.kt renamed to lib/src/jvmMain/kotlin/ru/raysmith/tgbot/core/ChatDataHolder.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,8 @@ interface ChatIdHolder {
1313
* The chat id may be null in CallbackQueryHandler when a message is too old
1414
* */
1515
fun getChatIdOrThrow() = getChatId() ?: throw UnknownChatIdException()
16-
}
16+
}
17+
18+
interface ChatDataHolder : ChatIdHolder {
19+
fun getMessageThreadId(): Int?
20+
}

lib/src/jvmMain/kotlin/ru/raysmith/tgbot/core/Extensions.kt

Lines changed: 0 additions & 6 deletions
This file was deleted.

lib/src/jvmMain/kotlin/ru/raysmith/tgbot/core/IEditor.kt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ package ru.raysmith.tgbot.core
22

33
import ru.raysmith.tgbot.core.handler.base.CallbackQueryHandler
44
import ru.raysmith.tgbot.model.bot.ChatId
5+
import ru.raysmith.tgbot.model.bot.message.MessageDsl
56
import ru.raysmith.tgbot.model.bot.message.MessageText
67
import ru.raysmith.tgbot.model.bot.message.MessageWithReplyMarkup
78
import ru.raysmith.tgbot.model.bot.message.TextMessage
89
import ru.raysmith.tgbot.model.bot.message.keyboard.MessageInlineKeyboard
9-
import ru.raysmith.tgbot.model.bot.message.media.CaptionableMediaMessage
1010
import ru.raysmith.tgbot.model.bot.message.media.ExtendedCaptionableMediaMessage
1111
import ru.raysmith.tgbot.model.network.keyboard.InlineKeyboardButton
1212
import ru.raysmith.tgbot.model.network.media.input.InputMedia
@@ -16,7 +16,7 @@ import ru.raysmith.tgbot.network.API
1616
import ru.raysmith.tgbot.utils.pagination.Pagination
1717

1818
/** Represent an object that can edit messages */
19-
interface IEditor : ChatIdHolder, API, BotHolder {
19+
interface IEditor : ChatDataHolder, API, BotHolder {
2020

2121
/** Identifier of the message to be edited */
2222
var messageId: Int?
@@ -75,6 +75,11 @@ interface IEditor : ChatIdHolder, API, BotHolder {
7575
.editMedia(media, chatId, messageId, inlineMessageId)
7676
}
7777

78+
@MessageDsl
79+
suspend fun edit(text: String) = edit { this.text = text }
80+
suspend fun editWithEntities(message: suspend (@MessageDsl MessageText).() -> Unit) = edit {
81+
textWithEntities { message() }
82+
}
7883
suspend fun edit(
7984
chatId: ChatId = getChatIdOrThrow(),
8085
messageId: Int? = this.messageId,
@@ -104,14 +109,17 @@ interface IEditor : ChatIdHolder, API, BotHolder {
104109

105110
private fun CallbackQueryHandler.getPreviousPageButton(pagePrefix: String? = null): InlineKeyboardButton? {
106111
var res: InlineKeyboardButton? = null
107-
when(query.message) {
112+
when (query.message) {
108113
is InaccessibleMessage, null -> {}
109114
is Message -> {
110115
if (query.message.replyMarkup?.keyboard != null) {
111116
keyboard@ for (row in query.message.replyMarkup.keyboard) {
112117
row@ for (button in row) {
113118
if (pagePrefix != null && row.none { it.callbackData?.startsWith(pagePrefix) == true }) break@row
114-
if (button.text.startsWith(Pagination.SYMBOL_CURRENT_PAGE) && button.text.endsWith(Pagination.SYMBOL_CURRENT_PAGE)) {
119+
if (button.text.startsWith(Pagination.SYMBOL_CURRENT_PAGE) && button.text.endsWith(
120+
Pagination.SYMBOL_CURRENT_PAGE
121+
)
122+
) {
115123
res = button
116124
break@keyboard
117125
}
@@ -142,7 +150,7 @@ interface IEditor : ChatIdHolder, API, BotHolder {
142150
else null
143151
}
144152

145-
private fun CallbackQueryHandler.getPreviousPage(pagePrefix: String? = null): Int {
153+
private fun CallbackQueryHandler.getPreviousPage(pagePrefix: String? = null): Int {
146154
return getPreviousPageButton(pagePrefix)?.getPageOrNull() ?: Pagination.PAGE_FIRST
147155
}
148156

lib/src/jvmMain/kotlin/ru/raysmith/tgbot/core/ISender.kt

Lines changed: 107 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,50 +12,89 @@ import ru.raysmith.tgbot.network.API
1212

1313
// TODO [docs] methods
1414
/** Represent an object that can send messages */
15-
interface ISender : ChatIdHolder, API, BotHolder {
15+
interface ISender : ChatDataHolder, API, BotHolder {
1616

17-
// TODO add messageThreadId to ChatIdHolder; rename to ChatDataHolder; add messageThreadId arg to all methods
17+
@MessageDsl
18+
suspend fun send(text: String) = send { this.text = text }
19+
suspend fun sendWithEntities(message: suspend (@MessageDsl MessageText).() -> Unit) = send {
20+
textWithEntities { message() }
21+
}
1822

1923
suspend fun send(chatId: ChatId = getChatIdOrThrow(), message: suspend TextMessage.() -> Unit): Message {
20-
return TextMessage(bot).apply { message() }.send(chatId)
24+
return TextMessage(bot).apply {
25+
this.messageThreadId = getMessageThreadId()
26+
message()
27+
}.send(chatId)
2128
}
2229

2330
suspend fun sendPhoto(chatId: ChatId = getChatIdOrThrow(), message: suspend PhotoMessage.() -> Unit): Message {
24-
return PhotoMessage(bot).apply { message() }.send(chatId)
31+
return PhotoMessage(bot).apply {
32+
this.messageThreadId = getMessageThreadId()
33+
message()
34+
}.send(chatId)
2535
}
2636

2737
suspend fun sendAudio(chatId: ChatId = getChatIdOrThrow(), message: suspend AudioMessage.() -> Unit): Message {
28-
return AudioMessage(bot).apply { message() }.send(chatId)
38+
return AudioMessage(bot).apply {
39+
this.messageThreadId = getMessageThreadId()
40+
message()
41+
}.send(chatId)
2942
}
3043

31-
suspend fun sendDocument(chatId: ChatId = getChatIdOrThrow(), message: suspend DocumentMessage.() -> Unit): Message {
32-
return DocumentMessage(bot).apply { message() }.send(chatId)
44+
suspend fun sendDocument(
45+
chatId: ChatId = getChatIdOrThrow(),
46+
message: suspend DocumentMessage.() -> Unit
47+
): Message {
48+
return DocumentMessage(bot).apply {
49+
this.messageThreadId = getMessageThreadId()
50+
message()
51+
}.send(chatId)
3352
}
3453

3554
suspend fun sendVideo(chatId: ChatId = getChatIdOrThrow(), message: suspend VideoMessage.() -> Unit): Message {
36-
return VideoMessage(bot).apply { message() }.send(chatId)
55+
return VideoMessage(bot).apply {
56+
this.messageThreadId = getMessageThreadId()
57+
message()
58+
}.send(chatId)
3759
}
3860

39-
suspend fun sendAnimation(chatId: ChatId = getChatIdOrThrow(), message: suspend AnimationMessage.() -> Unit): Message {
40-
return AnimationMessage(bot).apply { message() }.send(chatId)
61+
suspend fun sendAnimation(
62+
chatId: ChatId = getChatIdOrThrow(),
63+
message: suspend AnimationMessage.() -> Unit
64+
): Message {
65+
return AnimationMessage(bot).apply {
66+
this.messageThreadId = getMessageThreadId()
67+
message()
68+
}.send(chatId)
4169
}
4270

4371
suspend fun sendVoice(chatId: ChatId = getChatIdOrThrow(), message: suspend VoiceMessage.() -> Unit): Message {
44-
return VoiceMessage(bot).apply { message() }.send(chatId)
72+
return VoiceMessage(bot).apply {
73+
this.messageThreadId = getMessageThreadId()
74+
message()
75+
}.send(chatId)
4576
}
4677

47-
suspend fun sendVideoNote(chatId: ChatId = getChatIdOrThrow(), message: suspend VideoNoteMessage.() -> Unit): Message {
48-
return VideoNoteMessage(bot).apply { message() }.send(chatId)
78+
suspend fun sendVideoNote(
79+
chatId: ChatId = getChatIdOrThrow(),
80+
message: suspend VideoNoteMessage.() -> Unit
81+
): Message {
82+
return VideoNoteMessage(bot).apply {
83+
this.messageThreadId = getMessageThreadId()
84+
message()
85+
}.send(chatId)
4986
}
5087

5188
suspend fun sendLocation(
5289
latitude: Double,
5390
longitude: Double,
54-
messageThreadId: Int? = null,
5591
chatId: ChatId = getChatIdOrThrow(),
5692
message: suspend LocationMessage.() -> Unit
5793
): Message {
58-
return LocationMessage(latitude, longitude, bot).apply { message() }.send(chatId)
94+
return LocationMessage(latitude, longitude, bot).apply {
95+
this.messageThreadId = getMessageThreadId()
96+
message()
97+
}.send(chatId)
5998
}
6099

61100
suspend fun editMessageLiveLocation(
@@ -66,7 +105,10 @@ interface ISender : ChatIdHolder, API, BotHolder {
66105
inlineMessageId: String? = null,
67106
message: suspend LocationMessage.() -> Unit
68107
): LiveLocationResponse {
69-
return LocationMessage(latitude, longitude, bot).apply { message() }
108+
return LocationMessage(latitude, longitude, bot).apply {
109+
this.messageThreadId = getMessageThreadId()
110+
message()
111+
}
70112
.edit(chatId, messageId, inlineMessageId)
71113
}
72114

@@ -76,56 +118,90 @@ interface ISender : ChatIdHolder, API, BotHolder {
76118
inlineMessageId: String? = null,
77119
message: suspend LocationMessage.() -> Unit
78120
): LiveLocationResponse {
79-
return LocationMessage(0.0, 0.0, bot).apply { message() }.stop(chatId, messageId, inlineMessageId)
121+
return LocationMessage(0.0, 0.0, bot).apply {
122+
this.messageThreadId = getMessageThreadId()
123+
message()
124+
}.stop(chatId, messageId, inlineMessageId)
80125
}
81126

82127
suspend fun sendVenue(
83128
latitude: Double,
84129
longitude: Double,
85130
title: String,
86131
address: String,
87-
messageThreadId: Int? = null,
88132
chatId: ChatId = getChatIdOrThrow(),
89133
message: suspend VenueMessage.() -> Unit
90134
): Message {
91-
return VenueMessage(latitude, longitude, title, address, bot).apply { message() }.send(chatId)
135+
return VenueMessage(latitude, longitude, title, address, bot).apply {
136+
this.messageThreadId = getMessageThreadId()
137+
message()
138+
}.send(chatId)
92139
}
93140

94141
suspend fun sendContact(
95142
phoneNumber: String,
96143
firstName: String,
97-
messageThreadId: Int? = null,
98144
chatId: ChatId = getChatIdOrThrow(),
99145
message: suspend ContactMessage.() -> Unit
100146
): Message {
101-
return ContactMessage(phoneNumber, firstName, bot).apply { message() }.send(chatId)
147+
return ContactMessage(phoneNumber, firstName, bot).apply {
148+
this.messageThreadId = getMessageThreadId()
149+
message()
150+
}.send(chatId)
102151
}
103152

104153
suspend fun sendPoll(
105-
messageThreadId: Int? = null,
106154
chatId: ChatId = getChatIdOrThrow(),
107155
message: suspend PollMessage.() -> Unit
108156
): Message {
109-
return PollMessage(bot).apply { message() }.send(chatId)
157+
return PollMessage(bot).apply {
158+
this.messageThreadId = getMessageThreadId()
159+
message()
160+
}.send(chatId)
110161
}
111162

112-
suspend fun sendDice(emoji: String, chatId: ChatId = getChatIdOrThrow(), message: suspend DiceMessage.() -> Unit): Message {
113-
return DiceMessage(emoji, bot).apply { message() }.send(chatId)
163+
suspend fun sendDice(
164+
emoji: String,
165+
chatId: ChatId = getChatIdOrThrow(),
166+
message: suspend DiceMessage.() -> Unit
167+
): Message {
168+
return DiceMessage(emoji, bot).apply {
169+
this.messageThreadId = getMessageThreadId()
170+
message()
171+
}.send(chatId)
114172
}
115173

116-
suspend fun sendChatAction(action: ChatAction, businessConnectionId: String? = null, chatId: ChatId = getChatIdOrThrow()): Boolean {
174+
suspend fun sendChatAction(
175+
action: ChatAction,
176+
businessConnectionId: String? = null,
177+
chatId: ChatId = getChatIdOrThrow()
178+
): Boolean {
117179
return sendChatAction(action, businessConnectionId, chatId)
118180
}
119181

120-
suspend fun sendMediaGroup(chatId: ChatId = getChatIdOrThrow(), message: suspend MediaGroupMessage.() -> Unit): List<Message> {
121-
return MediaGroupMessage(bot).apply { message() }.send(chatId)
182+
suspend fun sendMediaGroup(
183+
chatId: ChatId = getChatIdOrThrow(),
184+
message: suspend MediaGroupMessage.() -> Unit
185+
): List<Message> {
186+
return MediaGroupMessage(bot).apply {
187+
this.messageThreadId = getMessageThreadId()
188+
message()
189+
}.send(chatId)
122190
}
123191

124192
suspend fun sendSticker(chatId: ChatId = getChatIdOrThrow(), message: suspend StickerMessage.() -> Unit): Message {
125-
return StickerMessage(bot).apply { message() }.send(chatId)
193+
return StickerMessage(bot).apply {
194+
this.messageThreadId = getMessageThreadId()
195+
message()
196+
}.send(chatId)
126197
}
127198

128-
suspend fun sendPaidMedia(chatId: ChatId = getChatIdOrThrow(), message: suspend PaidMediaMessage.() -> Unit): Message {
129-
return PaidMediaMessage(bot).apply { message() }.send(chatId)
199+
suspend fun sendPaidMedia(
200+
chatId: ChatId = getChatIdOrThrow(),
201+
message: suspend PaidMediaMessage.() -> Unit
202+
): Message {
203+
return PaidMediaMessage(bot).apply {
204+
message()
205+
}.send(chatId)
130206
}
131207
}

lib/src/jvmMain/kotlin/ru/raysmith/tgbot/core/handler/EventHandler.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package ru.raysmith.tgbot.core.handler
22

33
import ru.raysmith.tgbot.core.BotContext
4-
import ru.raysmith.tgbot.core.ChatIdHolder
4+
import ru.raysmith.tgbot.core.ChatDataHolder
55
import ru.raysmith.tgbot.core.IEditor
66
import ru.raysmith.tgbot.core.ISender
77
import ru.raysmith.tgbot.model.network.updates.Update
@@ -10,7 +10,7 @@ import ru.raysmith.tgbot.utils.locations.LocationFlowContext
1010
import ru.raysmith.tgbot.utils.locations.LocationsWrapper
1111

1212
@HandlerDsl
13-
interface EventHandler : ChatIdHolder, IEditor, ISender {
13+
interface EventHandler : ChatDataHolder, IEditor, ISender {
1414
var handled: Boolean // TODO should be internal
1515
suspend fun setupFeatures(vararg features: BotFeature, callFirst: Boolean = false)
1616
suspend fun handle() // TODO should be internal

lib/src/jvmMain/kotlin/ru/raysmith/tgbot/core/handler/EventHandlerFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import ru.raysmith.tgbot.model.network.updates.Update
55
import ru.raysmith.tgbot.model.network.updates.UpdateType
66

77
@HandlerDsl
8-
interface EventHandlerFactory {
8+
sealed interface EventHandlerFactory {
99
companion object {
1010
@Deprecated("Use main logger", ReplaceWith("Bot.logger"))
1111
internal val logger = LoggerFactory.getLogger("event-handler-factory")

lib/src/jvmMain/kotlin/ru/raysmith/tgbot/core/handler/ILocationEventHandlerFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ class LocationEventHandlerFactory<LFC : LocationFlowContext>(
171171
null -> UnknownEventHandler(update, bot, unknownHandler)
172172
}
173173

174-
override fun handleUnknown(handler: suspend UnknownEventHandler.() -> Unit) {
174+
override fun handleUnknown(handler: suspend UnknownEventHandler.() -> Unit) { // TODO location variant with flow context?
175175
unknownHandler = handler
176176
}
177177

lib/src/jvmMain/kotlin/ru/raysmith/tgbot/core/handler/base/CallbackQueryHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ open class CallbackQueryHandler(
4848
}
4949

5050
override fun getChatId() = query.message?.chat?.id
51-
override fun getChatIdOrThrow() = query.message?.chat?.id ?: throw UnknownChatIdException()
51+
override fun getMessageThreadId(): Int? = query.message?.asMessageOrNull()?.messageThreadId
5252

5353
override suspend fun setupFeatures(vararg features: BotFeature, callFirst: Boolean) {
5454
if (callFirst) localFeatures.addAll(0, features.toList())

0 commit comments

Comments
 (0)