Add ability to send location messages via bot
This commit is contained in:
parent
7a33de1c0d
commit
aff20dbc2b
6 changed files with 135 additions and 17 deletions
|
@ -84,6 +84,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
var sharingStatusChanges = ConcurrentLinkedQueue<SharingStatus>()
|
||||
|
||||
var currentSharingMode = ""
|
||||
private set
|
||||
|
||||
var metricsConstants = MetricsConstants.KILOMETERS_AND_METERS
|
||||
var speedConstants = SpeedConstants.KILOMETERS_PER_HOUR
|
||||
|
@ -138,6 +139,11 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
shareChatInfo = ShareChatInfo()
|
||||
}
|
||||
val currentTime = System.currentTimeMillis() / 1000
|
||||
val user = app.telegramHelper.getCurrentUser()
|
||||
if (user != null && currentSharingMode != user.id.toString() && shareChatInfo.start == -1L) {
|
||||
shareChatInfo.shouldSendViaBotMessage = true
|
||||
}
|
||||
|
||||
shareChatInfo.chatId = chatId
|
||||
shareChatInfo.start = currentTime
|
||||
if (shareChatInfo.livePeriod == -1L) {
|
||||
|
@ -157,6 +163,15 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
shareDevices = list.toHashSet()
|
||||
}
|
||||
|
||||
fun updateCurrentSharingMode(sharingMode: String) {
|
||||
if (currentSharingMode != sharingMode) {
|
||||
shareChatsInfo.forEach { (_, shareInfo) ->
|
||||
shareInfo.shouldSendViaBotMessage = true
|
||||
}
|
||||
}
|
||||
currentSharingMode = sharingMode
|
||||
}
|
||||
|
||||
fun getChatLivePeriod(chatId: Long) = shareChatsInfo[chatId]?.livePeriod
|
||||
|
||||
fun getChatsShareInfo() = shareChatsInfo
|
||||
|
@ -172,6 +187,10 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
return false
|
||||
}
|
||||
|
||||
fun getShareDeviceNameWithExternalId(externalId: String): String? {
|
||||
return shareDevices.singleOrNull { it.externalId == externalId }?.deviceName
|
||||
}
|
||||
|
||||
fun getLastSuccessfulSendTime() = shareChatsInfo.values.maxBy { it.lastSuccessfulSendTimeMs }?.lastSuccessfulSendTimeMs ?: -1
|
||||
|
||||
fun stopSharingLocationToChats() {
|
||||
|
@ -279,6 +298,9 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
when {
|
||||
!gpsEnabled -> {
|
||||
locationTime = app.shareLocationHelper.lastLocationMessageSentTime
|
||||
if (locationTime <= 0) {
|
||||
locationTime = getLastSuccessfulSendTime()
|
||||
}
|
||||
title = app.getString(R.string.no_gps_connection)
|
||||
description = app.getString(R.string.last_updated_location)
|
||||
statusType = SharingStatusType.NO_GPS
|
||||
|
@ -441,6 +463,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
obj.put(ShareChatInfo.CURRENT_MESSAGE_ID_KEY, chatInfo.currentMessageId)
|
||||
obj.put(ShareChatInfo.USER_SET_LIVE_PERIOD_KEY, chatInfo.userSetLivePeriod)
|
||||
obj.put(ShareChatInfo.USER_SET_LIVE_PERIOD_START_KEY, chatInfo.userSetLivePeriodStart)
|
||||
obj.put(ShareChatInfo.LAST_SUCCESSFUL_SEND_TIME_KEY, chatInfo.lastSuccessfulSendTimeMs)
|
||||
jArray.put(obj)
|
||||
}
|
||||
jArray
|
||||
|
@ -461,6 +484,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
currentMessageId = obj.optLong(ShareChatInfo.CURRENT_MESSAGE_ID_KEY)
|
||||
userSetLivePeriod = obj.optLong(ShareChatInfo.USER_SET_LIVE_PERIOD_KEY)
|
||||
userSetLivePeriodStart = obj.optLong(ShareChatInfo.USER_SET_LIVE_PERIOD_START_KEY)
|
||||
lastSuccessfulSendTimeMs = obj.optLong(ShareChatInfo.LAST_SUCCESSFUL_SEND_TIME_KEY)
|
||||
}
|
||||
shareChatsInfo[shareInfo.chatId] = shareInfo
|
||||
}
|
||||
|
@ -708,8 +732,9 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
var lastSuccessfulLocation: LatLon? = null
|
||||
var lastSuccessfulSendTimeMs = -1L
|
||||
var shouldDeletePreviousMessage = false
|
||||
var additionalActiveTime = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
||||
var shouldSendViaBotMessage = false
|
||||
var hasSharingError = false
|
||||
var additionalActiveTime = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
||||
|
||||
fun getNextAdditionalActiveTime(): Long {
|
||||
var index = ADDITIONAL_ACTIVE_TIME_VALUES_SEC.indexOf(additionalActiveTime)
|
||||
|
@ -733,6 +758,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
internal const val CURRENT_MESSAGE_ID_KEY = "currentMessageId"
|
||||
internal const val USER_SET_LIVE_PERIOD_KEY = "userSetLivePeriod"
|
||||
internal const val USER_SET_LIVE_PERIOD_START_KEY = "userSetLivePeriodStart"
|
||||
internal const val LAST_SUCCESSFUL_SEND_TIME_KEY = "lastSuccessfulSendTime"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,9 +3,13 @@ package net.osmand.telegram.helpers
|
|||
import net.osmand.Location
|
||||
import net.osmand.PlatformUtil
|
||||
import net.osmand.telegram.TelegramApplication
|
||||
import net.osmand.telegram.TelegramSettings
|
||||
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
|
||||
import net.osmand.telegram.utils.AndroidNetworkUtils
|
||||
import net.osmand.telegram.utils.BASE_URL
|
||||
import org.drinkless.td.libcore.telegram.TdApi
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
|
||||
private const val USER_SET_LIVE_PERIOD_DELAY_MS = 5000 // 5 sec
|
||||
|
||||
|
@ -47,13 +51,26 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
if (location != null) {
|
||||
val chatsShareInfo = app.settings.getChatsShareInfo()
|
||||
if (chatsShareInfo.isNotEmpty()) {
|
||||
val latitude = location.latitude
|
||||
val longitude = location.longitude
|
||||
val user = app.telegramHelper.getCurrentUser()
|
||||
val sharingMode = app.settings.currentSharingMode
|
||||
|
||||
if (user != null && sharingMode == user.id.toString()) {
|
||||
app.telegramHelper.sendLiveLocationMessage(chatsShareInfo, location.latitude, location.longitude)
|
||||
app.telegramHelper.sendLiveLocationMessage(chatsShareInfo, latitude, longitude)
|
||||
} else if (sharingMode.isNotEmpty()) {
|
||||
val url = "$BASE_URL/device/$sharingMode/send?lat=${location.latitude}&lon=${location.longitude}"
|
||||
AndroidNetworkUtils.sendRequestAsync(app, url, null, "Send Location", false, false, null)
|
||||
val url = "$BASE_URL/device/$sharingMode/send?lat=$latitude&lon=$longitude"
|
||||
AndroidNetworkUtils.sendRequestAsync(app, url, null, "Send Location", false, false,
|
||||
object : AndroidNetworkUtils.OnRequestResultListener {
|
||||
override fun onResult(result: String?) {
|
||||
updateShareInfoSuccessfulSendTime(result, chatsShareInfo)
|
||||
}
|
||||
})
|
||||
|
||||
val osmandBot = app.telegramHelper.getOsmandBot()
|
||||
if (osmandBot != null) {
|
||||
checkAndSendViaBotMessages(chatsShareInfo, TdApi.Location(latitude, longitude), osmandBot)
|
||||
}
|
||||
}
|
||||
}
|
||||
lastLocationMessageSentTime = System.currentTimeMillis()
|
||||
|
@ -133,6 +150,34 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
refreshNotification()
|
||||
}
|
||||
|
||||
private fun updateShareInfoSuccessfulSendTime(result: String?, chatsShareInfo: Map<Long, TelegramSettings.ShareChatInfo>) {
|
||||
if (result != null) {
|
||||
try {
|
||||
val jsonResult = JSONObject(result)
|
||||
val status = jsonResult.getString("status")
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (status == "OK") {
|
||||
chatsShareInfo.forEach { (_, shareInfo) ->
|
||||
shareInfo.lastSuccessfulSendTimeMs = currentTime
|
||||
}
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkAndSendViaBotMessages(chatsShareInfo: Map<Long, TelegramSettings.ShareChatInfo>, location: TdApi.Location, osmandBot: TdApi.User) {
|
||||
val deviceName = app.settings.getShareDeviceNameWithExternalId(app.settings.currentSharingMode)
|
||||
if (deviceName != null) {
|
||||
chatsShareInfo.forEach { (_, shareInfo) ->
|
||||
if (shareInfo.shouldSendViaBotMessage) {
|
||||
app.telegramHelper.sendViaBotLocationMessage(osmandBot.id, shareInfo, location, deviceName)
|
||||
shareInfo.shouldSendViaBotMessage = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshNotification() {
|
||||
app.runInUIThread {
|
||||
app.notificationHelper.refreshNotification(NotificationType.LOCATION)
|
||||
|
|
|
@ -89,6 +89,7 @@ class TelegramHelper private constructor() {
|
|||
|
||||
private var client: Client? = null
|
||||
private var currentUser: TdApi.User? = null
|
||||
private var osmandBot: TdApi.User? = null
|
||||
|
||||
private var haveFullChatList: Boolean = false
|
||||
private var needRefreshActiveLiveLocationMessages: Boolean = true
|
||||
|
@ -144,6 +145,8 @@ class TelegramHelper private constructor() {
|
|||
|
||||
fun getUser(id: Int) = users[id]
|
||||
|
||||
fun getOsmandBot() = osmandBot
|
||||
|
||||
fun getCurrentUser() = currentUser
|
||||
|
||||
fun getUserMessage(user: TdApi.User) =
|
||||
|
@ -480,6 +483,44 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
fun sendViaBotLocationMessage(userId: Int, shareInfo: TelegramSettings.ShareChatInfo, location: TdApi.Location, query: String) {
|
||||
log.debug("sendViaBotLocationMessage - ${shareInfo.chatId}")
|
||||
client?.send(TdApi.GetInlineQueryResults(userId, shareInfo.chatId, location, query, "")) { obj ->
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
if (error.code != IGNORED_ERROR_CODE) {
|
||||
listener?.onTelegramError(error.code, error.message)
|
||||
} else {
|
||||
shareInfo.shouldSendViaBotMessage = true
|
||||
}
|
||||
}
|
||||
TdApi.InlineQueryResults.CONSTRUCTOR -> {
|
||||
sendViaBotMessageFromQueryResults(shareInfo, obj as TdApi.InlineQueryResults, query)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendViaBotMessageFromQueryResults(
|
||||
shareInfo: TelegramSettings.ShareChatInfo,
|
||||
inlineQueryResults: TdApi.InlineQueryResults,
|
||||
query: String
|
||||
) {
|
||||
val queryResults = inlineQueryResults.results.asList()
|
||||
if (queryResults.isNotEmpty()) {
|
||||
val resultArticle = queryResults.firstOrNull {
|
||||
(it is TdApi.InlineQueryResultArticle && it.id.startsWith("t") && it.title == query)
|
||||
}
|
||||
if (resultArticle != null && resultArticle is TdApi.InlineQueryResultArticle) {
|
||||
client?.send(TdApi.SendInlineQueryResultMessage(shareInfo.chatId, 0, true,
|
||||
true, inlineQueryResults.inlineQueryId, resultArticle.id)) { obj ->
|
||||
handleLiveLocationMessageUpdate(obj, shareInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestSupergroupFullInfo(id: Int) {
|
||||
client?.send(TdApi.GetSupergroupFullInfo(id)) { obj ->
|
||||
when (obj.constructor) {
|
||||
|
@ -939,7 +980,8 @@ class TelegramHelper private constructor() {
|
|||
s.startsWith(UPDATED_PREFIX) -> {
|
||||
if (res.lastUpdated == 0) {
|
||||
val updatedStr = s.removePrefix(UPDATED_PREFIX)
|
||||
val updatedS = updatedStr.substring(0, updatedStr.indexOf("("))
|
||||
val endIndex = updatedStr.indexOf("(")
|
||||
val updatedS = updatedStr.substring(0, if (endIndex != -1) endIndex else updatedStr.length)
|
||||
res.lastUpdated = (parseTime(updatedS.trim()) / 1000).toInt()
|
||||
}
|
||||
}
|
||||
|
@ -1036,7 +1078,11 @@ class TelegramHelper private constructor() {
|
|||
|
||||
TdApi.UpdateUser.CONSTRUCTOR -> {
|
||||
val updateUser = obj as TdApi.UpdateUser
|
||||
users[updateUser.user.id] = updateUser.user
|
||||
val user = updateUser.user
|
||||
users[updateUser.user.id] = user
|
||||
if (isOsmAndBot(user.id)) {
|
||||
osmandBot = user
|
||||
}
|
||||
}
|
||||
TdApi.UpdateUserStatus.CONSTRUCTOR -> {
|
||||
val updateUserStatus = obj as TdApi.UpdateUserStatus
|
||||
|
|
|
@ -218,7 +218,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
|||
if (user != null) {
|
||||
OsmandApiUtils.updateSharingDevices(app, user.id)
|
||||
if (settings.currentSharingMode.isEmpty()) {
|
||||
settings.currentSharingMode = user.id.toString()
|
||||
settings.updateCurrentSharingMode(user.id.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,7 +209,7 @@ class SettingsDialogFragment : BaseDialogFragment() {
|
|||
isChecked = checked
|
||||
}
|
||||
setOnClickListener {
|
||||
settings.currentSharingMode = tag
|
||||
settings.updateCurrentSharingMode(tag)
|
||||
updateSelectedSharingMode()
|
||||
}
|
||||
this.tag = tag
|
||||
|
|
|
@ -55,16 +55,17 @@ class SharingStatusBottomSheet : DialogFragment() {
|
|||
findViewById<TextView>(R.id.status_change_time).text = OsmandFormatter.getFormattedTime(sharingStatus.statusChangeTime, false)
|
||||
findViewById<TextView>(R.id.last_location_line).text = sharingStatus.description
|
||||
|
||||
if (sharingStatusType != TelegramSettings.SharingStatusType.INITIALIZING
|
||||
&& (sharingStatusType == TelegramSettings.SharingStatusType.SENDING && time != -1L)) {
|
||||
if (sharingStatusType != TelegramSettings.SharingStatusType.INITIALIZING) {
|
||||
if ((sharingStatusType == TelegramSettings.SharingStatusType.SENDING && time <= 0)) {
|
||||
findViewById<TextView>(R.id.last_location_line_time).visibility = View.GONE
|
||||
} else {
|
||||
val descriptionTime = when {
|
||||
time > 0 -> OsmandFormatter.getFormattedTime(time, false)
|
||||
sharingStatusType == TelegramSettings.SharingStatusType.NO_GPS -> getString(
|
||||
R.string.not_found_yet
|
||||
)
|
||||
sharingStatusType == TelegramSettings.SharingStatusType.NO_GPS -> getString(R.string.not_found_yet)
|
||||
else -> getString(R.string.not_sent_yet)
|
||||
}
|
||||
findViewById<TextView>(R.id.last_location_line_time).text = descriptionTime
|
||||
}
|
||||
} else {
|
||||
findViewById<TextView>(R.id.last_location_line_time).visibility = View.GONE
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue