DEV Community

Luiz Américo
Luiz Américo

Posted on • Originally published at blikblum.dev on

WhatsApp webhook API types

The (Missing) WhatsApp webhook API types

I am working on a project that involves integrating with the WhatsApp Business API, and I noticed that there are no official TypeScript types for the webhook API. The documentation while detailed, lacks (or i could not find) the type definitions that would make it easier to work with the API in a type-safe manner.

So, I decided to create my own minimal set of types to help me with the integration.

Reverse engineering the webhook payload

The process was pretty simple: 1 - In my app webhook endpoint, i saved the received payloads to a database 2 - From this sample i created the types using a JSON to TypeScript converter 3 - I then refined the types to make them more readable and easier to work with.

Some notes:

  • The types are not exhaustive, they only cover the message types that I needed for my project i.e, 'messages' and 'message_template_status_update'.
  • My go to JSON to Typescript converter was from Transform.Tools which is based on json_typegen. But is lacking creation of enum / union types from fields with repeatable values. Fortunately i found quicktype that supports this feature.

The types

export interface NotificationPayload { object: "whatsapp_business_account"; entry: Entry[]; } export interface Entry { id: string; changes: Change[]; } export type Change = MessagesChange | MessageTemplateStatusUpdateChange; export interface MessagesChange { field: "messages"; value: MessagesValue; } export interface MessageTemplateStatusUpdateChange { field: "message_template_status_update"; value: MessageTemplateStatusUpdateValue; } export interface MessageTemplateStatusUpdateValue { reason: string; message_template_name: string; event: string; message_template_language: string; message_template_id: number; } export interface MessagesValue { metadata: Metadata; messaging_product: MessagingProduct; statuses?: StatusElement[]; messages?: Message[]; contacts?: Contact[]; } export interface Contact { profile: Profile; wa_id: string; } export interface Profile { name: string; } export interface Message { from: string; id: string; text?: Text; type: string; timestamp: string; sticker?: Sticker; } export interface Sticker { sha256: string; mime_type: string; animated: boolean; id: string; } export interface Text { body: string; } export type MessagingProduct = "whatsapp"; export interface Metadata { phone_number_id: string; display_phone_number: string; } export interface StatusElement { biz_opaque_callback_data?: string; id: string; conversation?: Conversation; pricing?: Pricing; status: StatusEnum; timestamp: string; recipient_id: string; errors?: Error[]; } export interface Conversation { origin: Origin; id: string; expiration_timestamp?: string; } export interface Origin { type: Category; } export type Category = "marketing" | "utility"; export interface Error { code: number; title: string; message: string; error_data: ErrorData; } export interface ErrorData { details: string; } export interface Pricing { pricing_model: PricingModel; category: Category; billable: boolean; } export type PricingModel = "CBP"; export type StatusEnum = "delivered" | "failed" | "read" | "sent"; 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)