The third argument is not your HTML
GmailApp.sendEmail takes four arguments: recipient, subject, body, and an options object. That third positional argument, body, is the plain-text version of the email. Put HTML there and recipients whose clients strip or block HTML will see raw tags in their inbox.
Your HTML goes in options.htmlBody. When a mail client supports HTML, it renders that string. When it does not, or when a user has images and rich content disabled, the client falls back to body. Both fields are required for a well-formed message.
The first time I hit this, I was putting a full HTML string as the third argument and wondering why Gmail itself was showing tags. The fix is one extra object literal: GmailApp.sendEmail(to, subject, plainText, { htmlBody: myHtml }).
The plain-text fallback does not need to be a stripped version of the HTML. A short summary sentence is enough. Its job is to survive the rare client or filter that refuses all HTML, not to duplicate the full message.