1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-11-26 03:58:44 +00:00

locations updates

This commit is contained in:
InsanusMokrassar 2020-11-05 01:12:14 +06:00
parent 609a959b99
commit 201def826e
31 changed files with 315 additions and 70 deletions

View File

@ -22,6 +22,24 @@
* Limits for dices has been changed * Limits for dices has been changed
* `commonDiceResultLimit` has been deprecated * `commonDiceResultLimit` has been deprecated
* New field `DiceAnimationType#valueLimits` * New field `DiceAnimationType#valueLimits`
* Locations updates:
* New interface `Headed` with property `heading`
* New interface `HorizontallyAccured` with property `horizontalAccuracy`
* New interface `ProximityAlertable` with property `proximityAlertRadius`
* `Location` class has been separated:
* `StaticLocation` for static locations
* `LiveLocation` for live locations
* Property `Livable#livePeriod` now use typealias type `Seconds` (the same by meaning - `Int`)
* `EditLocationMessage` now extends `Locationed`, `HorizontallyAccured`, `ProximityAlertable` and `Headed` interfaces
* New properties in `EditChatMessageLiveLocation`: `horizontalAccuracy`, `heading`, `proximityAlertRadius`
* New properties in `EditInlineMessageLiveLocation`: `horizontalAccuracy`, `heading`, `proximityAlertRadius`
* Main constructor of `SendLocation` now is internal. Instead of that currently available next factories:
* `SendLocation` - sending of static location without live parameters
* `SendStaticLocation` - sending of static location without live parameters
* `SendLiveLocation` - sending of live location with live parameters
* `PositionedSendMessageRequest` now extends `Locationed`
* `LocationContent#createResend` now can create `LiveLocation`
* Support of `ProximityAlertTriggered`. It is `CommonEvent`
* `API`: * `API`:
* Extensions `TelegramBot#pinChatMessage` now support any `Chat` and `Message`s from any `Chat` * Extensions `TelegramBot#pinChatMessage` now support any `Chat` and `Message`s from any `Chat`
* New extensions `TelegramBot#unpinAllChatMessages` * New extensions `TelegramBot#unpinAllChatMessages`

View File

@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.Degrees
interface Headed {
val heading: Degrees?
}

View File

@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.Meters
interface HorizontallyAccured {
val horizontalAccuracy: Meters?
}

View File

@ -1,8 +1,10 @@
package dev.inmo.tgbotapi.CommonAbstracts package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.Seconds
interface Livable { interface Livable {
/** /**
* Period in SECONDS * Period in [Seconds]
*/ */
val livePeriod: Int? val livePeriod: Seconds?
} }

View File

@ -0,0 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.Meters
interface ProximityAlertable {
val proximityAlertRadius: Meters?
}

View File

@ -6,6 +6,7 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import dev.inmo.tgbotapi.types.message.content.LocationContent import dev.inmo.tgbotapi.types.message.content.LocationContent
import dev.inmo.tgbotapi.utils.throwRangeError
import kotlinx.serialization.* import kotlinx.serialization.*
private val commonResultDeserializer = TelegramBotAPIMessageDeserializationStrategyClass<ContentMessage<LocationContent>>() private val commonResultDeserializer = TelegramBotAPIMessageDeserializationStrategyClass<ContentMessage<LocationContent>>()
@ -20,6 +21,12 @@ data class EditChatMessageLiveLocation(
override val latitude: Double, override val latitude: Double,
@SerialName(longitudeField) @SerialName(longitudeField)
override val longitude: Double, override val longitude: Double,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null,
@SerialName(replyMarkupField) @SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null override val replyMarkup: InlineKeyboardMarkup? = null
) : EditChatMessage<LocationContent>, EditReplyMessage, EditLocationMessage { ) : EditChatMessage<LocationContent>, EditReplyMessage, EditLocationMessage {
@ -28,4 +35,10 @@ data class EditChatMessageLiveLocation(
get() = commonResultDeserializer get() = commonResultDeserializer
override val requestSerializer: SerializationStrategy<*> override val requestSerializer: SerializationStrategy<*>
get() = serializer() get() = serializer()
init {
if (horizontalAccuracy != null && horizontalAccuracy !in horizontalAccuracyLimit) {
throwRangeError("horizontalAccuracy", horizontalAccuracyLimit, horizontalAccuracy)
}
}
} }

