[{"data":1,"prerenderedAt":636},["ShallowReactive",2],{"bootstrap":3,"blog-how-to-send-templated-emails-with-commerce-layer-and-sendgrid":277},{"navigation":4,"globalConfig":196,"forms":218},{"headerSections":5,"headerFooterLinks":67,"footer":76,"legalLinks":153,"socialLinks":176},[6,39,44,50,57,62],{"hasSubMenu":7,"title":8,"links":9,"columns":38},true,"Product",[10,20,26,32],{"showTag":11,"_modelApiKey":12,"text":13,"subtitle":14,"icon":15,"isExternal":11,"link":16,"openForm":11},false,"navigation_link","Universal checkout","Sell anywhere","globe-simple",{"_modelApiKey":17,"slug":18,"title":19},"page","universal-checkout","Universal Checkout",{"showTag":11,"_modelApiKey":12,"text":21,"subtitle":22,"icon":23,"isExternal":11,"link":24,"openForm":11},"Distributed OMS","Manage orders","package",{"_modelApiKey":17,"slug":25,"title":21},"distributed-oms",{"showTag":11,"_modelApiKey":12,"text":27,"subtitle":28,"icon":29,"isExternal":11,"link":30,"openForm":11},"Promotion engine","Automated discounts","seal-percent",{"_modelApiKey":17,"slug":31,"title":27},"promotion-engine",{"showTag":11,"_modelApiKey":12,"text":33,"subtitle":34,"icon":35,"isExternal":11,"link":36,"openForm":11},"POS system","Operate stores","devices",{"_modelApiKey":17,"slug":37,"title":33},"pos-system",2,{"hasSubMenu":11,"showTag":11,"_modelApiKey":12,"text":40,"isExternal":11,"link":41,"openForm":11,"title":40},"Pricing",{"_modelApiKey":42,"slug":43},"pricing_page","pricing",{"hasSubMenu":11,"showTag":11,"_modelApiKey":12,"text":45,"isExternal":11,"link":46,"openForm":11,"title":45},"Customers",{"_modelApiKey":47,"slug":48,"title":49},"customer_landing_page","customers","Customers page",{"hasSubMenu":11,"showTag":11,"_modelApiKey":12,"text":51,"isExternal":11,"link":52,"openForm":11,"form":54,"title":51},"Partners",{"_modelApiKey":17,"slug":53,"title":51},"partners",{"_modelApiKey":55,"slug":53,"name":56},"form","PartnersForm",{"hasSubMenu":11,"showTag":11,"_modelApiKey":12,"text":58,"label":59,"isExternal":7,"url":60,"openForm":11,"title":61},"Docs Hub","Learn more","https:\u002F\u002Fdocs.commercelayer.io\u002F","Docs",{"hasSubMenu":11,"showTag":11,"_modelApiKey":12,"text":63,"isExternal":11,"link":64,"openForm":11,"title":63},"Blog",{"_modelApiKey":65,"slug":66},"blog_landing_page","blog",[68,72],{"text":69,"link":70},"Sign in",{"_modelApiKey":12,"text":69,"isExternal":7,"url":71,"openForm":11},"https:\u002F\u002Fdashboard.commercelayer.io\u002Fsign_in",{"text":73,"link":74},"Sign up for free",{"_modelApiKey":12,"text":73,"isExternal":7,"url":75,"openForm":11},"https:\u002F\u002Fdashboard.commercelayer.io\u002Fsign_up",[77,89,109,132],{"hasSubMenu":7,"title":8,"links":78},[79,81,83,85,87],{"showTag":11,"_modelApiKey":12,"text":13,"subtitle":14,"icon":15,"isExternal":11,"link":80,"openForm":11},{"_modelApiKey":17,"slug":18,"title":19},{"showTag":11,"_modelApiKey":12,"text":21,"subtitle":22,"icon":23,"isExternal":11,"link":82,"openForm":11},{"_modelApiKey":17,"slug":25,"title":21},{"showTag":11,"_modelApiKey":12,"text":27,"subtitle":28,"icon":29,"isExternal":11,"link":84,"openForm":11},{"_modelApiKey":17,"slug":31,"title":27},{"showTag":11,"_modelApiKey":12,"text":33,"subtitle":34,"icon":35,"isExternal":11,"link":86,"openForm":11},{"_modelApiKey":17,"slug":37,"title":33},{"showTag":11,"_modelApiKey":12,"text":40,"isExternal":11,"link":88,"openForm":11},{"_modelApiKey":42,"slug":43},{"hasSubMenu":7,"title":90,"links":91},"Resources",[92,94,99,104,107],{"showTag":11,"_modelApiKey":12,"text":93,"isExternal":7,"url":60,"openForm":11},"Documentation",{"showTag":11,"_modelApiKey":12,"text":95,"label":95,"isExternal":11,"link":96,"openForm":11},"Agentic Commerce",{"_modelApiKey":17,"slug":97,"title":98},"agentic-commerce-whitepaper","Agentic Commerce Whitepaper",{"showTag":11,"_modelApiKey":12,"text":100,"isExternal":11,"link":101,"openForm":11},"Core concepts",{"_modelApiKey":17,"slug":102,"title":103},"headless-commerce","Headless commerce",{"showTag":11,"_modelApiKey":12,"text":105,"isExternal":7,"url":106,"openForm":11},"Changelog","https:\u002F\u002Fdocs.commercelayer.io\u002Fchangelog\u002F",{"showTag":11,"_modelApiKey":12,"text":63,"isExternal":11,"link":108,"openForm":11},{"_modelApiKey":65,"slug":66},{"hasSubMenu":7,"title":110,"links":111},"Company",[112,116,118,121,126],{"showTag":11,"_modelApiKey":12,"text":113,"isExternal":11,"link":114,"openForm":11},"Vision",{"_modelApiKey":17,"slug":115,"title":113},"vision",{"showTag":11,"_modelApiKey":12,"text":45,"isExternal":11,"link":117,"openForm":11},{"_modelApiKey":47,"slug":48,"title":49},{"showTag":11,"_modelApiKey":12,"text":51,"isExternal":11,"link":119,"openForm":11,"form":120},{"_modelApiKey":17,"slug":53,"title":51},{"_modelApiKey":55,"slug":53,"name":56},{"showTag":11,"_modelApiKey":12,"text":122,"isExternal":11,"link":123,"openForm":11},"Security",{"_modelApiKey":17,"slug":124,"title":125},"security","Security at Commerce Layer",{"showTag":11,"_modelApiKey":12,"text":127,"label":128,"isExternal":11,"openForm":7,"form":129},"Giveback","Giveback program",{"_modelApiKey":55,"slug":130,"name":131},"giveback","GivebackForm",{"hasSubMenu":7,"title":133,"links":134},"Get in touch",[135,140,145,149],{"showTag":11,"_modelApiKey":12,"text":136,"isExternal":11,"openForm":7,"form":137},"Contact",{"_modelApiKey":55,"slug":138,"name":139},"contact","ContactUsForm",{"showTag":11,"_modelApiKey":12,"text":141,"isExternal":11,"openForm":7,"form":142},"Book a demo",{"_modelApiKey":55,"slug":143,"name":144},"demo","RequestDemoForm",{"showTag":11,"_modelApiKey":12,"text":146,"label":147,"isExternal":7,"url":148,"openForm":11},"Support","Email support","mailto:support@commercelayer.io",{"showTag":11,"_modelApiKey":12,"text":150,"label":151,"isExternal":7,"url":152,"openForm":11},"Community","Discord community","https:\u002F\u002Fdiscord.gg\u002Fcommercelayer",{"hasSubMenu":7,"title":154,"links":155},"Legal",[156,161,165,169,173],{"showTag":11,"_modelApiKey":12,"text":157,"label":158,"isExternal":7,"url":159,"openForm":11,"htmlClassNames":160},"Terms","Terms and conditions","\u002Flegal-embed\u002Fterms-of-service","iubenda-nostyle no-brand iubenda-noiframe iubenda-embed",{"showTag":11,"_modelApiKey":12,"text":162,"label":163,"isExternal":7,"url":164,"openForm":11,"htmlClassNames":160},"Privacy","Privacy policy","\u002Flegal-embed\u002Fprivacy-policy",{"showTag":11,"_modelApiKey":12,"text":166,"label":167,"isExternal":7,"url":168,"openForm":11,"htmlClassNames":160},"Cookies","Cookie policy","\u002Flegal-embed\u002Fcookie-policy",{"showTag":11,"_modelApiKey":12,"text":170,"isExternal":7,"url":171,"openForm":11,"htmlClassNames":172},"Notice at collection","#","iubenda-cs-uspr-link",{"showTag":11,"_modelApiKey":12,"text":174,"isExternal":7,"url":171,"openForm":11,"htmlClassNames":175},"Privacy preferences","iubenda-cs-preferences-link",[177,180,184,188,192],{"title":178,"type":179,"url":152,"isExternal":7},"Discord","discord-logo",{"title":181,"type":182,"url":183,"isExternal":7},"Github","github","https:\u002F\u002Fgithub.com\u002Fcommercelayer",{"title":185,"type":186,"url":187,"isExternal":7},"Bluesky","bluesky-logo","https:\u002F\u002Fbsky.app\u002Fprofile\u002Fcommercelayer.io",{"title":189,"type":190,"url":191,"isExternal":7},"X","x-logo","https:\u002F\u002Fx.com\u002Fcommercelayer",{"title":193,"type":194,"url":195,"isExternal":7},"LinkedIn","linkedin","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fcommerce-layer",{"pagesWithoutCtaPanel":197,"ctaPanel":198,"notification":208,"showApiResponseTime":11,"newsletterSignup":216},[],{"title":199,"subtitle":200,"ctas":201},"Ready to get started?","Discover how we can help your business.",[202,205],{"_modelApiKey":203,"text":204,"isExternal":7,"url":75,"openForm":11},"link","Get started for free",{"_modelApiKey":203,"text":206,"isExternal":11,"openForm":7,"form":207},"Contact us",{"_modelApiKey":55,"slug":138,"name":139},{"showNotification":7,"link":209,"linkText":210,"text":215},{"_modelApiKey":203,"text":210,"isExternal":11,"link":211,"openForm":11},"Read article",{"_modelApiKey":212,"slug":213,"title":214},"blog_post","payment-api-redesigned","Introducing our new Payments API. For humans and agents.","\u003Cp>Introducing our new Payments API. For humans and agents.\u003C\u002Fp>\n",{"ctaText":217},"Subscribe",[219,225,229,236,240,246,249,253,261,262,267,272,274],{"_modelApiKey":55,"slug":220,"pardotFormEmbedCode":221,"formEmbedMinHeight":222,"successTitle":223,"successCopy":224},"agentic-commerce","https:\u002F\u002Fcommercelayer.fillout.com\u002Ft\u002F5w4Khwgxr6us?whitepaper=agentic",520,"Thank you for your request!","We’ll be in touch soon to arrange a date and time for your personalized demo.",{"_modelApiKey":55,"slug":226,"pardotFormEmbedCode":227,"formEmbedMinHeight":228,"successTitle":223,"successCopy":224},"shopify","https:\u002F\u002Fform.fillout.com\u002Ft\u002FgVnLSmKZwRus",850,{"_modelApiKey":55,"slug":130,"pardotFormEmbedCode":230,"formEmbedMinHeight":231,"displayTitle":232,"copy":233,"successTitle":234,"successCopy":235},"https:\u002F\u002Fform.fillout.com\u002Ft\u002FmVDF8aAiofus",500,"We give back.","\u003Cp>Part of Commerce Layer&#39;s company ethos is to empathize and support one another: co-workers, customers, and community. We want to do our part to help nonprofit organizations and small businesses who may feel adversely affected by the current global economic climate, and as a result, need in-kind support to reach their customers.\u003C\u002Fp>\n\n\u003Cp>If this general description matches your organization’s needs, please tell us your story by completing the following form so we can consider helping your cause.\u003C\u002Fp>\n","Thank you!","We will contact you soon to learn more about your story.",{"_modelApiKey":55,"slug":237,"pardotFormEmbedCode":227,"formEmbedMinHeight":228,"displayTitle":238,"copy":239},"book-an-onboarding-session","Book an onboarding session","\u003Cp>Schedule some time and our devs will help you set up a Commerce Layer + Sanity store.\u003C\u002Fp>\n",{"_modelApiKey":55,"slug":241,"pardotFormEmbedCode":242,"formEmbedMinHeight":243,"displayTitle":244,"successTitle":234,"successCopy":245},"download-our-whitepaper","https:\u002F\u002Fform.fillout.com\u002Ft\u002F5YPWmy8oT7us?whitepaper=ComposableCommerce",450,"Download our whitepaper.","Check your inbox. You should receive a download link soon.",{"_modelApiKey":55,"slug":247,"pardotFormEmbedCode":248,"formEmbedMinHeight":243,"displayTitle":244,"successTitle":234,"successCopy":245},"download-the-content-and-commerce-whitepaper","https:\u002F\u002Fform.fillout.com\u002Ft\u002F5YPWmy8oT7us?whitepaper=ContentAndCommerce",{"_modelApiKey":55,"slug":250,"pardotFormEmbedCode":251,"formEmbedMinHeight":243,"displayTitle":244,"copy":252,"successTitle":234,"successCopy":245},"whitepaper","https:\u002F\u002Fform.fillout.com\u002Ft\u002F5YPWmy8oT7us?whitepaper=Jamstack","\u003Cp>Commerce Layer is the perfect platform for building commerce on the Jamstack. Convert any design into pixel perfect HTML pages. Connect a best-of-breed headless CMS. Go serverless and forget the hassle of managing complex infrastructures.\u003C\u002Fp>\n",{"_modelApiKey":55,"slug":254,"pardotFormEmbedCode":255,"formEmbedMinHeight":256,"displayTitle":257,"copy":258,"successTitle":259,"successCopy":260},"contact-links","https:\u002F\u002Fform.fillout.com\u002Ft\u002FeWPyhHGHT7us",750,"Contact us.","\u003Cp>Tell us about your project. Our team will reach out to you for a personalized offer.\u003C\u002Fp>\n","Thanks for your message!","We’ll be in touch soon to discuss your project details.",{"_modelApiKey":55,"slug":138,"pardotFormEmbedCode":255,"formEmbedMinHeight":256,"displayTitle":257,"copy":258,"successTitle":259,"successCopy":260},{"_modelApiKey":55,"slug":263,"pardotFormEmbedCode":227,"formEmbedMinHeight":228,"displayTitle":264,"successTitle":265,"successCopy":266},"demo-embed","Want to see it in action? Request a demo.","Thanks for your request!","We’ll be in touch soon to arrange a date and time for your free live demo.",{"_modelApiKey":55,"slug":53,"pardotFormEmbedCode":268,"formEmbedMinHeight":228,"displayTitle":269,"copy":270,"successTitle":234,"successCopy":271},"https:\u002F\u002Fform.fillout.com\u002Ft\u002F9MTkDWMUSqus","Become our partner.","\u003Cp>Join us and get our guidance in helping your clients succeed. Our partners are our ambassadors. We are committed to your success as much as you are.\u003C\u002Fp>\n","We will contact you soon to discuss the details of our partnership.",{"_modelApiKey":55,"slug":273,"pardotFormEmbedCode":268,"formEmbedMinHeight":228,"displayTitle":269,"copy":270,"successTitle":234,"successCopy":271},"partners-embed",{"_modelApiKey":55,"slug":143,"pardotFormEmbedCode":227,"formEmbedMinHeight":228,"displayTitle":275,"copy":276,"successTitle":265,"successCopy":266},"Get a free live demo.","\u003Cp>Get a personalized demo and learn more about what Commerce Layer can do for your company.\u003C\u002Fp>\n",{"_modelApiKey":212,"link":278,"subtitle":283,"date":283,"author":284,"additionalAuthors":294,"icon":295,"abstract":296,"tag":297,"displayTitle":279,"cardRatio":300,"featured":11,"seoMetaTags":301,"layout":365,"blogPostCarousel":536,"_seoMetaTags":597,"authors":631},{"text":279,"isExternal":11,"url":280,"link":281},"How to send templated emails with Commerce Layer and SendGrid.","",{"_modelApiKey":212,"slug":282},"how-to-send-templated-emails-with-commerce-layer-and-sendgrid","October 13, 2022",{"name":285,"picture":286},"Bolaji Ayodeji",{"url":287,"alt":288,"title":288,"width":289,"height":289,"format":290,"focalPoint":291,"customData":293},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1643036479-bolaji.jpg","Bolaji Ayodeji — Developer Advocate at Commerce Layer",1280,"jpg",{"x":292,"y":292},0.5,{},[],"paper-plane-tilt","Learn how to create a styled dynamic email template, write a lambda function in Zapier to intercept the payload data from Commerce Layer, and apply the template before sending the email through SendGrid API.",{"color":298,"name":299},"gray","Tutorials","portrait",[302,306,310,313,317,320,323,327,331,335,338,342,346,350,354,357,361],{"attributes":303,"tag":304,"content":305},null,"title","How to Send Templated Order Emails with Commerce Layer",{"attributes":307,"tag":309,"content":303},{"property":308,"content":305},"og:title","meta",{"attributes":311,"tag":309,"content":303},{"name":312,"content":305},"twitter:title",{"attributes":314,"tag":309,"content":303},{"name":315,"content":316},"description","In this article, you will learn how to create a styled dynamic template for sending order confirmation emails using Commerce Layer, Zapier, and SendGrid.",{"attributes":318,"tag":309,"content":303},{"property":319,"content":316},"og:description",{"attributes":321,"tag":309,"content":303},{"name":322,"content":316},"twitter:description",{"attributes":324,"tag":309,"content":303},{"property":325,"content":326},"og:image","https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665657028-how-to-send-templated-emails-with-commerce-layer-and-sendgrid-1200-x-630.jpg?auto=format&fit=max&w=1200",{"attributes":328,"tag":309,"content":303},{"property":329,"content":330},"og:image:width","1200",{"attributes":332,"tag":309,"content":303},{"property":333,"content":334},"og:image:height","630",{"attributes":336,"tag":309,"content":303},{"name":337,"content":326},"twitter:image",{"attributes":339,"tag":309,"content":303},{"property":340,"content":341},"og:locale","en",{"attributes":343,"tag":309,"content":303},{"property":344,"content":345},"og:type","article",{"attributes":347,"tag":309,"content":303},{"property":348,"content":349},"og:site_name","Commerce Layer",{"attributes":351,"tag":309,"content":303},{"property":352,"content":353},"article:modified_time","2025-10-08T16:26:31Z",{"attributes":355,"tag":309,"content":303},{"property":356,"content":280},"article:publisher",{"attributes":358,"tag":309,"content":303},{"name":359,"content":360},"twitter:card","summary_large_image",{"attributes":362,"tag":309,"content":303},{"name":363,"content":364},"twitter:site","@commercelayer",[366,372,384,387,395,398,406,414,417,422,425,428,431,434,437,445,448,455,458,466,469,477,480,488,491,494,497,505,513,516,523,526,528,531],{"_modelApiKey":367,"copy":368,"listStyle":369,"darkTheme":11,"buttons":370,"color":371,"indent":7},"wysiwyg","\u003Cp>In \u003Ca href=\"https:\u002F\u002Fcommercelayer.io\u002Fblog\u002Fhow-to-send-emails-with-commerce-layer-webhooks-zapier-and-sendgrid\" target=\"_blank\" rel=\"noopener noreferrer\">the previous article of our Webhooks series\u003C\u002Fa>, we discussed how you can use our webhooks technology to send order confirmation emails to customers when they make a new purchase using Zapier and SendGrid. But as we observed, the email we sent wasn’t styled nicely like the emails you receive from your favorite brands. In this article, we will further discuss how to create a styled dynamic template in SendGrid, write a lambda function inside our existing Zapier actions to intercept the payload data from Commerce Layer, and apply the template before sending the email through SendGrid API. As a bonus, we will also show you how to do this with a custom Nodejs server (or any language you choose). Sounds fun, right? Let’s get right into it, then.\u003C\u002Fp>\n","directional",[],"red",{"_modelApiKey":373,"border":7,"caption":374,"image":375,"size":383,"darkTheme":11,"rounded":7,"color":371},"image_block","Sneak Peek 😉",{"url":376,"alt":377,"title":377,"width":378,"height":379,"format":380,"focalPoint":381,"customData":382},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665659841-order-confirmation-email-demo.png","Order Confirmation Email Demo",1508,2642,"png",{"x":292,"y":292},{},"standard",{"_modelApiKey":367,"copy":385,"listStyle":369,"darkTheme":11,"buttons":386,"color":371,"indent":11},"\u003Chr>\n\n\u003Ch3>Prerequisites\u003C\u002Fh3>\n\n\u003Cul>\n\u003Cli>You have read the \u003Ca href=\"https:\u002F\u002Fcommercelayer.io\u002Fblog\u002Fa-comprehensive-guide-to-commerce-layer-webhooks\" target=\"_blank\" rel=\"noopener noreferrer\">first\u003C\u002Fa> and \u003Ca href=\"https:\u002F\u002Fcommercelayer.io\u002Fblog\u002Fhow-to-send-emails-with-commerce-layer-webhooks-zapier-and-sendgrid\" target=\"_blank\" rel=\"noopener noreferrer\">second\u003C\u002Fa> parts of the webhook series.\u003C\u002Fli>\n\u003Cli>A general understanding of how APIs work.\u003C\u002Fli>\n\u003Cli>Basic HTML, CSS, and JavaScript knowledge.\u003C\u002Fli>\n\u003Cli>You should have a \u003Ca href=\"https:\u002F\u002Fdashboard.commercelayer.io\u002Fsign_up\" target=\"_blank\" rel=\"noopener noreferrer\">Commerce Layer account\u003C\u002Fa>, have set up your organization, and have created the required commerce data resources for your market. You can follow the \u003Ca href=\"https:\u002F\u002Fdocs.commercelayer.io\u002Fdevelopers\u002Fwelcome\u002Fonboarding-tutorial\" target=\"_blank\" rel=\"noopener noreferrer\">onboarding tutorial\u003C\u002Fa> or \u003Ca href=\"https:\u002F\u002Fdocs.commercelayer.io\u002Fdevelopers\u002Fwelcome\u002Fmanual-configuration\" target=\"_blank\" rel=\"noopener noreferrer\">manual configuration guide\u003C\u002Fa> to achieve this.\u003C\u002Fli>\n\u003Cli>Create an integration application and save your credentials (Client ID, Client secret, and Base endpoint) by following \u003Ca href=\"https:\u002F\u002Fdocs.commercelayer.io\u002Fdevelopers\u002Fwelcome\u002Fmanual-configuration#create-an-application\" target=\"_blank\" rel=\"noopener noreferrer\">this guide\u003C\u002Fa> in our documentation.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Chr>\n\n\u003Ch3>Getting started with SendGrid\u003C\u002Fh3>\n\n\u003Cp>SendGrid is a service that provides you with an Email API and some other communication APIs you can use to send emails to certain recipients. If you’re new to using SendGrid, follow the steps below to create a SendGrid account:\u003C\u002Fp>\n\n\u003Col>\n\u003Cli>First, create a \u003Ca href=\"https:\u002F\u002Fapp.sendgrid.com\" target=\"_blank\" rel=\"noopener noreferrer\">SendGrid account\u003C\u002Fa> if you don&#39;t have one already.\u003C\u002Fli>\n\u003Cli>Next, verify your account and set up 2FA.\u003C\u002Fli>\n\u003Cli>Finally, create and verify a Single Sender identity account (PS: this is for testing purposes; for production use, it&#39;s recommended to use the \u003Ca href=\"https:\u002F\u002Fdocs.sendgrid.com\u002Fui\u002Faccount-and-settings\u002Fhow-to-set-up-domain-authentication\" target=\"_blank\" rel=\"noopener noreferrer\">Domain Authentication Identity\u003C\u002Fa>.\u003C\u002Fli>\n\u003Cli>That&#39;s all :)\u003C\u002Fli>\n\u003C\u002Fol>\n\n\u003Ch3>Creating a dynamic Sendgrid template\u003C\u002Fh3>\n\n\u003Cp>Before we proceed to set up our Zapier integration for sending emails, we need first to create a styled template we will use to send the emails. We will then use this template and populate it with dynamic data coming in from Commerce Layer when the Zap is triggered.\u003C\u002Fp>\n",[],{"_modelApiKey":373,"border":7,"caption":280,"image":388,"size":383,"darkTheme":11,"rounded":7,"color":371},{"url":389,"alt":390,"title":390,"width":391,"height":392,"format":380,"focalPoint":393,"customData":394},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665657660-sendgrid-dynamic-templates.png","SendGrid Dynamic Templates",2070,1288,{"x":292,"y":292},{},{"_modelApiKey":367,"copy":396,"listStyle":369,"darkTheme":11,"buttons":397,"color":371,"indent":11},"\u003Cp>Kindly follow the steps below to create and design a dynamic template:\u003C\u002Fp>\n\n\u003Col>\n\u003Cli>Visit the \u003Ca href=\"https:\u002F\u002Fsendgrid.com\u002Fdynamic_templates\" target=\"_blank\" rel=\"noopener noreferrer\">Dynamic Transactional Templates\u003C\u002Fa> page and click the ”\u003Cstrong>Create a Dynamic Template”\u003C\u002Fstrong> button.\u003C\u002Fli>\n\u003Cli>Enter a unique name for the template and then click \u003Cstrong>Save\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003Cli>Click on the created template and click the “\u003Cstrong>Add Version”\u003C\u002Fstrong> button.\u003C\u002Fli>\n\u003Cli>Pick a design from one of SendGrid’s official templates or select a blank template to design from scratch.\u003C\u002Fli>\n\u003Cli>Select the Design or Code editor and click Continue (you can also import an HTML email during editing).\u003C\u002Fli>\n\u003Cli>Now you can begin designing your template.\u003C\u002Fli>\n\u003C\u002Fol>\n\n\u003Cp>\u003Cbr \u002F>\u003C\u002Fp>\n\n\u003Cp>SendGrid allows you to add dynamic data using \u003Ca href=\"https:\u002F\u002Fhandlebarsjs.com\" target=\"_blank\" rel=\"noopener noreferrer\">Handlebars\u003C\u002Fa> in the template and will render the actual data via the API. When we send order confirmation emails to customers, we will be able to personalize the messages in the template by inserting dynamic data. For example, suppose you have a customer&#39;s name stored in a JSON property called \u003Ccode>&quot;customerName&quot;\u003C\u002Fcode>. In that case, you can insert the property&#39;s value into a template by adding \u003Ccode>{{customerName}}\u003C\u002Fcode> wherever you want the customer&#39;s name to appear. If the data includes characters like \u003Cstrong>&#39;, &quot; or &amp;\u003C\u002Fstrong>, you can use the “triple-stash” like so \u003Ccode>{{{shippingAddress}}}\u003C\u002Fcode>. The same goes for other properties like customer email, order summary details, shipment tracking URLs, etc.\u003C\u002Fp>\n\n\u003Cp>This might be the most challenging part of this tutorial, as you will need some design and basic HTML\u002FCSS knowledge to design the perfect email template. However, we believe you already have excellent designers if you&#39;re a brand. You can have them design something for all emails you want to send to your customers. Your frontend engineers can then use SendGrid to implement the designs using the drag-and-drop editor, code editor, or HTML import. All you need to do is add substitution tags anywhere you want to add dynamic data, and you can \u003Ca href=\"https:\u002F\u002Fdocs.sendgrid.com\u002Fui\u002Fsending-email\u002Feditor#test-data\" target=\"_blank\" rel=\"noopener noreferrer\">preview them using test data\u003C\u002Fa> right inside SendGrid, as seen in the screenshots below:\u003C\u002Fp>\n",[],{"_modelApiKey":373,"border":7,"caption":280,"image":399,"size":383,"darkTheme":11,"rounded":7,"color":371},{"url":400,"alt":401,"title":401,"width":402,"height":403,"format":380,"focalPoint":404,"customData":405},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665658354-sendgrid-test-data-preview.png","Sendgrid Test Data Preview",1192,1392,{"x":292,"y":292},{},{"_modelApiKey":373,"border":7,"caption":280,"image":407,"size":383,"darkTheme":11,"rounded":7,"color":371},{"url":408,"alt":409,"title":409,"width":410,"height":411,"format":380,"focalPoint":412,"customData":413},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665658327-sendgrid-test-data.png","Sendgrid Test Data",2724,1774,{"x":292,"y":292},{},{"_modelApiKey":367,"copy":415,"listStyle":369,"darkTheme":11,"buttons":416,"color":371,"indent":11},"\u003Cp>The test data you will use with the Sendgrid template will be in JSON format like so:\u003C\u002Fp>\n",[],{"_modelApiKey":418,"code":419,"showLineNumbers":11,"highlightLines":280,"language":420,"size":421},"code_block","{\n  \"customerName\": \"Bolaji\",\n  \"orderTimeStamp\": \"2022-09-30T19:44:05.519Z\",\n  \"dateFormat\": \"MMMM DD, YYYY\",\n  \"shipmentNumber\": \"#21527675\u002FS\u002F001\",\n  \"orderNumber\": \"21527675\",\n  \"customerEmail\": \"bolaji@commercelayer.io\",\n  \"marketName\": \"USA\",\n  \"shippingAddress\": \"Bolaji Ayodeji, 333 Fremont Street, 94016 San Francisco CA (US) +14845219712\",\n  \"shippingMethod\": \"Express Delivery\",\n  \"paymentMethod\": \"Wire Transfer\",\n  \"lineItems\": \"...\",\n  \"totalAmount\": \"$500\",\n  \"shippingAmount\": \"$50\",\n  \"grandTotalAmount\": \"$550\"\n}","json","Wide",{"_modelApiKey":367,"copy":423,"listStyle":369,"darkTheme":11,"buttons":424,"color":371,"indent":11},"\u003Cp>We will then use the handlebars templating language to render any property we want. If your data includes an array of objects, you can iterate over the data for the line items in the array using the \u003Ccode>{{#each }}\u003C\u002Fcode> helper function to build a list of all the objects in the array. This will look something like this depending on how you want to style your template:\u003C\u002Fp>\n",[],{"_modelApiKey":418,"code":426,"showLineNumbers":11,"highlightLines":280,"language":427,"size":421},"{{#each lineItems}}\n\u003Cdiv style=\"font-size: 14px; font-family: 'courier new', courier, monospace\">\n  \u003Cimg\n    src=\"{{{this.skuImage}}}\"\n    alt=\"{{{this.skuName}}}\"\n    style=\"width: 10%; vertical-align: middle\"\n  \u002F>\n    {{{this.skuName}}} x{{{this.skuQuantity}}}\n  (\u003Cspan style=\"color: #666eff\">{{{this.skuFormattedAmount}}}\u003C\u002Fspan>)\n\u003C\u002Fdiv>\n{{\u002Feach}}","html",{"_modelApiKey":367,"copy":429,"listStyle":369,"darkTheme":11,"buttons":430,"color":371,"indent":11},"\u003Cp>But since the Commerce Layer Zapier app already returns an HTML property with all the line items summary, we can use that. Also, if you require more styling options, a good tip is to use the global styles or advanced options to add styles to the head of the email because most email clients work better with inline styles than with external styles. For example, we will put the styles for the SKU image and line items table in the HTML head like so:\u003C\u002Fp>\n",[],{"_modelApiKey":418,"code":432,"showLineNumbers":11,"highlightLines":280,"language":427,"size":433},"\u003Cstyle>\n  .line-item-image img {\n    margin-left: auto;\n    margin-right: auto;\n    display: block;\n  }\n  img {\n    width: 50px;\n    height: auto;\n  }\n  .line-items {\n    width: 100%;\n  }\n  .line-items td {\n    font-family: courier, monospace;\n    border: 1px solid #666eff;\n    padding: 5px;\n  }\n\u003C\u002Fstyle>","Standard",{"_modelApiKey":367,"copy":435,"listStyle":369,"darkTheme":11,"buttons":436,"color":371,"indent":11},"\u003Cp>And this is pretty much all you need to do at this stage. I believe you will design something even better than this and feed it with the right data. If you want, you can \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fcommercelayer\u002Fexamples\u002Ftree\u002Fmain\u002Fwebhooks\u002Fsendgrid-templated-emails\u002Ftemplates\u002Forder-confirmation.html\" target=\"_blank\" rel=\"noopener noreferrer\">download the code for the template\u003C\u002Fa> we designed, import it into your SendGrid account, and customize it as you desire.\u003C\u002Fp>\n",[],{"_modelApiKey":438,"title":439,"preTitle":440,"linkText":441,"darkTheme":11,"link":442},"link_block","Order confirmation email template","Code demo","View on GitHub",{"_modelApiKey":203,"text":443,"label":280,"subtitle":280,"icon":280,"isExternal":7,"url":444,"link":303,"anchor":280,"openForm":11,"form":303,"htmlClassNames":280},"Order Confirmation Email Template","https:\u002F\u002Fgithub.com\u002FBolajiAyodeji\u002Fcl-sendgrid-webhooks\u002Fblob\u002Fmain\u002Ftemplates\u002Forder-confirmation.html",{"_modelApiKey":367,"copy":446,"listStyle":369,"darkTheme":11,"buttons":447,"color":371,"indent":11},"\u003Cp>The next hurdle is to figure out how to receive live data from Commerce Layer, process them in Zapier, parse the data to look exactly like the test JSON data above, and write some code to send an email to the customer when a new order is placed using the dynamic data.\u003C\u002Fp>\n\n\u003Ch3>Getting started with Zapier\u003C\u002Fh3>\n\n\u003Cp>Now, let&#39;s show you how you can complete the integration with our webhooks, lambda functions, and SendGrid. To achieve this, we will utilize our private \u003Ca href=\"https:\u002F\u002Fzapier.com\u002Fdeveloper\u002Fpublic-invite\u002F1418\u002F4068b989bdb97d852a4e199b1d1adf46\" target=\"_blank\" rel=\"noopener noreferrer\">Zapier app\u003C\u002Fa> (which is still in beta at the time of writing this article) that will allow you to easily integrate 3000+ third-party services with Commerce Layer and build any automation workflow in minutes. So, kindly follow the steps below to get started:\u003C\u002Fp>\n\n\u003Col>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fzapier.com\u002Fsign-up\" target=\"_blank\" rel=\"noopener noreferrer\">Create a Zapier account\u003C\u002Fa> if you don&#39;t have one yet.\u003C\u002Fli>\n\u003Cli>Use \u003Ca href=\"https:\u002F\u002Fzapier.com\u002Fdeveloper\u002Fpublic-invite\u002F1418\u002F4068b989bdb97d852a4e199b1d1adf46\" target=\"_blank\" rel=\"noopener noreferrer\">this invite link\u003C\u002Fa> to install our private Commerce Layer Zapier app.\u003C\u002Fli>\n\u003Cli>Now, \u003Ca href=\"https:\u002F\u002Fzapier.com\u002Fhelp\u002Fcreate\u002Fbasics\u002Fcreate-zaps\" target=\"_blank\" rel=\"noopener noreferrer\">create a Zap\u003C\u002Fa>, an automated workflow that connects apps and services (like Commerce Layer and SendGrid in our case).\u003C\u002Fli>\n\u003C\u002Fol>\n",[],{"_modelApiKey":373,"border":7,"caption":280,"image":449,"size":383,"darkTheme":11,"rounded":7,"color":371},{"url":450,"alt":451,"title":451,"width":452,"height":403,"format":380,"focalPoint":453,"customData":454},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665660012-create-cl-zap.png","Create CL Zap",2176,{"x":292,"y":292},{},{"_modelApiKey":367,"copy":456,"listStyle":369,"darkTheme":11,"buttons":457,"color":371,"indent":11},"\u003Cp>Remember that when you turn your Zap on, it will run all the action steps every time the trigger event occurs. For example, the Commerce Layer webhook will be the trigger event, and the corresponding action is to run a lambda function and send some data to SendGrid, which in turn delivers that data to a customer via email.\u003C\u002Fp>\n\n\u003Cp>Just for a refresher or for those reading the third part of this series first, here’s how to create the Commerce Layer trigger event:\u003C\u002Fp>\n\n\u003Ch4>\u003Cstrong>Trigger event\u003C\u002Fstrong>\u003C\u002Fh4>\n\n\u003Col>\n\u003Cli>Search for “Commerce Layer” and select the app in the \u003Cem>App Event\u003C\u002Fem> field. Then select the latest version.\u003C\u002Fli>\n\u003Cli>Select a \u003Ccode>New Order Event\u003C\u002Fcode> trigger event.\u003C\u002Fli>\n\u003Cli>Click the button to sign in to your Commerce Layer account.\u003C\u002Fli>\n\u003Cli>Enter your organization hostname, Client ID, and Client Secret. You should have this already from the prerequisite step where you created an integration application earlier.\u003C\u002Fli>\n\u003Cli>Click “Yes continue,” and you should be authorized if you entered valid credentials.\u003C\u002Fli>\n\u003Cli>Click continue and select the \u003Ccode>place\u003C\u002Fcode> order event. You can choose another option based on the type of trigger you want. But since we want to send a notification when an order is placed successfully (which would have a placed status), then \u003Ccode>place\u003C\u002Fcode> event works for us. You can learn more about the anatomy of an order in our \u003Ca href=\"https:\u002F\u002Fcommercelayer.io\u002Fdocs\u002Fdata-model\u002Fanatomy-of-an-order\" target=\"_blank\" rel=\"noopener noreferrer\">data model\u003C\u002Fa> documentation.\u003C\u002Fli>\n\u003Cli>Click “Continue” and the test trigger button, and the app will find a recent order in your Commerce Layer organization to confirm that the correct account is connected and your trigger is set up correctly. This will return the last order we created.\u003C\u002Fli>\n\u003C\u002Fol>\n",[],{"_modelApiKey":373,"border":7,"caption":280,"image":459,"size":383,"darkTheme":11,"rounded":7,"color":371},{"url":460,"alt":461,"title":461,"width":462,"height":463,"format":380,"focalPoint":464,"customData":465},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665660156-trigger-cl-zap.png","Trigger CL Zap",2268,1430,{"x":292,"y":292},{},{"_modelApiKey":367,"copy":467,"listStyle":369,"darkTheme":11,"buttons":468,"color":371,"indent":11},"\u003Ch4>Action (code by Zapier)\u003C\u002Fh4>\n\n\u003Cp>Now the fun part 🙃. Let&#39;s send an email to the customer who placed the order with details of their order by creating another action. In this action, we will write code to send an email with SendGrid API, include a styled template, and add dynamic variables to the email content from the Commerce Layer webhook payload. Kindly follow the steps below to set the action up:\u003C\u002Fp>\n\n\u003Col>\n\u003Cli>Search for “Code by Zapier” and select the app in the \u003Cem>App Event\u003C\u002Fem> field.\u003C\u002Fli>\n\u003Cli>Select the \u003Ccode>Run JavaScript\u003C\u002Fcode> action event (you can also select \u003Ccode>Run Python\u003C\u002Fcode> if you prefer to write your code with Python programming language).\u003C\u002Fli>\n\u003Cli>Create a SendGrid API key with Full access “Main Send” permission by navigating to the SendGrid dashboard and opening Settings &gt; \u003Ca href=\"https:\u002F\u002Fapp.sendgrid.com\u002Fsettings\u002Fapi_keys\" target=\"_blank\" rel=\"noopener noreferrer\">API Keys\u003C\u002Fa>.\u003C\u002Fli>\n\u003Cli>Create some input data variables with the data from Commerce Layer, as seen in the screenshot below. These variables can be accessed as strings within code using \u003Ccode>inputData.keyName\u003C\u002Fcode> or \u003Ccode>inputData[&#39;keyName&#39;]\u003C\u002Fcode>.\u003C\u002Fli>\n\u003C\u002Fol>\n",[],{"_modelApiKey":373,"border":7,"caption":280,"image":470,"size":383,"darkTheme":11,"rounded":7,"color":371},{"url":471,"alt":472,"title":472,"width":473,"height":474,"format":380,"focalPoint":475,"customData":476},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665660441-zap-data-variables.png","Zap Data Variables",1418,1282,{"x":292,"y":292},{},{"_modelApiKey":367,"copy":478,"listStyle":369,"darkTheme":11,"buttons":479,"color":371,"indent":11},"\u003Cp>Now, in the code field, add the following JavaScript code, including your template ID:\u003C\u002Fp>\n",[],{"_modelApiKey":373,"border":11,"caption":280,"image":481,"size":383,"darkTheme":11,"rounded":7,"color":371},{"url":482,"alt":483,"title":483,"width":484,"height":485,"format":380,"focalPoint":486,"customData":487},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665660518-sendgrid-template-id.png","Sendgrid Template ID",1946,690,{"x":292,"y":292},{},{"_modelApiKey":418,"code":489,"showLineNumbers":11,"highlightLines":280,"language":490,"size":421},"const apiKey = \"YOUR_API_KEY\";\n\nawait fetch(\"https:\u002F\u002Fapi.sendgrid.com\u002Fv3\u002Fmail\u002Fsend\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${apiKey}`,\n    \"Content-Type\": \"application\u002Fjson\",\n  },\n  body: JSON.stringify({\n    from: {\n      email: \"bolaji@commercelayer.io\",\n      name: \"Cake Store Team\",\n    },\n    reply_to: {\n      email: \"bolaji@commercelayer.io\",\n      name: \"Cake Store Customer Support\",\n    },\n    personalizations: [\n      {\n        to: [\n          {\n            email: inputData.customerEmail,\n          },\n        ],\n        dynamic_template_data: {\n          customerName: inputData.customerName,\n          orderTimeStamp: inputData.orderTimeStamp,\n          dateFormat: \"MMMM DD, YYYY\",\n          shipmentNumber: `${\n            inputData.shipmentNumber.match(\u002F#\\d{8}\\\u002FS\\\u002F\\d{3}\u002Fg)[0]\n          }`,\n          orderNumber: inputData.orderNumber,\n          customerEmail: inputData.customerEmail,\n          marketName: inputData.marketName,\n          paymentMethod: inputData.paymentMethod,\n          shippingAddress: inputData.shippingAddress,\n          shippingMethod: inputData.shippingMethod,\n          lineItems: inputData.lineItems,\n          totalAmount: inputData.totalAmount,\n          shippingAmount: inputData.shippingAmount,\n          grandTotalAmount: inputData.grandTotalAmount,\n        },\n      },\n    ],\n    template_id: \"d-cd0b22632dcc427cb2b98e3bgg562e5a\",\n  }),\n})\n  .then((response) => {\n    output = response;\n    console.log(`Email sent to ${inputData.customerEmail}!`);\n    console.log(output);\n  })\n  .catch((error) => {\n    console.error(error);\n  });","javascript",{"_modelApiKey":492,"copy":493,"color":371},"highlight_block","You don't need to write a function for the script; the “Code by Zapier” action already wraps the code in an async function.",{"_modelApiKey":367,"copy":495,"listStyle":369,"darkTheme":11,"buttons":496,"color":371,"indent":11},"\u003Cp>And that&#39;s all! You can now test the action or publish the zap. As discussed earlier, turning the zap on will make the entire automation run when the trigger occurs. If you want more flexibility, consider using the AWS Lambda Zapier action (although it’s a premium service). You should also know that your test email might be delivered to the Spam folder. To avoid this, you need to \u003Ca href=\"https:\u002F\u002Fdocs.sendgrid.com\u002Fui\u002Faccount-and-settings\u002Fhow-to-set-up-domain-authentication\" target=\"_blank\" rel=\"noopener noreferrer\">authenticate your SendGrid sender identity\u003C\u002Fa>, as mentioned earlier.\u003C\u002Fp>\n",[],{"_modelApiKey":373,"border":7,"caption":280,"image":498,"size":383,"darkTheme":11,"rounded":7,"color":371},{"url":499,"alt":500,"title":500,"width":501,"height":502,"format":380,"focalPoint":503,"customData":504},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665661657-zap-action-result.png","Zap Action Result",1428,1174,{"x":292,"y":292},{},{"_modelApiKey":373,"border":7,"caption":280,"image":506,"size":383,"darkTheme":11,"rounded":7,"color":371},{"url":507,"alt":508,"title":508,"width":509,"height":510,"format":380,"focalPoint":511,"customData":512},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1665661860-order-email-full-demo.png","Order Email Full Demo",1724,3305,{"x":292,"y":292},{},{"_modelApiKey":367,"copy":514,"listStyle":369,"darkTheme":11,"buttons":515,"color":371,"indent":11},"\u003Cp>If you want to test this yourself, I have created an \u003Ca href=\"https:\u002F\u002Fcommercelayer.io\u002Fdocs\u002Fdata-model\u002Fsku-lists\" target=\"_blank\" rel=\"noopener noreferrer\">SKU List\u003C\u002Fa> and a \u003Ca href=\"https:\u002F\u002Fbit.ly\u002Fcl-cake-store-microstore\" target=\"_blank\" rel=\"noopener noreferrer\">sample MicroStore\u003C\u002Fa> specially for YOU. With this, you can purchase some items, checkout with your email\u002Fshipping details, and select Wire Transfer as the payment method (PS: this is a test order and not real :-)). This will place a test order with no charge, and you will receive a confirmation email (the Zap will continue pending until our Zapier test account exceeds the monthly free tasks limit, so let’s call this a special treat for early readers 😉).\u003C\u002Fp>\n",[],{"_modelApiKey":438,"title":517,"preTitle":518,"linkText":519,"darkTheme":11,"link":520},"Introducing Microstores.","Related Article","Read",{"isExternal":11,"link":521},{"_modelApiKey":212,"slug":522},"introducing-microstores",{"_modelApiKey":367,"copy":524,"listStyle":369,"darkTheme":11,"buttons":525,"color":371,"indent":11},"\u003Ch3>Conclusion\u003C\u002Fh3>\n\n\u003Cp>We hope you have learned more ways to utilize our webhooks feature! You can also consider other email API platforms like Postmark that provide a similar experience for sending dynamic templates. If you have followed this series so far, you would understand that you can do this entire integration without Zapier if you want more flexibility and deploy the service yourself. All you have to do is create a server, create an endpoint to serve as a callback for the webhook, receive the data from Commerce Layer, filter and format out the data you need for the email, and use one of SendGrid mail libraries (depending on your choice of programming language) to write a mail script (passing in the dynamic data inside an object). However, using serverless or Lambda functions when you deploy your custom server is wise due to scaling concerns. This would look something like the code below if written with JavaScript and Nodejs:\u003C\u002Fp>\n",[],{"_modelApiKey":418,"code":527,"showLineNumbers":11,"highlightLines":280,"language":490,"size":421},"require(\"dotenv\").config();\nconst express = require(\"express\");\nconst CryptoJS = require(\"crypto-js\");\nconst hmacSHA256 = require(\"crypto-js\u002Fhmac-sha256\");\n\nconst app = express();\nconst port = 9000;\n\n\u002F\u002F Fetch RAW incoming JSON requests and put in req.rawBody\napp.use(\n  express.json({\n    limit: \"5mb\",\n    verify: (req, res, buf) => {\n      req.rawBody = buf.toString();\n    },\n  })\n);\n\napp.post(\"\u002Fcallback\", (req, res) => {\n  \u002F\u002F Verify the payload coming from Commerce Layer\n  const signature = req.headers[\"x-commercelayer-signature\"];\n  const hash = hmacSHA256(req.rawBody, process.env.CL_SHARED_SECRET);\n  const encode = hash.toString(CryptoJS.enc.Base64);\n  if (req.method === \"POST\" && signature === encode) {\n    const payload = req.body;\n\n    \u002F\u002F Filter payload and fetch the required order summary\n    const lineItemsArray = payload.included.filter(\n      (x) => x.type === \"line_items\" && x.attributes.item_type === \"skus\"\n    );\n\n    const filteredLineItemsArray = lineItemsArray.map((item) => {\n      return {\n        image_url: item.attributes.image_url,\n        name: item.attributes.name,\n        quantity: item.attributes.quantity,\n        formatted_total_amount: item.attributes.formatted_total_amount,\n      };\n    });\n\n    const inputData = {\n      customerName: payload.included[2].attributes.first_name,\n      customerEmail: payload.data.attributes.customer_email,\n      orderNumber: payload.data.attributes.number.toString(),\n      orderTimeStamp: payload.data.attributes.placed_at,\n      marketName: payload.included[0].attributes.name,\n      paymentMethod: payload.included[4].attributes.name,\n      shippingAddress: payload.included[2].attributes.full_address,\n      shipmentNumber: payload.included.find((x) => x.type === \"shipments\")\n        .attributes.number,\n      shippingMethod: payload.included.find(\n        (x) => x.type === \"shipping_methods\"\n      ).attributes.name,\n      lineItemsHtml:\n        `\u003Ctable class=\"line-items\">` +\n        filteredLineItemsArray\n          .map(\n            (item) =>\n              `\u003Ctr class=\"line-item\">\u003Ctd class=\"line-item-image\">\u003Cimg src=\"${item.image_url}\" alt=\"${item.name}\" \u002F>\u003C\u002Ftd>\u003Ctd class=\"line-item-name\">${item.name}\u003C\u002Ftd>\u003Ctd class=\"line-item-qty\">${item.quantity}\u003C\u002Ftd>\u003Ctd class=\"line-item-amount\">${item.formatted_total_amount}\u003C\u002Ftd>\u003C\u002Ftr>`\n          )\n          .join(\"\") +\n        `\u003C\u002Ftable>`,\n      totalAmount: payload.data.attributes.formatted_subtotal_amount,\n      shippingAmount: payload.data.attributes.formatted_shipping_amount,\n      grandTotalAmount: payload.data.attributes.formatted_total_amount,\n    };\n\n    \u002F\u002F Send Email with SendGrid\n    const sgMail = require(\"@sendgrid\u002Fmail\");\n    sgMail.setApiKey(process.env.SENDGRID_API_KEY);\n\n    sgMail\n      .send({\n        to: inputData.customerEmail,\n        from: {\n          email: \"bolaji@commercelayer.io\",\n          name: \"Cake Store Team\",\n        },\n        reply_to: {\n          email: \"bolaji@commercelayer.io\",\n          name: \"No Reply\",\n        },\n        templateId: process.env.SENDGRID_TEMPLATE_ID,\n        dynamicTemplateData: {\n          customerName: inputData.customerName,\n          orderTimeStamp: inputData.orderTimeStamp,\n          dateFormat: \"MMMM DD, YYYY\",\n          shipmentNumber: inputData.shipmentNumber,\n          orderNumber: inputData.orderNumber,\n          customerEmail: inputData.customerEmail,\n          marketName: inputData.marketName,\n          paymentMethod: inputData.paymentMethod,\n          shippingAddress: inputData.shippingAddress,\n          shippingMethod: inputData.shippingMethod,\n          lineItems: inputData.lineItemsHtml,\n          totalAmount: inputData.totalAmount,\n          shippingAmount: inputData.shippingAmount,\n          grandTotalAmount: inputData.grandTotalAmount,\n        },\n      })\n      .then((response) => {\n        console.log(response);\n        res.status(200).json({\n          message: `Email sent to customer (${inputData.customerEmail})!`,\n          response: response,\n        });\n      })\n      .catch((error) => {\n        console.error(error);\n        res.status(500).json({\n          error: error,\n        });\n      });\n  } else {\n    res.status(401).json({\n      error: \"Unauthorized: Invalid signature\",\n    });\n  }\n});\n\napp.listen(port, () => {\n  console.log(`Listening at http:\u002F\u002Flocalhost:${port}`);\n});",{"_modelApiKey":367,"copy":529,"listStyle":369,"darkTheme":11,"buttons":530,"color":371,"indent":11},"\u003Cp>I’ll imagine you will have email servers like this for several transactional emails you will be sending to customers, like shipment confirmation, signup welcome, password reset, order cancellation, shipment updates, recommendations, promotion activation, customer group invite, order subscriptions, and lots more. In addition, you can explore \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fcommercelayer\u002Fexamples\u002Ftree\u002Fmain\u002Fwebhooks\u002Fsendgrid-templated-emails\" target=\"_blank\" rel=\"noopener noreferrer\">this GitHub repository\u003C\u002Fa> containing all the code used in this tutorial for further learning and code customization. Thank you for reading this far; cheers!\u003C\u002Fp>\n",[],{"_modelApiKey":438,"title":532,"preTitle":440,"linkText":441,"darkTheme":11,"link":533},"SendGrid webhooks",{"_modelApiKey":203,"text":534,"label":280,"subtitle":280,"icon":280,"isExternal":7,"url":535,"link":303,"anchor":280,"openForm":11,"form":303,"htmlClassNames":280},"SendGrid Webhooks Code Demo","https:\u002F\u002Fgithub.com\u002FBolajiAyodeji\u002Fcl-sendgrid-webhooks",{"displayTitle":537,"cta":303,"ctaText":280,"cards":538},"Your next read",[539,554,568,582],{"_modelApiKey":212,"link":540,"subtitle":544,"date":544,"author":545,"additionalAuthors":549,"icon":550,"abstract":551,"tag":552,"displayTitle":541,"cardRatio":300,"featured":553},{"text":541,"isExternal":11,"url":280,"link":542},"A comprehensive guide to Commerce Layer webhooks.",{"_modelApiKey":212,"slug":543},"a-comprehensive-guide-to-commerce-layer-webhooks","June 9, 2022",{"name":285,"picture":546},{"url":287,"alt":288,"title":288,"width":289,"height":289,"format":290,"focalPoint":547,"customData":548},{"x":292,"y":292},{},[],"webhooks-logo","We provides a list of specific events you can monitor and transmit real-time data from using webhooks. In this article, we will introduce our webhooks mechanism and guide you through a couple of simple demo examples so that you can see it in action.",{"color":298,"name":299},0,{"_modelApiKey":212,"link":555,"subtitle":559,"date":559,"author":560,"additionalAuthors":564,"icon":295,"abstract":565,"tag":566,"displayTitle":556,"cardRatio":11,"featured":567},{"text":556,"isExternal":11,"url":280,"link":557},"How to send emails with Commerce Layer webhooks, Zapier, and SendGrid.",{"_modelApiKey":212,"slug":558},"how-to-send-emails-with-commerce-layer-webhooks-zapier-and-sendgrid","August 4, 2022",{"name":285,"picture":561},{"url":287,"alt":288,"title":288,"width":289,"height":289,"format":290,"focalPoint":562,"customData":563},{"x":292,"y":292},{},[],"You can use our webhooks technology to send order confirmation emails to your customers when they make a new purchase. At the end of this tutorial, you will understand how to use Zapier and SendGrid to send plain order confirmation emails.",{"color":298,"name":299},1,{"_modelApiKey":212,"link":569,"subtitle":573,"date":573,"author":574,"additionalAuthors":578,"icon":579,"abstract":580,"tag":581,"displayTitle":570,"cardRatio":11,"featured":38},{"text":570,"isExternal":11,"url":280,"link":571},"Building an external payment gateway with the Twitter API.",{"_modelApiKey":212,"slug":572},"building-an-external-payment-gateway-with-twitter-api","August 17, 2022",{"name":285,"picture":575},{"url":287,"alt":288,"title":288,"width":289,"height":289,"format":290,"focalPoint":576,"customData":577},{"x":292,"y":292},{},[],"twitter-logo","We makes integrating with any local payment gateway like Twitter possible, allowing you to explore any option your customers demand. In this article, you will learn how to get started with our payment gateways, external payment gateways, and payment methods.",{"color":298,"name":299},{"_modelApiKey":212,"link":583,"subtitle":587,"date":587,"author":588,"additionalAuthors":592,"icon":593,"abstract":594,"tag":595,"displayTitle":584,"cardRatio":11,"featured":596},{"text":584,"isExternal":11,"url":280,"link":585},"Getting started with Commerce Layer JavaScript SDK.",{"_modelApiKey":212,"slug":586},"getting-started-with-commerce-layer-javascript-sdk","April 14, 2022",{"name":285,"picture":589},{"url":287,"alt":288,"title":288,"width":289,"height":289,"format":290,"focalPoint":590,"customData":591},{"x":292,"y":292},{},[],"code-block","Commerce Layer provides a JavaScript SDK that makes it quick and easy for developers to interact with our commerce APIs. In this article, we’ll look at some fundamental technical details about how it works.",{"color":298,"name":299},3,[598,599,601,603,605,607,609,611,613,615,617,619,621,623,625,627,629],{"attributes":303,"tag":304,"content":305},{"attributes":600,"tag":309,"content":303},{"property":308,"content":305},{"attributes":602,"tag":309,"content":303},{"name":312,"content":305},{"attributes":604,"tag":309,"content":303},{"name":315,"content":316},{"attributes":606,"tag":309,"content":303},{"property":319,"content":316},{"attributes":608,"tag":309,"content":303},{"name":322,"content":316},{"attributes":610,"tag":309,"content":303},{"property":325,"content":326},{"attributes":612,"tag":309,"content":303},{"property":329,"content":330},{"attributes":614,"tag":309,"content":303},{"property":333,"content":334},{"attributes":616,"tag":309,"content":303},{"name":337,"content":326},{"attributes":618,"tag":309,"content":303},{"property":340,"content":341},{"attributes":620,"tag":309,"content":303},{"property":344,"content":345},{"attributes":622,"tag":309,"content":303},{"property":348,"content":349},{"attributes":624,"tag":309,"content":303},{"property":352,"content":353},{"attributes":626,"tag":309,"content":303},{"property":356,"content":280},{"attributes":628,"tag":309,"content":303},{"name":359,"content":360},{"attributes":630,"tag":309,"content":303},{"name":363,"content":364},[632],{"name":285,"picture":633},{"url":287,"alt":288,"title":288,"width":289,"height":289,"format":290,"focalPoint":634,"customData":635},{"x":292,"y":292},{},1790330005503]