From 751d13a35e323eb911b11394594d8ad54022f784 Mon Sep 17 00:00:00 2001 From: Harold Hunt Date: Fri, 13 Feb 2026 08:17:04 -0500 Subject: [PATCH 1/2] Allow Siri to send to bots with open chats --- Telegram/SiriIntents/IntentContacts.swift | 27 +++++++++++++++++++++++ Telegram/SiriIntents/IntentHandler.swift | 10 ++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/Telegram/SiriIntents/IntentContacts.swift b/Telegram/SiriIntents/IntentContacts.swift index bc9e10590c2..f702c30f7e6 100644 --- a/Telegram/SiriIntents/IntentContacts.swift +++ b/Telegram/SiriIntents/IntentContacts.swift @@ -117,6 +117,33 @@ func matchingCloudContacts(postbox: Postbox, contacts: [MatchingDeviceContact]) } } +func matchingOpenChatWithDeviceContacts(postbox: Postbox, contacts: [MatchingDeviceContact]) -> Signal<[(String, TelegramUser)], NoError> { + return postbox.transaction { transaction -> [(String, TelegramUser)] in + var result: [(String, TelegramUser)] = [] + let contactPeerIds = transaction.getContactPeerIds() + + outer: for peerId in transaction.chatListGetAllPeerIds(groupId: .root) { + if contactPeerIds.contains(peerId) { + continue + } + if peerId.namespace != Namespaces.Peer.CloudUser { + continue + } + guard let user = transaction.getPeer(peerId) as? TelegramUser, !user.isDeleted else { + continue + } + for contact in contacts { + if let contactPeerId = contact.peerId, contactPeerId == peerId { + result.append((contact.stableId, user)) + continue outer + } + } + } + + return result + } +} + func matchingCloudContact(postbox: Postbox, peerId: PeerId) -> Signal { return postbox.transaction { transaction -> TelegramUser? in if let user = transaction.getPeer(peerId) as? TelegramUser { diff --git a/Telegram/SiriIntents/IntentHandler.swift b/Telegram/SiriIntents/IntentHandler.swift index 46395e888b4..8f234a083c1 100644 --- a/Telegram/SiriIntents/IntentHandler.swift +++ b/Telegram/SiriIntents/IntentHandler.swift @@ -335,7 +335,15 @@ class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchFo |> castError(IntentContactsError.self) |> mapToSignal { account -> Signal<[(String, TelegramUser)], IntentContactsError> in if let account = account { - return matchingCloudContacts(postbox: account.postbox, contacts: matchedContacts) + return combineLatest( + matchingCloudContacts(postbox: account.postbox, contacts: matchedContacts), + matchingOpenChatWithDeviceContacts(postbox: account.postbox, contacts: matchedContacts) + ) + |> map { cloudContacts, openChatContacts in + var result = cloudContacts + result.append(contentsOf: openChatContacts) + return result + } |> castError(IntentContactsError.self) } else { return .fail(.generic) From 7a6184aef77b2ee2a29cd161bd310cdadaa6cc98 Mon Sep 17 00:00:00 2001 From: Harold Hunt Date: Fri, 13 Feb 2026 08:31:45 -0500 Subject: [PATCH 2/2] Open chats - only match leftovers --- Telegram/SiriIntents/IntentHandler.swift | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Telegram/SiriIntents/IntentHandler.swift b/Telegram/SiriIntents/IntentHandler.swift index 8f234a083c1..2447f2ef4dd 100644 --- a/Telegram/SiriIntents/IntentHandler.swift +++ b/Telegram/SiriIntents/IntentHandler.swift @@ -335,14 +335,19 @@ class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchFo |> castError(IntentContactsError.self) |> mapToSignal { account -> Signal<[(String, TelegramUser)], IntentContactsError> in if let account = account { - return combineLatest( - matchingCloudContacts(postbox: account.postbox, contacts: matchedContacts), - matchingOpenChatWithDeviceContacts(postbox: account.postbox, contacts: matchedContacts) - ) - |> map { cloudContacts, openChatContacts in - var result = cloudContacts - result.append(contentsOf: openChatContacts) - return result + return matchingCloudContacts(postbox: account.postbox, contacts: matchedContacts) + |> mapToSignal { cloudContacts -> Signal<[(String, TelegramUser)], NoError> in + let matchedStableIds = Set(cloudContacts.map { $0.0 }) + let unmatchedContacts = matchedContacts.filter { !matchedStableIds.contains($0.stableId) } + if unmatchedContacts.isEmpty { + return .single(cloudContacts) + } + return matchingOpenChatWithDeviceContacts(postbox: account.postbox, contacts: unmatchedContacts) + |> map { openChatContacts -> [(String, TelegramUser)] in + var result = cloudContacts + result.append(contentsOf: openChatContacts) + return result + } } |> castError(IntentContactsError.self) } else {