import Foundation import Postbox import SwiftSignalKit import TelegramApi import MtProtoKit import SyncCore public func requestStartBot(account: Account, botPeerId: PeerId, payload: String?) -> Signal { if let payload = payload, !payload.isEmpty { return account.postbox.loadedPeerWithId(botPeerId) |> mapToSignal { botPeer -> Signal in if let inputUser = apiInputUser(botPeer) { let r = account.network.request(Api.functions.messages.startBot(bot: inputUser, peer: .inputPeerEmpty, randomId: arc4random64(), startParam: payload)) |> mapToSignal { result -> Signal in account.stateManager.addUpdates(result) return .complete() } |> `catch` { _ -> Signal in return .complete() } return r |> retryRequest } else { return .complete() } } } else { return enqueueMessages(account: account, peerId: botPeerId, messages: [.message(text: "/start", attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)]) |> mapToSignal { _ -> Signal in return .complete() } } } public enum RequestStartBotInGroupError { case generic } public enum StartBotInGroupResult { case none case channelParticipant(RenderedChannelParticipant) } public func requestStartBotInGroup(account: Account, botPeerId: PeerId, groupPeerId: PeerId, payload: String?) -> Signal { return account.postbox.transaction { transaction -> (Peer?, Peer?) in return (transaction.getPeer(botPeerId), transaction.getPeer(groupPeerId)) } |> mapError { _ -> RequestStartBotInGroupError in return .generic } |> mapToSignal { botPeer, groupPeer -> Signal in if let botPeer = botPeer, let inputUser = apiInputUser(botPeer), let groupPeer = groupPeer, let inputGroup = apiInputPeer(groupPeer) { let request = account.network.request(Api.functions.messages.startBot(bot: inputUser, peer: inputGroup, randomId: arc4random64(), startParam: payload ?? "")) |> mapError { _ -> RequestStartBotInGroupError in return .generic } |> mapToSignal { result -> Signal in account.stateManager.addUpdates(result) if groupPeerId.namespace == Namespaces.Peer.CloudChannel { return fetchChannelParticipant(account: account, peerId: groupPeerId, participantId: botPeerId) |> mapError { _ -> RequestStartBotInGroupError in return .generic } |> mapToSignal { participant -> Signal in return account.postbox.transaction { transaction -> StartBotInGroupResult in if let participant = participant, let peer = transaction.getPeer(participant.peerId) { var peers: [PeerId: Peer] = [:] let presences: [PeerId: PeerPresence] = [:] peers[peer.id] = peer return .channelParticipant(RenderedChannelParticipant(participant: participant, peer: peer, peers: peers, presences: presences)) } else { return .none } } |> mapError { _ -> RequestStartBotInGroupError in return .generic } } } else { return .single(.none) } } return request } else { return .complete() } } }