@@ -91,6 +91,40 @@ abstract class NotificationProcessor(context: Context) {
9191 @VisibleForTesting
9292 val msgTitlePattern: Pattern = Pattern .compile(" ^(\\ [特别关心])?.*?(?: \\ ((\\ d+)条新消息\\ ))?$" )
9393
94+ // 关联QQ消息
95+ // title:
96+ // - 只有一条消息: 关联QQ号
97+ // - 一人发来多条消息: 关联QQ号 ({x}条新消息)
98+ // - 多人发来消息: QQ
99+ // ticker: 关联QQ号-{关联昵称} {发送者昵称}:{消息内容}
100+ // content:
101+ // - 一人发来消息: {消息内容}
102+ // - 多人发来消息: 有 {x} 个联系人给你发过来{y}条新消息
103+
104+ /* *
105+ * 匹配关联 QQ 消息 ticker.
106+ *
107+ * Group: 1关联账号昵称, 2消息内容
108+ */
109+ @VisibleForTesting
110+ val bindingQQMsgTickerPattern: Pattern = Pattern .compile(" ^关联QQ号-(.+?):([\\ s\\ S]+)$" )
111+
112+ /* *
113+ * 匹配关联 QQ 消息 content. 用于提取未读消息个数。
114+ *
115+ * Group: 1未读消息个数
116+ */
117+ @VisibleForTesting
118+ val bindingQQMsgContextPattern: Pattern = Pattern .compile(" ^有 (?:\\ d+) 个联系人给你发过来(\\ d+)条新消息$" )
119+
120+ /* *
121+ * 匹配关联 QQ 消息 title. 用于提取未读消息个数。
122+ *
123+ * Group: 1未读消息个数
124+ */
125+ @VisibleForTesting
126+ val bindingQQMsgTitlePattern: Pattern = Pattern .compile(" ^关联QQ号 \\ ((\\ d+)条新消息\\ )$" )
127+
94128 // Q空间动态
95129 // title(与我相关): QQ空间动态(共x条未读); (特别关心): QQ空间动态
96130 // ticker(与我相关): 详情(例如xxx评论了你); (特别关心): 【特别关心】昵称:内容
@@ -161,8 +195,10 @@ abstract class NotificationProcessor(context: Context) {
161195 * 检测到合并消息的回调。
162196 *
163197 * 合并消息:有 x 个联系人给你发过来y条新消息
198+ *
199+ * @param isBindingMsg 是否来自关联 QQ 的消息。
164200 */
165- protected open fun onMultiMessageDetected () {}
201+ protected open fun onMultiMessageDetected (isBindingMsg : Boolean ) {}
166202
167203 /* *
168204 * 创建优化后的QQ空间通知。
@@ -234,7 +270,7 @@ abstract class NotificationProcessor(context: Context) {
234270 Timber .tag(TAG ).v(" Title: $title ; Ticker: $ticker ; QZone: $isQzone ; Multi: $isMulti ; Content: $content " )
235271
236272 if (isMulti) {
237- onMultiMessageDetected()
273+ onMultiMessageDetected(ticker?.contains( " 关联QQ号- " ) ? : false )
238274 }
239275
240276 // 隐藏消息详情
@@ -319,6 +355,21 @@ abstract class NotificationProcessor(context: Context) {
319355 }
320356 }
321357 }
358+
359+ // 关联账号消息
360+ bindingQQMsgTickerPattern.matcher(ticker).also { matcher ->
361+ if (matcher.matches()) {
362+ val account = matcher.group(1 ) ? : " "
363+ val text = matcher.group(2 ) ? : return null
364+ val conversation = addMessage(tag, context.getString(R .string.notify_binding_msg_title, account),
365+ text, null , getNotifyLargeIcon(context, original), original.contentIntent,
366+ original.deleteIntent, false )
367+ deleteOldMessage(conversation, matchBindingMsgNum(title, content))
368+ Timber .tag(TAG ).d(" [Binding] Account: $account ; Text: $text " )
369+ return renewConversionNotification(context, tag, NotifyChannel .FRIEND , conversation, sbn, original)
370+ }
371+ }
372+
322373 Timber .tag(TAG ).w(" [None] Not match any pattern." )
323374 return null
324375 }
@@ -367,6 +418,28 @@ abstract class NotificationProcessor(context: Context) {
367418 return 0
368419 }
369420
421+ /* *
422+ * 提取关联账号的未读消息个数。
423+ */
424+ private fun matchBindingMsgNum (title : String? , content : String? ): Int {
425+ if (title == null || content == null ) return 1
426+ if (title == " QQ" ) {
427+ bindingQQMsgContextPattern.matcher(content).also { matcher ->
428+ if (matcher.matches()) {
429+ return matcher.group(1 )?.toInt() ? : 1
430+ }
431+ }
432+ } else {
433+ bindingQQMsgTitlePattern.matcher(title).also { matcher ->
434+ if (matcher.matches()) {
435+ return matcher.group(1 )?.toInt() ? : 1
436+ }
437+ }
438+ }
439+
440+ return 1
441+ }
442+
370443 /* *
371444 * 获取通知的大图标。
372445 *
0 commit comments