@@ -121,6 +121,49 @@ enum CarPlayIntentDonation {
121121
122122 // MARK: - Helpers
123123
124+ /// Builds an INSendMessageIntent for a received message, suitable for use with
125+ /// Communication Notifications (`UNMutableNotificationContent.updating(from:)`).
126+ /// Returns nil if the message has no sender.
127+ static func incomingMessageIntent( from message: MessageEntity ) -> INSendMessageIntent ? {
128+ guard let fromUser = message. fromUser else { return nil }
129+
130+ let sender = IntentMessageConverters . inPerson ( from: fromUser)
131+ let me = mePerson ( )
132+
133+ if message. toUser != nil {
134+ // Direct message
135+ return INSendMessageIntent (
136+ recipients: [ me] ,
137+ outgoingMessageType: . outgoingMessageText,
138+ content: message. messagePayload,
139+ speakableGroupName: nil ,
140+ conversationIdentifier: " dm- \( fromUser. num) " ,
141+ serviceName: " Meshtastic " ,
142+ sender: sender,
143+ attachments: nil
144+ )
145+ } else {
146+ // Channel message
147+ let channelName = channelDisplayName ( for: message. channel)
148+ let groupName = INSpeakableString ( spokenPhrase: channelName)
149+ let intent = INSendMessageIntent (
150+ recipients: [ me] ,
151+ outgoingMessageType: . outgoingMessageText,
152+ content: message. messagePayload,
153+ speakableGroupName: groupName,
154+ conversationIdentifier: " channel- \( message. channel) " ,
155+ serviceName: " Meshtastic " ,
156+ sender: sender,
157+ attachments: nil
158+ )
159+ intent. setImage (
160+ INImage ( named: " antenna.radiowaves.left.and.right " ) ,
161+ forParameterNamed: \. speakableGroupName
162+ )
163+ return intent
164+ }
165+ }
166+
124167 static func mePerson( ) -> INPerson {
125168 let meHandle = INPersonHandle ( value: " me " , type: . unknown)
126169 return INPerson (
0 commit comments