View File

@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.requests.edit.LiveLocation
import dev.inmo.tgbotapi.requests.edit.abstracts.* import dev.inmo.tgbotapi.requests.edit.abstracts.*
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.utils.throwRangeError
import kotlinx.serialization.* import kotlinx.serialization.*
@Serializable @Serializable
@ -13,10 +14,22 @@ data class EditInlineMessageLiveLocation(
override val latitude: Double, override val latitude: Double,
@SerialName(longitudeField) @SerialName(longitudeField)
override val longitude: Double, override val longitude: Double,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null,
@SerialName(replyMarkupField) @SerialName(replyMarkupField)
override val replyMarkup: InlineKeyboardMarkup? = null override val replyMarkup: InlineKeyboardMarkup? = null
) : EditInlineMessage, EditReplyMessage, EditLocationMessage { ) : EditInlineMessage, EditReplyMessage, EditLocationMessage {
override fun method(): String = "editMessageLiveLocation" override fun method(): String = "editMessageLiveLocation"
override val requestSerializer: SerializationStrategy<*> override val requestSerializer: SerializationStrategy<*>
get() = serializer() get() = serializer()
init {
if (horizontalAccuracy != null && horizontalAccuracy !in horizontalAccuracyLimit) {
throwRangeError("horizontalAccuracy", horizontalAccuracyLimit, horizontalAccuracy)
}
}
} }

View File

@ -1,6 +1,5 @@
package dev.inmo.tgbotapi.requests.edit.abstracts package dev.inmo.tgbotapi.requests.edit.abstracts
interface EditLocationMessage { import dev.inmo.tgbotapi.CommonAbstracts.*
val latitude: Double
val longitude: Double interface EditLocationMessage : Locationed, HorizontallyAccured, ProximityAlertable, Headed
}

View File

@ -1,19 +1,74 @@
package dev.inmo.tgbotapi.requests.send package dev.inmo.tgbotapi.requests.send
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.requests.send.abstracts.* import dev.inmo.tgbotapi.requests.send.abstracts.*
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import dev.inmo.tgbotapi.types.message.content.LocationContent import dev.inmo.tgbotapi.types.message.content.LocationContent
import dev.inmo.tgbotapi.utils.throwRangeError
import kotlinx.serialization.* import kotlinx.serialization.*
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>> private val commonResultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
= TelegramBotAPIMessageDeserializationStrategyClass() = TelegramBotAPIMessageDeserializationStrategyClass()
fun SendLocation(
chatId: ChatIdentifier,
latitude: Double,
longitude: Double,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
replyMarkup: KeyboardMarkup? = null
) = SendLocation(
chatId,
latitude,
longitude,
null,
null,
null,
null,
disableNotification,
replyToMessageId,
replyMarkup
)
fun SendStaticLocation(
chatId: ChatIdentifier,
latitude: Double,
longitude: Double,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
replyMarkup: KeyboardMarkup? = null
) = SendLocation(chatId, latitude, longitude, disableNotification, replyToMessageId, replyMarkup)
fun SendLiveLocation(
chatId: ChatIdentifier,
latitude: Double,
longitude: Double,
livePeriod: Seconds,
horizontalAccuracy: Meters? = null,
heading: Degrees? = null,
proximityAlertRadius: Meters? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
replyMarkup: KeyboardMarkup? = null
) = SendLocation(
chatId,
latitude,
longitude,
livePeriod,
horizontalAccuracy,
heading,
proximityAlertRadius,
disableNotification,
replyToMessageId,
replyMarkup
)
@Serializable @Serializable
data class SendLocation( data class SendLocation internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@SerialName(latitudeField) @SerialName(latitudeField)
@ -21,7 +76,13 @@ data class SendLocation(
@SerialName(longitudeField) @SerialName(longitudeField)
override val longitude: Double, override val longitude: Double,
@SerialName(livePeriodField) @SerialName(livePeriodField)
val livePeriod: Long? = null, override val livePeriod: Seconds? = null,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null,
@SerialName(disableNotificationField) @SerialName(disableNotificationField)
override val disableNotification: Boolean = false, override val disableNotification: Boolean = false,
@SerialName(replyToMessageIdField) @SerialName(replyToMessageIdField)
@ -30,7 +91,11 @@ data class SendLocation(
override val replyMarkup: KeyboardMarkup? = null override val replyMarkup: KeyboardMarkup? = null
) : SendMessageRequest<ContentMessage<LocationContent>>, ) : SendMessageRequest<ContentMessage<LocationContent>>,
ReplyingMarkupSendMessageRequest<ContentMessage<LocationContent>>, ReplyingMarkupSendMessageRequest<ContentMessage<LocationContent>>,
PositionedSendMessageRequest<ContentMessage<LocationContent>> PositionedSendMessageRequest<ContentMessage<LocationContent>>,
HorizontallyAccured,
Livable,
ProximityAlertable,
Headed
{ {
override fun method(): String = "sendLocation" override fun method(): String = "sendLocation"
override val resultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>> override val resultDeserializer: DeserializationStrategy<ContentMessage<LocationContent>>
@ -42,5 +107,8 @@ data class SendLocation(
if (livePeriod != null && livePeriod !in livePeriodLimit) { if (livePeriod != null && livePeriod !in livePeriodLimit) {
error("Live period for sending location must be in $livePeriodLimit, but was $livePeriod") error("Live period for sending location must be in $livePeriodLimit, but was $livePeriod")
} }
if (horizontalAccuracy != null && horizontalAccuracy !in horizontalAccuracyLimit) {
throwRangeError("horizontalAccuracy", horizontalAccuracyLimit, horizontalAccuracy)
}
} }
} }

