Merge pull request #5627 from osmandapp/fix_telegram_helper

Fix telegram helper
This commit is contained in:
Alexander Sytnyk 2018-07-02 20:32:18 +03:00 committed by GitHub
commit 114c951d31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -24,6 +24,8 @@ class TelegramHelper private constructor() {
private const val CHAT_LIVE_USERS_LIMIT = 100
private const val IGNORED_ERROR_CODE = 406
private const val UPDATE_LIVE_MESSAGES_INTERVAL_SEC = 30L
private const val MESSAGE_ACTIVE_TIME_SEC = 24 * 60 * 60 // 24 hours
private const val OSMAND_BOT_USERNAME = "osmand_bot"
private var helper: TelegramHelper? = null
@ -49,7 +51,8 @@ class TelegramHelper private constructor() {
private val downloadChatFilesMap = ConcurrentHashMap<String, TdApi.Chat>()
private val downloadUserFilesMap = ConcurrentHashMap<String, TdApi.User>()
private val usersLiveMessages = ConcurrentHashMap<Long, TdApi.Message>()
// Can contain TdApi.MessageLocation or TdApi.MessageText from osmand_bot
private val usersLocationMessages = ConcurrentHashMap<Int, TdApi.Message>()
private val usersFullInfo = ConcurrentHashMap<Int, TdApi.UserFullInfo>()
private val basicGroupsFullInfo = ConcurrentHashMap<Int, TdApi.BasicGroupFullInfo>()
@ -102,18 +105,13 @@ class TelegramHelper private constructor() {
return users[id]
}
fun getUserMessage(user: TdApi.User): TdApi.Message? {
for (message in usersLiveMessages.values) {
if (message.senderUserId == user.id) {
return message
}
}
return null
}
fun getUserMessage(user: TdApi.User) = usersLocationMessages[user.id]
fun getMessageById(id: Long) = usersLocationMessages.values.firstOrNull { it.id == id }
fun getChatMessages(chatTitle: String): List<TdApi.Message> {
val res = mutableListOf<TdApi.Message>()
for (message in usersLiveMessages.values) {
for (message in usersLocationMessages.values) {
val title = chats[message.chatId]?.title
if (title == chatTitle) {
res.add(message)
@ -123,12 +121,12 @@ class TelegramHelper private constructor() {
}
fun getMessages(): List<TdApi.Message> {
return usersLiveMessages.values.toList()
return usersLocationMessages.values.toList()
}
fun getMessagesByChatIds(): Map<Long, List<TdApi.Message>> {
val res = mutableMapOf<Long, MutableList<TdApi.Message>>()
for (message in usersLiveMessages.values) {
for (message in usersLocationMessages.values) {
var messages = res[message.chatId]
if (messages != null) {
messages.add(message)
@ -356,41 +354,31 @@ class TelegramHelper private constructor() {
}
}
updateChatTitles()
getChatRecentLocationMessages(chatTitles.keys)
listener?.onTelegramChatsRead()
}
private fun getChatRecentLocationMessages(chatTitles: Set<String>) {
if (haveAuthorization) {
for (chatTitle in chatTitles) {
val chatId = this.chatTitles[chatTitle]
if (chatId != null) {
val chat = chats[chatId]
if (chat == null || isChannel(chat)) {
continue
}
client?.send(TdApi.SearchChatRecentLocationMessages(chatId, CHAT_LIVE_USERS_LIMIT)) { obj ->
when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error
val code = error.code
if (code != IGNORED_ERROR_CODE && code != 400) {
listener?.onTelegramError(code, error.message)
}
}
TdApi.Messages.CONSTRUCTOR -> {
val messages = (obj as TdApi.Messages).messages
for (message in messages) {
if (!message.isOutgoing && message.content is TdApi.MessageLocation) {
usersLiveMessages[message.id] = message
}
}
incomingMessagesListeners.forEach { it.onReceiveChatLocationMessages(chatTitle, *messages) }
}
else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
}
private fun requestMessage(chatId: Long, messageId: Long, onComplete: (TdApi.Message) -> Unit) {
client?.send(TdApi.GetMessage(chatId, messageId)) { 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)
}
}
TdApi.Message.CONSTRUCTOR -> onComplete(obj as TdApi.Message)
}
}
}
private fun addNewMessage(message: TdApi.Message) {
if (message.isAppropriate()) {
usersLocationMessages[message.senderUserId] = message
val chatTitle = chats[message.chatId]?.title
if (chatTitle != null) {
incomingMessagesListeners.forEach {
it.onReceiveChatLocationMessages(chatTitle, message)
}
}
}
}
@ -606,6 +594,30 @@ class TelegramHelper private constructor() {
listener?.onTelegramStatusChanged(prevAuthState, newAuthState)
}
private fun TdApi.Message.isAppropriate(): Boolean {
if (isOutgoing || isChannelPost) {
return false
}
val lastEdited = Math.max(date, editDate)
if (TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) - lastEdited > MESSAGE_ACTIVE_TIME_SEC) {
return false
}
val content = content
return when (content) {
is TdApi.MessageLocation -> true
is TdApi.MessageText -> {
if (content.text.text.startsWith("{")) {
// TODO: get user from library if null
if (users[senderUserId]?.username == OSMAND_BOT_USERNAME) {
return true
}
}
false
}
else -> false
}
}
class OrderedChat internal constructor(internal val order: Long, internal val chatId: Long, internal val isChannel: Boolean) : Comparable<OrderedChat> {
override fun compareTo(other: OrderedChat): Int {
@ -789,8 +801,12 @@ class TelegramHelper private constructor() {
}
TdApi.UpdateMessageContent.CONSTRUCTOR -> {
val updateMessageContent = obj as TdApi.UpdateMessageContent
val message = usersLiveMessages[updateMessageContent.messageId]
if (message != null && !message.isOutgoing) {
val message = getMessageById(updateMessageContent.messageId)
if (message == null) {
updateMessageContent.apply {
requestMessage(chatId, messageId, this@TelegramHelper::addNewMessage)
}
} else {
synchronized(message) {
message.content = updateMessageContent.newContent
}
@ -800,21 +816,10 @@ class TelegramHelper private constructor() {
it.onReceiveChatLocationMessages(chatTitle, message)
}
}
}
}
TdApi.UpdateNewMessage.CONSTRUCTOR -> {
val updateNewMessage = obj as TdApi.UpdateNewMessage
val message = updateNewMessage.message
if (!message.isOutgoing && message.content is TdApi.MessageLocation) {
usersLiveMessages[message.id] = message
val chatTitle = chats[message.chatId]?.title
if (chatTitle != null) {
incomingMessagesListeners.forEach {
it.onReceiveChatLocationMessages(chatTitle, message)
}
}
}
addNewMessage((obj as TdApi.UpdateNewMessage).message)
}
TdApi.UpdateMessageMentionRead.CONSTRUCTOR -> {
val updateChat = obj as TdApi.UpdateMessageMentionRead