Pawsome Birthday Club
A personalized monthly Birthday Campaign for Pawsome Pet Co., built to demonstrate AMPscript-first email development using Data Extensions, dynamic content, personalized offers, pet-based recommendations, MJML and responsive HTML email.
Email Preview
Sample rendered email β Max / Dog / Gold-tier test record
|
|
|
|
|
|
Project Overview
Pawsome Pet Co. runs a monthly Birthday Club campaign for customers whose pets have birthdays during the current month. This campaign combines a personalized birthday message, customer-specific discount, loyalty-tier messaging and two pet-relevant gift recommendations. The campaign is designed as an AMPscript-heavy SFMC email rather than a static HTML creative.
Objective
Build a Monthly Birthday Club email that feels personal and brand-led while demonstrating practical AMPscript skills. The supplied Birthday Club DE acts as the send audience, while lookup Data Extensions provide reusable pet personality content and gift recommendations.
Campaign Flow
Birthday Club DE
β
Subscriber + Pet Attributes
β
AMPscript
βββ First Name fallback
βββ Pet Personality lookup
βββ Loyalty-tier subject line
βββ Gift recommendation lookup
βββ Discount calculation
βββ Pet-type banner selection
β
Personalized MJML / HTML Email
β
September Birthday Club Send
The provided send audience already contains customers with September pet birthdays, so no SQL audience-selection step is required for this campaign. AMPscript performs the runtime content assembly and personalization inside the email.
Data Model
Birthday Club
SubscriberKey
FirstName
EmailAddress
PetName
PetType
Breed
PetBirthday
DiscountCode
DiscountPercent
LoyaltyTier
Pet Personality
PetType
BirthdayHeadline
BirthdayPersonality
PetDescription
PetEmoji
Gift Ideas
GiftID
GiftName
PetType
Category
Price
Description
ShopURL
ImageURL
Birthday Club
β
βββ PetType βββββββββββ Pet Personality
β
βββ PetType βββββββββββ Gift Ideas
β
2 Recommendations
AMPscript
AMPscript is the primary orchestration layer. It reads the sendable subscriber attributes, retrieves reusable content from the lookup Data Extensions, builds the personalized subject line, calculates recommendation prices after the birthday discount and selects the appropriate hero image.
%%[
var @subscriberKey, @firstName, @emailAddress, @petName, @petType, @discountPercent, @loyaltyTier
SET @subscriberKey = AttributeValue("SubscriberKey")
SET @firstName = AttributeValue("FirstName")
SET @emailAddress = AttributeValue("EmailAddress")
SET @petName = AttributeValue("PetName")
SET @petType = AttributeValue("PetType")
SET @discountPercent = AttributeValue("DiscountPercent")
SET @loyaltyTier = AttributeValue("LoyaltyTier")
SET @date = SystemDateToLocalDate(Now(1))
SET @offerMonth = FormatDate(@date, 'MMMM')
SET @offerValidity = FormatDate(@date, 'Y')
/*Validate firstName*/
IF EMPTY(@firstName) THEN
SET @firstName = 'there'
ENDIF
/*Content(personality) based on pet type*/
SET @petPersonalityRows = LookupRows('Pet Personality', 'PetType', @petType)
IF rowCount(@petPersonalityRows) > 0 THEN
VAR @row, @birthdayHeadline, @birthdayPersonality, @petDescription
SET @row = Row(@petPersonalityRows, 1)
SET @birthdayHeadline = Field(@row, 'BirthdayHeadline')
SET @birthdayPersonality = Field(@row, 'BirthdayPersonality')
SET @petDescription = Field(@row, 'PetDescription')
SET @petEmoji = Field(@row, 'petEmoji')
ENDIF
/*Dynamic subjectline based on loyalty tier*/
IF @loyaltyTier == 'Platinum' THEN
SET @subjectline = Concat('A VIP birthday treat, just for ', @petName, ' ', @petEmoji)
ELSEIF @loyaltyTier == 'Gold' THEN
SET @subjectline = Concat('Celebrate ', @petName,' with a birthday treat from us ', @petEmoji)
ELSEIF @loyaltyTier == 'Silver' THEN
SET @subjectline = Concat("Extra cuddles. Extra treats. It's ", @petName, "'s birthday! ", @petEmoji)
ELSE
SET @subjectline = Concat("It's paw-ty time ", @petName, "! Your birthday treat is waiting ", @petEmoji)
ENDIF
/*Get 2 gift recommendations*/
SET @giftIdeasRows = LookupOrderedRows('Gift Ideas', 2, 'Price DESC', 'PetType', @petType)
SET @giftIdeasCount = rowCount(@giftIdeasRows)
SET @giftRow1 = Row(@giftIdeasRows, 1)
SET @giftName1 = Field(@giftRow1, 'GiftName')
SET @giftPrice1 = Field(@giftRow1, 'Price')
SET @formatGiftPrice1 = FormatNumber(@giftPrice1, "C")
SET @finalPrice1 = FormatNumber(Subtract(@giftPrice1, Multiply(@giftPrice1, Divide(@discountPercent, 100))), "C")
SET @giftDescription1 = Field(@giftRow1, 'Description')
SET @shopURL1 = Field(@giftRow1, 'ShopURL')
SET @imageURL1 = Field(@giftRow1, 'ImageURL')
IF @giftIdeasCount == 2 THEN
SET @giftRow2 = Row(@giftIdeasRows, 2)
SET @giftName2 = Field(@giftRow2, 'GiftName')
SET @giftPrice2 = Field(@giftRow2, 'Price')
SET @formatGiftPrice2 = FormatNumber(@giftPrice2, "C")
SET @finalPrice2 = FormatNumber(Subtract(@giftPrice2, Multiply(@giftPrice2, Divide(@discountPercent, 100))), "C")
SET @giftDescription2 = Field(@giftRow2, 'Description')
SET @shopURL2 = Field(@giftRow2, 'ShopURL')
SET @imageURL2 = Field(@giftRow2, 'ImageURL')
ELSE
SET @giftIdeasRowsAll = LookupOrderedRows('Gift Ideas', 1, 'Price DESC', 'PetType', 'All')
SET @giftRow2 = Row(@giftIdeasRowsAll, 1)
SET @giftName2 = Field(@giftRow2, 'GiftName')
SET @giftPrice2 = Field(@giftRow2, 'Price')
SET @formatGiftPrice2 = FormatNumber(@giftPrice2, "C")
SET @finalPrice2 = FormatNumber(Subtract(@giftPrice2, Multiply(@giftPrice2, Divide(@discountPercent, 100))), "C")
SET @giftDescription2 = Field(@giftRow2, 'Description')
SET @shopURL2 = Field(@giftRow2, 'ShopURL')
SET @imageURL2 = Field(@giftRow2, 'ImageURL')
ENDIF
/*Dynamic banner based on pet type*/
IF @petType == 'Dog' THEN
SET @banner = 'https://as1.ftcdn.net/v2/jpg/03/22/78/92/1000_F_322789275_pRYGzHcwPOBFiSD34xXIMILVMGxfqJBV.jpg'
ELSE
SET @banner = 'https://images.ampscriptacademy.com.au/uploads/hero-gemini-removebg-preview.png'
ENDIF
]%%
Dynamic Content & Personalization
MJML
MJML is used for the responsive email structure. AMPscript variables are embedded directly into the MJML so the compiled HTML retains the dynamic SFMC logic.
<mjml> <mj-head> <mj-attributes> <mj-all font-size="16px" font-family="Helvetica, Arial, sans-serif" color="#333333" line-height="22px" /> </mj-attributes> </mj-head> <mj-body background-color="#d6dde5"> <mj-section background-color="#fa8739"> <mj-column> <mj-text align="center" font-weight="800" font-family="Comic Sans Ms">Pawsome Pet Co.</mj-text> </mj-column> </mj-section> <mj-section padding="0px"> <mj-column padding="0px"> <mj-image padding="0px" src="%%=v(@banner)=%%"></mj-image> </mj-column> </mj-section> <mj-section background-color="#fff"> <mj-column> <mj-text align="center" font-size="20px" line-height="26px" font-family="Comic Sans Ms"> <p>%%=v(@birthdayHeadline)=%%</p> <p>%%=v(@offerMonth)=%% is %%=v(@petName)=%%'s Birthday Month! %%=v(@petEmoji)=%%</p> <p>%%=v(@birthdayPersonality)=%%</p> </mj-text> <mj-divider border-width="1px" border-style="dashed" border-color="lightgrey" /> <mj-text font-family="Helvetica" font-size="14px"> <p>Hey %%=v(@firstName)=%%,</p> <p>Someone special is celebrating another trip around the sun!</p> <p>To make the celebration even more pawsome, enjoy <strong>%%=v(@discountPercent)=%% OFF</strong> on your next purchase.</p> <p>Use your personal birthday code: <span style="font-family:Comic Sans Ms; background:#fa8739">%%=v(@discountCode)=%%</span></p> <p style="font-family:Comic Sans Ms">Valid throughout %%=v(@offerValidity)=%%.</p> </mj-text> <mj-button background-color="#fa8739" color="#fff" border-radius="20px">Claim %%=v(@petName)=%%'s Birthday</mj-button> </mj-column> </mj-section> <mj-section background-color="#fa8739" padding-bottom="0px" padding-top="0"> <mj-column background-color="#fa8739"> <mj-image src="%%=v(@imageURL1)=%%" alt="giftImage1" width="301px" padding-left="0px" padding-right="0px" padding-bottom="0px" padding-top="0"></mj-image> </mj-column> <mj-column width="50%"> <mj-text align="left" color="#fff" font-size="13px" padding-left="25px" padding-right="25px" padding-bottom="0px" padding-top="0"> <p style="font-size: 19px;">%%=v(@giftName1)=%%</p> <p style="font-size: 36px;"><s style="font-size: 26px; color:#d6dde5">%%=v(@formatGiftPrice1)=%%</s> %%=v(@finalPrice1)=%%</p> <p>%%=v(@giftDescription1)=%%</p> </mj-text> <mj-button background-color="#fff" color="#fa8739" padding="15px 30px" border-radius="3px" href="%%=v(@shopURL1)=%%" padding-bottom="10px" padding-top="0">BUY NOW</mj-button> </mj-column> </mj-section> <mj-section background-color="#2f323b" padding-bottom="0px" padding-top="0"> <mj-column> <mj-text align="left" color="#fff" font-size="13px" padding-left="25px" padding-right="25px" padding-bottom="0px" padding-top="0"> <p style="font-size: 19px;">%%=v(@giftName2)=%%</p> <p style="font-size: 36px;"><s style="font-size: 26px; color:#d6dde5">%%=v(@formatGiftPrice2)=%%</s> %%=v(@finalPrice2)=%%</p> <p>%%=v(@giftDescription2)=%%</p> </mj-text> <mj-button background-color="#fa8739" color="#fff" padding="15px 30px" border-radius="3px" href="%%=v(@shopURL2)=%%" padding-bottom="10px" padding-top="0">BUY NOW</mj-button> </mj-column> <mj-column> <mj-image src="%%=v(@imageURL2)=%%" alt="giftImage2" align="center" border="none" width="302px" padding-left="0px" padding-right="0px" padding-bottom="0px" padding-top="0"></mj-image> </mj-column> </mj-section> <mj-section background-color="#fff" padding-bottom="1px" padding-top="0px"></mj-section> <mj-section padding="0px" background-color="#fa8739"> <mj-column padding="0px"> <mj-text align="center" line-height="20px"> <p>Here's to another year of happy tails, tiny paws, big personalities and plenty of treats. πΎ</p> <p>Happy Birthday, %%=v(@petName)=%%!</p> <p>Β© The Pawsome Pet Co. Team</p> <p style="font-size:12px"><a href="#" style="color: inherit;">Manage Preferences</a> | <a href="#" style="color: inherit;">Unsubscribe</a></p> </mj-text> </mj-column> </mj-section> <mj-section padding="0px" background-color="#fa8739"> <mj-column padding="0px 0px 20px 0px"> <mj-social> <mj-social-element name="facebook" href="#"></mj-social-element> <mj-social-element name="twitter" href="#"></mj-social-element> <mj-social-element name="instagram" href="#"></mj-social-element> </mj-social> </mj-column> </mj-section> </mj-body> </mjml>
Implementation Notes
The campaign intentionally keeps the creative structure simple: one birthday hero/message area,
one personalized offer and two recommendation sections with alternating layouts. This keeps the
email visually engaging while leaving AMPscript as the primary technical focus.
The Gift Ideas lookup uses two pet-specific records when available. If only one exists, the first
recommendation remains pet-specific and the second is populated from a generic βAllβ record.
The email therefore maintains its two-product layout without hard-coding product content into the HTML.
Key Features
Source Code
The project includes the AMPscript, MJML source and rendered HTML preview used for the portfolio demonstration.