View File

@ -1,6 +1,5 @@
package dev.inmo.tgbotapi.requests.send.abstracts package dev.inmo.tgbotapi.requests.send.abstracts
interface PositionedSendMessageRequest<T: Any>: SendMessageRequest<T> { import dev.inmo.tgbotapi.CommonAbstracts.Locationed
val latitude: Double
val longitude: Double interface PositionedSendMessageRequest<T: Any>: SendMessageRequest<T>, Locationed
}

View File

@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.types package dev.inmo.tgbotapi.types
import dev.inmo.tgbotapi.types.location.StaticLocation
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@ -12,7 +13,7 @@ import kotlinx.serialization.Serializable
@Serializable @Serializable
data class ChatLocation( data class ChatLocation(
@SerialName(locationField) @SerialName(locationField)
val location: Location, val location: StaticLocation,
@SerialName(addressField) @SerialName(addressField)
val address: String val address: String
) )

View File

@ -28,6 +28,12 @@ typealias FoursquareType = String
typealias Seconds = Int typealias Seconds = Int
typealias LongSeconds = Long typealias LongSeconds = Long
typealias Meters = Float
typealias Degrees = Int
val degreesLimit = 1 .. 360
val horizontalAccuracyLimit = 0F .. 1500F
val getUpdatesLimit = 1 .. 100 val getUpdatesLimit = 1 .. 100
val callbackQueryAnswerLength = 0 until 200 val callbackQueryAnswerLength = 0 until 200
val captionLength = 0 .. 1024 val captionLength = 0 .. 1024
@ -93,6 +99,7 @@ const val replyMarkupField = "reply_markup"
const val disableContentTypeDetectionField = "disable_content_type_detection" const val disableContentTypeDetectionField = "disable_content_type_detection"
const val supportStreamingField = "support_streaming" const val supportStreamingField = "support_streaming"
const val livePeriodField = "live_period" const val livePeriodField = "live_period"
const val proximityAlertRadiusField = "proximity_alert_radius"
const val isBotField = "is_bot" const val isBotField = "is_bot"
const val firstNameField = "first_name" const val firstNameField = "first_name"
const val lastNameField = "last_name" const val lastNameField = "last_name"
@ -152,6 +159,7 @@ const val customTitleField = "custom_title"
const val optionIdsField = "option_ids" const val optionIdsField = "option_ids"
const val ipAddressField = "ip_address" const val ipAddressField = "ip_address"
const val linkedChatIdField = "linked_chat_id" const val linkedChatIdField = "linked_chat_id"
const val horizontalAccuracyField = "horizontal_accuracy"
const val requestContactField = "request_contact" const val requestContactField = "request_contact"
const val requestLocationField = "request_location" const val requestLocationField = "request_location"
@ -249,6 +257,7 @@ const val heightField = "height"
const val lengthField = "length" const val lengthField = "length"
const val latitudeField = "latitude" const val latitudeField = "latitude"
const val longitudeField = "longitude" const val longitudeField = "longitude"
const val headingField = "heading"
const val fromField = "from" const val fromField = "from"
const val userField = "user" const val userField = "user"
const val dateField = "date" const val dateField = "date"

