Home telegram - updateMessageService
Post
Cancel

telegram - updateMessageService

UpdateMessageService

class UpdateMessageService:NSObject,MTMessageService

1
2
3
var peerId: PeerId!
let pipe: ValuePipe<[UpdateGroup]> = ValuePipe()
var mtProto: MTProto?

Handle Proto Events

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func mtProtoWillAdd(_ mtProto: MTProto!) {
    self.mtProto = mtProto
}

// session changed
func mtProtoDidChangeSession(_ mtProto: MTProto!) {
  // reset
    self.pipe.putNext([.reset])
}

// server session changed
func mtProtoServerDidChangeSession(_ mtProto: MTProto!, firstValidMessageId: Int64, otherValidMessageIds: [Any]!) {
  // reset
    self.pipe.putNext([.reset])
}

// received new message
func mtProto(_ mtProto: MTProto!, receivedMessage message: MTIncomingMessage!) {
    if let updates = (message.body as? BoxedMessage)?.body as? Api.Updates {
        self.addUpdates(updates)
    }
}

UpdateGroup

enum UpdateGroup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
case withPts(updates: [Api.Update], users: [Api.User], chats: [Api.Chat])
case withQts(updates: [Api.Update], users: [Api.User], chats: [Api.Chat])
case withSeq(updates: [Api.Update], seqRange: (Int32, Int32), date: Int32, users: [Api.User], chats: [Api.Chat])
case withDate(updates: [Api.Update], date: Int32, users: [Api.User], chats: [Api.Chat])
case reset
case updatePts(pts: Int32, ptsCount: Int32)
case updateChannelPts(channelId: Int32, pts: Int32, ptsCount: Int32)

// updates
var updates: [Api.Update] {
    switch self {
        case let .withPts(updates, _, _):
            return updates
        case let .withDate(updates, _, _, _):
            return updates
        case let .withQts(updates, _, _):
            return updates
        case let .withSeq(updates, _, _, _, _):
            return updates
        case .reset, .updatePts, .updateChannelPts:
            return []
    }
}

// users
var users: [Api.User] {
    switch self {
        case let .withPts(_, users, _):
            return users
        case let .withDate(_, _, users, _):
            return users
        case let .withQts(_, users, _):
            return users
        case let .withSeq(_, _, _, users, _):
            return users
        case .reset, .updatePts, .updateChannelPts:
            return []
    }
}

// chats
var chats: [Api.Chat] {
    switch self {
        case let .withPts(_, _, chats):
            return chats
        case let .withDate(_, _, _, chats):
            return chats
        case let .withQts(_, _, chats):
            return chats
        case let .withSeq(_, _, _, _, chats):
            return chats
        case .reset, .updatePts, .updateChannelPts:
            return []
    }
}

PtsUpdate

struct PtsUpdate

1
2
3
4
let update: Api.Update?
let ptsRange: (Int32, Int32)
let users: [Api.User]
let chats: [Api.Chat]

QtsUpdate

struct QtsUpdate

1
2
3
4
let update: Api.Update
let qtsRange: (Int32, Int32)
let users: [Api.User]
let chats: [Api.Chat]

SeqUpdates

struct SeqUpdates

1
2
3
4
5
let updates: [Api.Update]
let seqRange: (Int32, Int32)
let date: Int32
let users: [Api.User]
let chats: [Api.Chat]

AddUpdates

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
func addUpdates(_ updates: Api.Updates) {
    switch updates {
        case let .updates(updates, users, chats, date, seq):
            let groups = groupUpdates(updates, users: users, chats: chats, date: date, seqRange: seq == 0 ? nil : (seq, 1))
            if groups.count != 0 {
                self.putNext(groups)
            }
        case let .updatesCombined(updates, users, chats, date, seqStart, seq):
            let groups = groupUpdates(updates, users: users, chats: chats, date: date, seqRange: seq == 0 ? nil : (seq, seq - seqStart))
            if groups.count != 0 {
                self.putNext(groups)
            }
        case let .updateShort(update, date):
            let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
            if groups.count != 0 {
                self.putNext(groups)
            }
        case let .updateShortChatMessage(flags, id, fromId, chatId, message, pts, ptsCount, date, fwdFrom, viaBotId, replyToMsgId, entities):
            let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: fromId, toId: Api.Peer.peerChat(chatId: chatId), fwdFrom: fwdFrom, viaBotId: viaBotId, replyToMsgId: replyToMsgId, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, editDate: nil, postAuthor: nil, groupedId: nil, restrictionReason: nil)
            let update = Api.Update.updateNewMessage(message: generatedMessage, pts: pts, ptsCount: ptsCount)
            let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
            if groups.count != 0 {
                self.putNext(groups)
            }
        case let .updateShortMessage(flags, id, userId, message, pts, ptsCount, date, fwdFrom, viaBotId, replyToMsgId, entities):
            let generatedFromId: Int32
            let generatedToId: Api.Peer
            if (Int(flags) & 2) != 0 {
                generatedFromId = self.peerId.id
                generatedToId = Api.Peer.peerUser(userId: userId)
            } else {
                generatedFromId = userId
                generatedToId = Api.Peer.peerUser(userId: self.peerId.id)
            }

            let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: generatedFromId, toId: generatedToId, fwdFrom: fwdFrom, viaBotId: viaBotId, replyToMsgId: replyToMsgId, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, editDate: nil, postAuthor: nil, groupedId: nil, restrictionReason: nil)
            let update = Api.Update.updateNewMessage(message: generatedMessage, pts: pts, ptsCount: ptsCount)
            let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
            if groups.count != 0 {
                self.putNext(groups)
            }
        case .updatesTooLong:
            self.pipe.putNext([.reset])
        case let .updateShortSentMessage(_, _, pts, ptsCount, _, _, _):
            self.pipe.putNext([.updatePts(pts: pts, ptsCount: ptsCount)])
    }
}

Group Updates

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
func groupUpdates(_ updates: [Api.Update], users: [Api.User], chats: [Api.Chat], date: Int32, seqRange: (Int32, Int32)?) -> [UpdateGroup] {
    var updatesWithPts: [Api.Update] = []
    var updatesWithQts: [Api.Update] = []
    var otherUpdates: [Api.Update] = []
    
    for update in updates {
        if let _ = apiUpdatePtsRange(update) {
            updatesWithPts.append(update)
        } else if let _ = apiUpdateQtsRange(update) {
            updatesWithQts.append(update)
        } else {
            otherUpdates.append(update)
        }
    }
    
    var groups: [UpdateGroup] = []
    if updatesWithPts.count != 0 {
        groups.append(.withPts(updates: updatesWithPts, users: users, chats: chats))
    }
    if updatesWithQts.count != 0 {
        groups.append(.withQts(updates: updatesWithQts, users: users, chats: chats))
    }
    
    if let seqRange = seqRange {
        groups.append(.withSeq(updates: otherUpdates, seqRange: seqRange, date: date, users: users, chats: chats))
    } else {
        groups.append(.withDate(updates: otherUpdates, date: date, users: users, chats: chats))
    }
    
    return groups
}
This post is licensed under CC BY 4.0 by the author.