@@ -80,19 +80,15 @@ def _normalize_path(path: Any) -> str:
8080 return raw if raw .startswith ("/" ) else f"/{ raw } "
8181
8282 @staticmethod
83- def _build_receipt_key (notification : Dict [str , Any ]) -> str :
83+ def _build_receipt_key (notification : Dict [str , Any ]) -> Optional [ str ] :
8484 explicit_id = str (notification .get ("id" ) or "" ).strip ()
8585 if explicit_id :
8686 return f"id:{ explicit_id } "
87- payload = "|" .join (
88- [
89- str (notification .get ("subscriptionId" ) or "" ),
90- str (notification .get ("changeType" ) or "" ),
91- str (notification .get ("resource" ) or "" ),
92- json .dumps (notification .get ("resourceData" ) or {}, sort_keys = True ),
93- ]
94- )
95- return f"sha1:{ sha1 (payload .encode ('utf-8' )).hexdigest ()} "
87+ return None
88+
89+ @staticmethod
90+ def _normalize_resource_value (resource : str ) -> str :
91+ return str (resource or "" ).strip ().strip ("/" )
9692
9793 def set_notification_scheduler (self , scheduler : Optional [NotificationScheduler ]) -> None :
9894 self ._notification_scheduler = scheduler
@@ -178,10 +174,11 @@ async def _handle_notification(self, request: "web.Request") -> "web.Response":
178174 continue
179175
180176 receipt_key = self ._build_receipt_key (notification )
181- if self ._has_seen_receipt (receipt_key ):
182- duplicates += 1
183- continue
184- self ._remember_receipt (receipt_key )
177+ if receipt_key is not None :
178+ if self ._has_seen_receipt (receipt_key ):
179+ duplicates += 1
180+ continue
181+ self ._remember_receipt (receipt_key )
185182
186183 accepted += 1
187184 scheduled += 1
@@ -205,10 +202,20 @@ async def _handle_notification(self, request: "web.Request") -> "web.Response":
205202 def _resource_accepted (self , resource : str ) -> bool :
206203 if not self ._accepted_resources :
207204 return True
205+ normalized_resource = self ._normalize_resource_value (resource )
208206 for pattern in self ._accepted_resources :
209- if pattern .endswith ("*" ) and resource .startswith (pattern [:- 1 ]):
210- return True
211- if resource == pattern or resource .startswith (f"{ pattern } /" ):
207+ normalized_pattern = self ._normalize_resource_value (pattern )
208+ if not normalized_pattern :
209+ continue
210+ if normalized_pattern .endswith ("*" ):
211+ prefix = normalized_pattern [:- 1 ].rstrip ("/" )
212+ if normalized_resource == prefix or normalized_resource .startswith (f"{ prefix } /" ):
213+ return True
214+ continue
215+ if (
216+ normalized_resource == normalized_pattern
217+ or normalized_resource .startswith (f"{ normalized_pattern } /" )
218+ ):
212219 return True
213220 return False
214221
@@ -232,8 +239,9 @@ def _remember_receipt(self, receipt_key: str) -> None:
232239 def _build_message_event (
233240 self ,
234241 notification : Dict [str , Any ],
235- receipt_key : str ,
242+ receipt_key : Optional [ str ] ,
236243 ) -> MessageEvent :
244+ message_id = receipt_key or f"sha1:{ sha1 (json .dumps (notification , sort_keys = True ).encode ('utf-8' )).hexdigest ()} "
237245 source = self .build_source (
238246 chat_id = f"msgraph:{ notification .get ('subscriptionId' , 'unknown' )} " ,
239247 chat_name = "msgraph/webhook" ,
@@ -246,7 +254,7 @@ def _build_message_event(
246254 message_type = MessageType .TEXT ,
247255 source = source ,
248256 raw_message = notification ,
249- message_id = receipt_key ,
257+ message_id = message_id ,
250258 internal = True ,
251259 )
252260
0 commit comments