View File

@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.ChosenInlineResult import dev.inmo.tgbotapi.types.InlineQueries.abstracts.ChosenInlineResult
import dev.inmo.tgbotapi.types.location.StaticLocation
data class LocationChosenInlineResult( data class LocationChosenInlineResult(
override val resultId: InlineQueryIdentifier, override val resultId: InlineQueryIdentifier,
override val user: User, override val user: User,
val location: Location, val location: StaticLocation,
override val inlineMessageId: InlineMessageIdentifier?, override val inlineMessageId: InlineMessageIdentifier?,
override val query: String override val query: String
) : ChosenInlineResult ) : ChosenInlineResult

View File

@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.ChosenInlineResult import dev.inmo.tgbotapi.types.InlineQueries.abstracts.ChosenInlineResult
import dev.inmo.tgbotapi.types.location.StaticLocation
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@ -14,7 +15,7 @@ internal data class RawChosenInlineResult(
@SerialName(queryField) @SerialName(queryField)
val query: String, val query: String,
@SerialName(locationField) @SerialName(locationField)
val location: Location? = null, val location: StaticLocation? = null,
@SerialName(inlineMessageIdField) @SerialName(inlineMessageIdField)
val inlineMessageId: InlineMessageIdentifier? = null val inlineMessageId: InlineMessageIdentifier? = null
) { ) {

View File

@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult package dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult
import dev.inmo.tgbotapi.CommonAbstracts.Livable import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.Locationed
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.* import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
@ -17,10 +16,16 @@ data class InlineQueryResultLocation(
override val latitude: Double, override val latitude: Double,
@SerialName(longitudeField) @SerialName(longitudeField)
override val longitude: Double, override val longitude: Double,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(titleField) @SerialName(titleField)
override val title: String, override val title: String,
@SerialName(livePeriodField) @SerialName(livePeriodField)
override val livePeriod: Int? = null, override val livePeriod: Seconds? = null,
@SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null,
@SerialName(thumbUrlField) @SerialName(thumbUrlField)
override val thumbUrl: String? = null, override val thumbUrl: String? = null,
@SerialName(thumbWidthField) @SerialName(thumbWidthField)
@ -33,7 +38,10 @@ data class InlineQueryResultLocation(
override val inputMessageContent: InputMessageContent? = null override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResult, ) : InlineQueryResult,
Locationed, Locationed,
HorizontallyAccured,
Livable, Livable,
ProximityAlertable,
Headed,
TitledInlineQueryResult, TitledInlineQueryResult,
WithInputMessageContentInlineQueryResult, WithInputMessageContentInlineQueryResult,
ThumbedInlineQueryResult, ThumbedInlineQueryResult,

View File

@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent package dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent
import dev.inmo.tgbotapi.CommonAbstracts.Livable import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.CommonAbstracts.Locationed
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InputMessageContent
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
@ -13,6 +12,12 @@ data class InputLocationMessageContent(
override val latitude: Double, override val latitude: Double,
@SerialName(longitudeField) @SerialName(longitudeField)
override val longitude: Double, override val longitude: Double,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(livePeriodField) @SerialName(livePeriodField)
override val livePeriod: Int? = null override val livePeriod: Seconds? = null,
) : Locationed, Livable, InputMessageContent @SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null
) : Locationed, HorizontallyAccured, ProximityAlertable, Livable, Headed, InputMessageContent

View File

@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.InlineQueries.query
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery import dev.inmo.tgbotapi.types.InlineQueries.abstracts.InlineQuery
import dev.inmo.tgbotapi.types.location.StaticLocation
data class LocationInlineQuery( data class LocationInlineQuery(
override val id: InlineQueryIdentifier, override val id: InlineQueryIdentifier,
override val from: User, override val from: User,
override val query: String, override val query: String,
override val offset: String, override val offset: String,
val location: Location val location: StaticLocation
) : InlineQuery ) : InlineQuery

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.InlineQueries.query package dev.inmo.tgbotapi.types.InlineQueries.query
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.location.StaticLocation
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@ -15,7 +16,7 @@ internal data class RawInlineQuery(
@SerialName(offsetField) @SerialName(offsetField)
val offset: String, val offset: String,
@SerialName(locationField) @SerialName(locationField)
val location: Location? = null val location: StaticLocation? = null
) { ) {
val asInlineQuery by lazy { val asInlineQuery by lazy {
location ?.let { location ?.let {

View File

@ -1,13 +0,0 @@
package dev.inmo.tgbotapi.types
import dev.inmo.tgbotapi.CommonAbstracts.Locationed
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Location(
@SerialName(longitudeField)
override val longitude: Double,
@SerialName(latitudeField)
override val latitude: Double
) : Locationed

View File

@ -0,0 +1,57 @@
package dev.inmo.tgbotapi.types.location
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
import kotlinx.serialization.*
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonObject
@Serializable(LocationSerializer::class)
sealed class Location : Locationed, HorizontallyAccured
@Serializable
data class StaticLocation(
@SerialName(longitudeField)
override val longitude: Double,
@SerialName(latitudeField)
override val latitude: Double,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null
) : Location()
@Serializable
data class LiveLocation(
@SerialName(longitudeField)
override val longitude: Double,
@SerialName(latitudeField)
override val latitude: Double,
@SerialName(horizontalAccuracyField)
override val horizontalAccuracy: Meters? = null,
@SerialName(livePeriodField)
override val livePeriod: Seconds,
@SerialName(headingField)
override val heading: Degrees? = null,
@SerialName(proximityAlertRadiusField)
override val proximityAlertRadius: Meters? = null
) : Location(), Livable, ProximityAlertable, Headed
@Serializer(Location::class)
object LocationSerializer : KSerializer<Location> {
override fun deserialize(decoder: Decoder): Location = JsonObject.serializer().deserialize(decoder).let {
if (it.containsKey(livePeriodField) && it[livePeriodField] != JsonNull) {
nonstrictJsonFormat.decodeFromJsonElement(LiveLocation.serializer(), it)
} else {
nonstrictJsonFormat.decodeFromJsonElement(StaticLocation.serializer(), it)
}
}
override fun serialize(encoder: Encoder, value: Location) {
when (value) {
is StaticLocation -> StaticLocation.serializer().serialize(encoder, value)
is LiveLocation -> LiveLocation.serializer().serialize(encoder, value)
}
}
}

View File

@ -0,0 +1,16 @@
package dev.inmo.tgbotapi.types.message.ChatEvents
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonEvent
import kotlinx.serialization.Serializable
/**
* This object represents the content of a service message, sent whenever a user in the chat triggers a proximity alert
* set by another user.
*/
@Serializable
data class ProximityAlertTriggered(
val traveler: User,
val watcher: User,
val distance: Meters
) : CommonEvent

View File

@ -8,6 +8,9 @@ import dev.inmo.tgbotapi.types.chat.abstracts.*
import dev.inmo.tgbotapi.types.dice.Dice import dev.inmo.tgbotapi.types.dice.Dice
import dev.inmo.tgbotapi.types.files.* import dev.inmo.tgbotapi.types.files.*
import dev.inmo.tgbotapi.types.games.RawGame import dev.inmo.tgbotapi.types.games.RawGame
import dev.inmo.tgbotapi.types.location.Location
import dev.inmo.tgbotapi.types.message.ChatEvents.ProximityAlertTriggered
import dev.inmo.tgbotapi.types.location.StaticLocation
import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.*
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.Message
@ -86,6 +89,7 @@ internal data class RawMessage(
// passport property // passport property
private val passport_data: Unit? = null, private val passport_data: Unit? = null,
private val proximity_alert_triggered: ProximityAlertTriggered? = null,
private val reply_markup: InlineKeyboardMarkup? = null private val reply_markup: InlineKeyboardMarkup? = null
) { ) {
@ -180,6 +184,7 @@ internal data class RawMessage(
) )
channel_chat_created -> ChannelChatCreated() channel_chat_created -> ChannelChatCreated()
pinned_message != null -> PinnedMessage(pinned_message.asMessage) pinned_message != null -> PinnedMessage(pinned_message.asMessage)
proximity_alert_triggered != null -> proximity_alert_triggered
else -> null else -> null
} }
} }

View File

@ -1,9 +1,10 @@
package dev.inmo.tgbotapi.types.message.content package dev.inmo.tgbotapi.types.message.content
import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.SendLocation import dev.inmo.tgbotapi.requests.send.*
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.location.*
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
@ -15,13 +16,26 @@ data class LocationContent(
disableNotification: Boolean, disableNotification: Boolean,
replyToMessageId: MessageIdentifier?, replyToMessageId: MessageIdentifier?,
replyMarkup: KeyboardMarkup? replyMarkup: KeyboardMarkup?
): Request<ContentMessage<LocationContent>> = SendLocation( ): Request<ContentMessage<LocationContent>> = when (location) {
is StaticLocation -> SendStaticLocation(
chatId, chatId,
location.latitude, location.latitude,
location.longitude, location.longitude,
null,
disableNotification, disableNotification,
replyToMessageId, replyToMessageId,
replyMarkup replyMarkup
) )
is LiveLocation -> SendLiveLocation(
chatId,
location.latitude,
location.longitude,
location.livePeriod,
location.horizontalAccuracy,
location.heading,
location.proximityAlertRadius,
disableNotification,
replyToMessageId,
replyMarkup
)
}
} }

