| 187 | |
| 188 | |
| 189 | def send_invitation_email( |
| 190 | email: EmailStr, |
| 191 | org_name: str, |
| 192 | inviter_username: str, |
| 193 | signup_url: str, |
| 194 | invite_code: Optional[str] = None, |
| 195 | lang: str = "en", |
| 196 | ): |
| 197 | safe_org_name = html.escape(org_name) |
| 198 | safe_inviter = html.escape(inviter_username) |
| 199 | |
| 200 | code_section = "" |
| 201 | if invite_code: |
| 202 | safe_code = html.escape(invite_code) |
| 203 | code_hint = t(lang, "invitation.code_hint") |
| 204 | code_section = f""" |
| 205 | <div style="margin: 28px 0;"> |
| 206 | <span style="{STYLES['code']}">{safe_code}</span> |
| 207 | </div> |
| 208 | <p style="{STYLES['p']}"> |
| 209 | {code_hint} |
| 210 | </p>""" |
| 211 | else: |
| 212 | code_section = f""" |
| 213 | <p style="{STYLES['p']}"> |
| 214 | {t(lang, "invitation.no_code_hint")} |
| 215 | </p>""" |
| 216 | |
| 217 | heading = t(lang, "invitation.heading") |
| 218 | intro = t(lang, "invitation.intro", inviter=safe_inviter, org_name=safe_org_name) |
| 219 | cta = t(lang, "invitation.cta", org_name=safe_org_name) |
| 220 | |
| 221 | body_content = f""" |
| 222 | <h1 style="{STYLES['h1']}">{heading}</h1> |
| 223 | <p style="{STYLES['p']}"> |
| 224 | {intro} |
| 225 | </p> |
| 226 | {code_section} |
| 227 | <a href="{signup_url}" style="{STYLES['button']}"> |
| 228 | {cta} |
| 229 | </a> |
| 230 | """ |
| 231 | |
| 232 | return send_email( |
| 233 | to=email, |
| 234 | subject=t(lang, "invitation.subject", org_name=safe_org_name), |
| 235 | body=_email_layout( |
| 236 | title=heading, |
| 237 | body_content=body_content, |
| 238 | footer_note=t(lang, "invitation.footer", inviter=safe_inviter), |
| 239 | ), |
| 240 | ) |
| 241 | |
| 242 | |
| 243 | def send_role_changed_email( |