(
self,
email: str,
email_id: str = None,
timeout: int = 120,
pattern: str = OTP_CODE_PATTERN,
otp_sent_at: Optional[float] = None,
)
| 212 | raise EmailServiceError(f"创建 Web2 邮箱失败: {e}") |
| 213 | |
| 214 | def get_verification_code( |
| 215 | self, |
| 216 | email: str, |
| 217 | email_id: str = None, |
| 218 | timeout: int = 120, |
| 219 | pattern: str = OTP_CODE_PATTERN, |
| 220 | otp_sent_at: Optional[float] = None, |
| 221 | ) -> Optional[str]: |
| 222 | mailbox = self._resolve_mailbox(email, email_id) |
| 223 | if not mailbox: |
| 224 | logger.warning("Web2 未找到邮箱缓存: %s", email) |
| 225 | return None |
| 226 | |
| 227 | token = str(mailbox.get("token") or "").strip() |
| 228 | if not token: |
| 229 | logger.warning("Web2 邮箱缺少 token,尝试使用 service_id 兜底: %s", email) |
| 230 | token = str(mailbox.get("service_id") or "").strip() |
| 231 | if not token: |
| 232 | logger.warning("Web2 邮箱缺少 token: %s", email) |
| 233 | return None |
| 234 | |
| 235 | email_norm = str(email or mailbox.get("email") or "").strip().lower() |
| 236 | seen_ids = self._seen_message_ids.setdefault(email_norm, set()) |
| 237 | start_time = time.time() |
| 238 | |
| 239 | while time.time() - start_time < timeout: |
| 240 | try: |
| 241 | response = self.http_client.get( |
| 242 | f"{self.config['base_url']}/messages", |
| 243 | headers=self._build_headers({ |
| 244 | "Cache-Control": "no-cache", |
| 245 | "Authorization": f"Bearer {token}", |
| 246 | }), |
| 247 | ) |
| 248 | if response.status_code != 200: |
| 249 | time.sleep(3) |
| 250 | continue |
| 251 | |
| 252 | payload = response.json() |
| 253 | if isinstance(payload, dict): |
| 254 | messages = payload.get("messages") |
| 255 | if messages is None: |
| 256 | messages = payload.get("data") or payload.get("items") or payload.get("results") or [] |
| 257 | elif isinstance(payload, list): |
| 258 | messages = payload |
| 259 | else: |
| 260 | messages = [] |
| 261 | if not isinstance(messages, list): |
| 262 | time.sleep(3) |
| 263 | continue |
| 264 | |
| 265 | for message in messages: |
| 266 | if not isinstance(message, dict): |
| 267 | continue |
| 268 | message_id = self._extract_message_id(message) |
| 269 | if message_id in seen_ids: |
| 270 | continue |
| 271 | seen_ids.add(message_id) |
nothing calls this directly
no test coverage detected