View File

@ -3,13 +3,14 @@ package dev.inmo.tgbotapi.types.venue
import dev.inmo.tgbotapi.CommonAbstracts.CommonVenueData import dev.inmo.tgbotapi.CommonAbstracts.CommonVenueData
import dev.inmo.tgbotapi.CommonAbstracts.Locationed import dev.inmo.tgbotapi.CommonAbstracts.Locationed
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.location.StaticLocation
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
data class Venue( data class Venue(
@SerialName(locationField) @SerialName(locationField)
val location: Location, val location: StaticLocation,
@SerialName(titleField) @SerialName(titleField)
override val title: String, override val title: String,
@SerialName(addressField) @SerialName(addressField)

View File

@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.utils package dev.inmo.tgbotapi.utils
internal fun throwRangeError( internal fun <T : Comparable<T>> throwRangeError(
valueName: String, valueName: String,
range: IntRange, range: ClosedRange<T>,
actualValue: Int actualValue: T
): Nothing = error("$valueName must be in range $range, but was $actualValue") ): Nothing = error("$valueName must be in range $range, but was $actualValue")

View File

@ -13,6 +13,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.content.LocationContent import dev.inmo.tgbotapi.types.message.content.LocationContent
import com.soywiz.klock.DateTime import com.soywiz.klock.DateTime
import com.soywiz.klock.TimeSpan import com.soywiz.klock.TimeSpan
import dev.inmo.tgbotapi.types.location.StaticLocation
import io.ktor.utils.io.core.Closeable import io.ktor.utils.io.core.Closeable
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -39,13 +40,13 @@ class LiveLocation internal constructor(
get() = field || leftUntilCloseMillis.millisecondsLong < 0L get() = field || leftUntilCloseMillis.millisecondsLong < 0L
private var message: ContentMessage<LocationContent> = initMessage private var message: ContentMessage<LocationContent> = initMessage
val lastLocation: Location val lastLocation: StaticLocation
get() = message.content.location get() = message.content.location
suspend fun updateLocation( suspend fun updateLocation(
location: Location, location: StaticLocation,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null
): Location { ): StaticLocation {
if (!isClosed) { if (!isClosed) {
message = requestsExecutor.editLiveLocation( message = requestsExecutor.editLiveLocation(
message, message,
@ -114,7 +115,7 @@ suspend fun TelegramBot.startLiveLocation(
suspend fun TelegramBot.startLiveLocation( suspend fun TelegramBot.startLiveLocation(
scope: CoroutineScope, scope: CoroutineScope,
chatId: ChatId, chatId: ChatId,
location: Location, location: StaticLocation,
liveTimeMillis: Long = defaultLivePeriodDelayMillis, liveTimeMillis: Long = defaultLivePeriodDelayMillis,
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
@ -126,7 +127,7 @@ suspend fun TelegramBot.startLiveLocation(
suspend fun TelegramBot.startLiveLocation( suspend fun TelegramBot.startLiveLocation(
scope: CoroutineScope, scope: CoroutineScope,
chat: Chat, chat: Chat,
location: Location, location: StaticLocation,
liveTimeMillis: Long = defaultLivePeriodDelayMillis, liveTimeMillis: Long = defaultLivePeriodDelayMillis,
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
@ -148,7 +149,7 @@ suspend inline fun TelegramBot.replyWithLiveLocation(
suspend inline fun TelegramBot.replyWithLiveLocation( suspend inline fun TelegramBot.replyWithLiveLocation(
to: Message, to: Message,
scope: CoroutineScope, scope: CoroutineScope,
location: Location, location: StaticLocation,
liveTimeMillis: Long = defaultLivePeriodDelayMillis, liveTimeMillis: Long = defaultLivePeriodDelayMillis,
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null

View File

@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.requests.edit.LiveLocation.EditChatMessageLiveLocation
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.chat.abstracts.Chat import dev.inmo.tgbotapi.types.chat.abstracts.Chat
import dev.inmo.tgbotapi.types.location.StaticLocation
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.LocationContent import dev.inmo.tgbotapi.types.message.content.LocationContent
@ -38,7 +39,7 @@ suspend fun TelegramBot.editLiveLocation(
suspend fun TelegramBot.editLiveLocation( suspend fun TelegramBot.editLiveLocation(
chatId: ChatIdentifier, chatId: ChatIdentifier,
messageId: MessageIdentifier, messageId: MessageIdentifier,
location: Location, location: StaticLocation,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null
) = execute( ) = execute(
EditChatMessageLiveLocation( EditChatMessageLiveLocation(
@ -49,12 +50,12 @@ suspend fun TelegramBot.editLiveLocation(
suspend fun TelegramBot.editLiveLocation( suspend fun TelegramBot.editLiveLocation(
chat: Chat, chat: Chat,
messageId: MessageIdentifier, messageId: MessageIdentifier,
location: Location, location: StaticLocation,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(chat.id, messageId, location.latitude, location.longitude, replyMarkup) ) = editLiveLocation(chat.id, messageId, location.latitude, location.longitude, replyMarkup)
suspend fun TelegramBot.editLiveLocation( suspend fun TelegramBot.editLiveLocation(
message: ContentMessage<LocationContent>, message: ContentMessage<LocationContent>,
location: Location, location: StaticLocation,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(message.chat, message.messageId, location.latitude, location.longitude, replyMarkup) ) = editLiveLocation(message.chat, message.messageId, location.latitude, location.longitude, replyMarkup)

View File

@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.extensions.api.edit.LiveLocation
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.edit.LiveLocation.EditInlineMessageLiveLocation import dev.inmo.tgbotapi.requests.edit.LiveLocation.EditInlineMessageLiveLocation
import dev.inmo.tgbotapi.types.InlineMessageIdentifier import dev.inmo.tgbotapi.types.InlineMessageIdentifier
import dev.inmo.tgbotapi.types.Location import dev.inmo.tgbotapi.types.location.StaticLocation
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
suspend fun TelegramBot.editLiveLocation( suspend fun TelegramBot.editLiveLocation(
@ -18,6 +18,6 @@ suspend fun TelegramBot.editLiveLocation(
) )
suspend fun TelegramBot.editLiveLocation( suspend fun TelegramBot.editLiveLocation(
inlineMessageId: InlineMessageIdentifier, inlineMessageId: InlineMessageIdentifier,
location: Location, location: StaticLocation,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null
) = editLiveLocation(inlineMessageId, location.latitude, location.longitude, replyMarkup) ) = editLiveLocation(inlineMessageId, location.latitude, location.longitude, replyMarkup)

View File

@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.requests.send.SendLocation
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.chat.abstracts.Chat import dev.inmo.tgbotapi.types.chat.abstracts.Chat
import dev.inmo.tgbotapi.types.location.StaticLocation
import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.Message
suspend fun TelegramBot.sendLocation( suspend fun TelegramBot.sendLocation(
@ -27,7 +28,7 @@ suspend fun TelegramBot.sendLocation(
suspend fun TelegramBot.sendLocation( suspend fun TelegramBot.sendLocation(
chatId: ChatIdentifier, chatId: ChatIdentifier,
location: Location, location: StaticLocation,
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
@ -58,7 +59,7 @@ suspend fun TelegramBot.sendLocation(
suspend fun TelegramBot.sendLocation( suspend fun TelegramBot.sendLocation(
chat: Chat, chat: Chat,
location: Location, location: StaticLocation,
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
@ -88,7 +89,7 @@ suspend inline fun TelegramBot.reply(
suspend inline fun TelegramBot.reply( suspend inline fun TelegramBot.reply(
to: Message, to: Message,
location: Location, location: StaticLocation,
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = sendLocation( ) = sendLocation(

View File

@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.requests.send.SendVenue
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.chat.abstracts.Chat import dev.inmo.tgbotapi.types.chat.abstracts.Chat
import dev.inmo.tgbotapi.types.location.StaticLocation
import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.venue.Venue import dev.inmo.tgbotapi.types.venue.Venue
@ -40,7 +41,7 @@ suspend fun TelegramBot.sendVenue(
suspend fun TelegramBot.sendVenue( suspend fun TelegramBot.sendVenue(
chatId: ChatIdentifier, chatId: ChatIdentifier,
location: Location, location: StaticLocation,
title: String, title: String,
address: String, address: String,
foursquareId: String? = null, foursquareId: String? = null,
@ -53,7 +54,7 @@ suspend fun TelegramBot.sendVenue(
suspend fun TelegramBot.sendVenue( suspend fun TelegramBot.sendVenue(
chat: Chat, chat: Chat,
location: Location, location: StaticLocation,
title: String, title: String,
address: String, address: String,
foursquareId: String? = null, foursquareId: String? = null,
@ -101,7 +102,7 @@ suspend inline fun TelegramBot.reply(
suspend inline fun TelegramBot.reply( suspend inline fun TelegramBot.reply(
to: Message, to: Message,
location: Location, location: StaticLocation,
title: String, title: String,
address: String, address: String,
foursquareId: String? = null, foursquareId: String? = null,

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.extensions.utils.extensions.venue package dev.inmo.tgbotapi.extensions.utils.extensions.venue
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.location.StaticLocation
import dev.inmo.tgbotapi.types.venue.Venue import dev.inmo.tgbotapi.types.venue.Venue
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@ -11,7 +12,7 @@ val Venue.foursquare: Foursquare?
} }
fun Venue( fun Venue(
location: Location, location: StaticLocation,
title: String, title: String,
address: String, address: String,
foursquare: Foursquare foursquare: Foursquare