1818from .email import parse_email_recipients , send_smtp_email
1919
2020
21- _GOOGLE_VOICE_SMTP_HOST = "smtp.gmail.com"
22- _GOOGLE_VOICE_SMTP_PORT = 465
23- _GOOGLE_VOICE_SMTP_STARTTLS = False
24- _GOOGLE_VOICE_SMTP_SSL = True
21+ _DEFAULT_GOOGLE_VOICE_SMTP_HOST = "smtp.gmail.com"
22+ _DEFAULT_GOOGLE_VOICE_SMTP_PORT = 465
23+ _DEFAULT_GOOGLE_VOICE_SMTP_SECURITY = "ssl"
24+ _SMTP_SECURITY_NONE = "none"
25+ _SMTP_SECURITY_SSL = "ssl"
26+ _SMTP_SECURITY_STARTTLS = "starttls"
27+ _SMTP_SECURITY_VALUES = {
28+ _SMTP_SECURITY_NONE ,
29+ _SMTP_SECURITY_SSL ,
30+ _SMTP_SECURITY_STARTTLS ,
31+ }
2532
2633
2734@dataclass (frozen = True )
2835class StrategyPluginGoogleVoiceSettings :
2936 recipients : tuple [str , ...] = ()
30- gmail_user : str | None = None
31- gmail_app_password : str | None = field (default = None , repr = False )
37+ sender_email : str | None = None
38+ sender_password : str | None = field (default = None , repr = False )
39+ smtp_host : str = _DEFAULT_GOOGLE_VOICE_SMTP_HOST
40+ smtp_port : int = _DEFAULT_GOOGLE_VOICE_SMTP_PORT
41+ smtp_security : str = _DEFAULT_GOOGLE_VOICE_SMTP_SECURITY
3242 timeout : float = 10.0
3343
3444 @classmethod
@@ -39,18 +49,29 @@ def from_object(cls, value: object) -> "StrategyPluginGoogleVoiceSettings":
3949 recipients = tuple (
4050 parse_email_recipients (_get_value (value , "crisis_alert_google_voice_recipients" , ()))
4151 ),
42- gmail_user = _first_non_empty (_get_value (value , "crisis_alert_google_voice_gmail_user" )),
43- gmail_app_password = _get_value (value , "crisis_alert_google_voice_gmail_app_password" ),
52+ sender_email = _first_non_empty (_get_value (value , "crisis_alert_google_voice_sender_email" )),
53+ sender_password = _get_value (value , "crisis_alert_google_voice_sender_password" ),
54+ smtp_host = _first_non_empty (
55+ _get_value (value , "crisis_alert_google_voice_smtp_host" )
56+ )
57+ or _DEFAULT_GOOGLE_VOICE_SMTP_HOST ,
58+ smtp_port = _coerce_int (
59+ _get_value (value , "crisis_alert_google_voice_smtp_port" ),
60+ _DEFAULT_GOOGLE_VOICE_SMTP_PORT ,
61+ ),
62+ smtp_security = _coerce_smtp_security (
63+ _get_value (value , "crisis_alert_google_voice_smtp_security" )
64+ ),
4465 )
4566
4667 def missing_fields (self ) -> tuple [str , ...]:
4768 missing : list [str ] = []
4869 if not parse_email_recipients (self .recipients ):
4970 missing .append ("CRISIS_ALERT_GOOGLE_VOICE_RECIPIENTS" )
50- if not str (self .gmail_user or "" ).strip ():
51- missing .append ("CRISIS_ALERT_GOOGLE_VOICE_GMAIL_USER " )
52- if not str (self .gmail_app_password or "" ).strip ():
53- missing .append ("CRISIS_ALERT_GOOGLE_VOICE_GMAIL_APP_PASSWORD " )
71+ if not str (self .sender_email or "" ).strip ():
72+ missing .append ("CRISIS_ALERT_GOOGLE_VOICE_SENDER_EMAIL " )
73+ if not str (self .sender_password or "" ).strip ():
74+ missing .append ("CRISIS_ALERT_GOOGLE_VOICE_SENDER_PASSWORD " )
5475 return tuple (missing )
5576
5677 @property
@@ -278,14 +299,14 @@ def _send_message(
278299 sent = send_notification (
279300 subject = message .subject ,
280301 body = message .body ,
281- smtp_host = _GOOGLE_VOICE_SMTP_HOST ,
282- smtp_port = _GOOGLE_VOICE_SMTP_PORT ,
283- sender = settings .gmail_user ,
302+ smtp_host = settings . smtp_host ,
303+ smtp_port = settings . smtp_port ,
304+ sender = settings .sender_email ,
284305 recipients = settings .recipients ,
285- username = settings .gmail_user ,
286- password = settings .gmail_app_password ,
287- use_starttls = _GOOGLE_VOICE_SMTP_STARTTLS ,
288- use_ssl = _GOOGLE_VOICE_SMTP_SSL ,
306+ username = settings .sender_email ,
307+ password = settings .sender_password ,
308+ use_starttls = settings . smtp_security == _SMTP_SECURITY_STARTTLS ,
309+ use_ssl = settings . smtp_security == _SMTP_SECURITY_SSL ,
289310 timeout = settings .timeout ,
290311 )
291312 except Exception as exc :
@@ -365,6 +386,23 @@ def _first_non_empty(*values: Any) -> str | None:
365386 return None
366387
367388
389+ def _coerce_int (value : Any , default : int ) -> int :
390+ text = str (value or "" ).strip ()
391+ if not text :
392+ return default
393+ try :
394+ return int (text )
395+ except (TypeError , ValueError ):
396+ return default
397+
398+
399+ def _coerce_smtp_security (value : Any ) -> str :
400+ security = str (value or "" ).strip ().lower ()
401+ if security in _SMTP_SECURITY_VALUES :
402+ return security
403+ return _DEFAULT_GOOGLE_VOICE_SMTP_SECURITY
404+
405+
368406def _fallback_alert_key (message : StrategyPluginAlertMessage ) -> str :
369407 return "strategy_plugin_google_voice_alert/" + _clean_relative_key (message .subject or "unknown" )
370408
0 commit comments