-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
React/Core: added Whatsapp Catalog component to Botonic (#2954)
<!-- _Set as [Draft PR](https://github.blog/2019-02-14-introducing-draft-pull-requests/) if it's not ready to be merged_. [PR best practices Reference](https://blog.codeminer42.com/on-writing-a-great-pull-request-37c60ce6f31d/) --> ## Description Added [Whatsapp Catalog](https://developers.facebook.com/docs/whatsapp/cloud-api/guides/sell-products-and-services/share-products/) component to Botonic <!-- - Must be clear and concise (2-3 lines). - Don't make reviewers think. The description should explain what has been implemented or what it's used for. If a pull request is not descriptive, people will be lazy or not willing to spend much time on it. - Be explicit with the names (don't abbreviate and don't use acronyms that can lead to misleading understanding). - If you consider it appropriate, include the steps to try the new features. --> ## Context Component used to send the Whatsapp Catalog linked to the bot's phone number. <!-- - What problem is trying to solve this pull request? - What are the reasons or business goals of this implementation? - Can I provide visual resources or links to understand better the situation? --> ## Approach taken / Explain the design <!-- - Explain what the code does. - If it's a complex solution, try to provide a sketch. --> ## To document / Usage example ``` render() { return ( <WhatsappCatalog body='Catalog sent from the bot' thumbnailProductId='p6ng7fghmh' footer="Catalog footer!!!" /> ) } ``` ![Captura de pantalla de 2025-01-14 09-40-59](https://github.com/user-attachments/assets/be565dcb-5eee-41fc-896a-c0cf11b55024) <!-- - How this is used? - If possible, provide a snippet of code with a usage example. --> ## Testing The pull request... - has unit tests
- Loading branch information
Showing
20 changed files
with
769 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
packages/botonic-react/src/components/whatsapp-catalog.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { INPUT } from '@botonic/core' | ||
import React from 'react' | ||
|
||
import { renderComponent } from '../util/react' | ||
import { Message } from './message' | ||
|
||
export interface WhatsappCatalogProps { | ||
body: string | ||
footer?: string | ||
thumbnailProductId?: string | ||
} | ||
|
||
const serialize = (message: string) => { | ||
return { text: message } | ||
} | ||
|
||
export const WhatsappCatalog = (props: WhatsappCatalogProps) => { | ||
const renderBrowser = () => { | ||
// Return a dummy message for browser | ||
const message = `WhatsApp Catalog would be sent to the user.` | ||
return ( | ||
<Message json={serialize(message)} {...props} type={INPUT.TEXT}> | ||
{message} | ||
</Message> | ||
) | ||
} | ||
|
||
const renderNode = () => { | ||
return ( | ||
// @ts-ignore Property 'message' does not exist on type 'JSX.IntrinsicElements'. | ||
<message | ||
{...props} | ||
body={props.body} | ||
footer={props.footer} | ||
thumbnailProductId={props.thumbnailProductId} | ||
type={INPUT.WHATSAPP_CATALOG} | ||
/> | ||
) | ||
} | ||
|
||
return renderComponent({ renderBrowser, renderNode }) | ||
} |
104 changes: 104 additions & 0 deletions
104
packages/botonic-react/src/components/whatsapp-media-carousel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { INPUT } from '@botonic/core' | ||
import React from 'react' | ||
|
||
import { toSnakeCaseKeys } from '../util/functional' | ||
import { renderComponent } from '../util/react' | ||
import { Message } from './message' | ||
|
||
type Parameters = TextParameter | CurrencyParameter | DateTimeParameter | ||
|
||
interface TextParameter { | ||
type: 'text' | ||
text: string | ||
} | ||
|
||
interface CurrencyParameter { | ||
type: 'currency' | ||
currency: { | ||
fallbackValue: string | ||
code: string | ||
amount1000: number | ||
} | ||
} | ||
|
||
interface DateTimeParameter { | ||
type: 'date_time' | ||
dateTime: { fallbackValue: string } | ||
} | ||
|
||
type CardButton = QuickReplyButton | UrlButton | ||
|
||
interface Button { | ||
type: 'quick_reply' | 'url' | ||
buttonIndex?: number | ||
} | ||
|
||
interface QuickReplyButton extends Button { | ||
payload: string | ||
} | ||
|
||
interface UrlButton extends Button { | ||
urlVariable: string | ||
} | ||
|
||
interface Card { | ||
fileType: 'image' | 'video' | ||
fileId: string | ||
cardIndex?: number | ||
bodyParameters?: Parameters[] | ||
buttons?: CardButton[] | ||
extraComponents?: Record<string, any>[] | ||
} | ||
|
||
export interface WhatsappMediaCarouselProps { | ||
templateName: string | ||
templateLanguage: string | ||
cards: Card[] | ||
bodyParameters?: Parameters[] | ||
} | ||
|
||
const serialize = (message: string) => { | ||
return { text: message } | ||
} | ||
|
||
export const WhatsappMediaCarousel = (props: WhatsappMediaCarouselProps) => { | ||
const renderBrowser = () => { | ||
// Return a dummy message for browser | ||
const message = `WhatsApp Media Carousel would be sent to the user.` | ||
return ( | ||
<Message json={serialize(message)} {...props} type={INPUT.TEXT}> | ||
{message} | ||
</Message> | ||
) | ||
} | ||
|
||
const getCards = (cards: Card[]) => { | ||
cards.forEach((card, index) => { | ||
if (!card.cardIndex) { | ||
card.cardIndex = index | ||
} | ||
card.buttons?.forEach((button, index) => { | ||
if (!button.buttonIndex) { | ||
button.buttonIndex = index | ||
} | ||
}) | ||
}) | ||
return toSnakeCaseKeys(cards) | ||
} | ||
|
||
const renderNode = () => { | ||
return ( | ||
// @ts-ignore Property 'message' does not exist on type 'JSX.IntrinsicElements'. | ||
<message | ||
{...props} | ||
bodyParameters={JSON.stringify(toSnakeCaseKeys(props.bodyParameters))} | ||
cards={JSON.stringify(getCards(props.cards))} | ||
templateName={props.templateName} | ||
templateLanguage={props.templateLanguage} | ||
type={INPUT.WHATSAPP_MEDIA_CAROUSEL} | ||
/> | ||
) | ||
} | ||
|
||
return renderComponent({ renderBrowser, renderNode }) | ||
} |
83 changes: 83 additions & 0 deletions
83
packages/botonic-react/src/components/whatsapp-product-carousel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { INPUT } from '@botonic/core' | ||
import React from 'react' | ||
|
||
import { toSnakeCaseKeys } from '../util/functional' | ||
import { renderComponent } from '../util/react' | ||
import { Message } from './message' | ||
|
||
type Parameters = TextParameter | CurrencyParameter | DateTimeParameter | ||
|
||
interface TextParameter { | ||
type: 'text' | ||
text: string | ||
} | ||
|
||
interface CurrencyParameter { | ||
type: 'currency' | ||
currency: { | ||
fallbackValue: string | ||
code: string | ||
amount1000: number | ||
} | ||
} | ||
|
||
interface DateTimeParameter { | ||
type: 'date_time' | ||
dateTime: { fallbackValue: string } | ||
} | ||
|
||
interface Card { | ||
productRetailerId: string | ||
catalogId: string | ||
cardIndex?: number | ||
} | ||
|
||
export interface WhatsappProductCarouselProps { | ||
templateName: string | ||
templateLanguage: string | ||
cards: Card[] | ||
bodyParameters?: Parameters[] | ||
} | ||
|
||
const serialize = (message: string) => { | ||
return { text: message } | ||
} | ||
|
||
export const WhatsappProductCarousel = ( | ||
props: WhatsappProductCarouselProps | ||
) => { | ||
const renderBrowser = () => { | ||
// Return a dummy message for browser | ||
const message = `WhatsApp Product Carousel would be sent to the user.` | ||
return ( | ||
<Message json={serialize(message)} {...props} type={INPUT.TEXT}> | ||
{message} | ||
</Message> | ||
) | ||
} | ||
|
||
const getCards = (cards: Card[]) => { | ||
cards.forEach((card, index) => { | ||
if (!card.cardIndex) { | ||
card.cardIndex = index | ||
} | ||
}) | ||
return toSnakeCaseKeys(cards) | ||
} | ||
|
||
const renderNode = () => { | ||
return ( | ||
// @ts-ignore Property 'message' does not exist on type 'JSX.IntrinsicElements'. | ||
<message | ||
{...props} | ||
bodyParameters={JSON.stringify(toSnakeCaseKeys(props.bodyParameters))} | ||
cards={JSON.stringify(getCards(props.cards))} | ||
templateName={props.templateName} | ||
templateLanguage={props.templateLanguage} | ||
type={INPUT.WHATSAPP_PRODUCT_CAROUSEL} | ||
/> | ||
) | ||
} | ||
|
||
return renderComponent({ renderBrowser, renderNode }) | ||
} |
Oops, something went wrong.