We are making changes to the WhatsApp Business Platform pricing model. See Pricing Updates on the WhatsApp Business Platform.

创建和管理模板

使用由 Meta 托管的云端 API 或本地 API 发送模板消息时,会用到模板。云端 API 借助机器学习审核模板和变量参数,以保护云端 API 服务的安全和诚信。在审核模板和变量文本时,云端 API 不会与 WhatsApp 分享任何信息。

您可以使用 WhatsApp Business 管理 API 或 WhatsApp 商务管理平台创建模板。WhatsApp Business 商业帐号可以拥有的模板数量由该帐号的母公司决定。如果母公司未经认证,则其下每个 WhatsApp Business 商业帐号最多可拥有 250 个模板。但是,如果母公司已经过认证,且至少有一个 WhatsApp Business 业务账户具有商业电话号码和经批准的显示名,则每个 WhatsApp Business 业务账户最多可拥有 6,000 个模板。

前期准备

您需要提供:

  • 与企业关联的系统用户访问口令
  • 企业的 WhatsApp Business 业务账户编号
  • 要在媒体模板中使用的任何文档、图像或视频文件的媒体素材名称。如需获取媒体素材名称,您必须使用可续传 API 上传媒体素材。

限制

  • 消息模板名称字段的限制为 512 个字符。
  • 消息模板内容字段的限制为 1,024 个字符。
  • 只有当模板处于已批准未通过已暂停状态时,才能对其进行编辑。您每天可以编辑模板一次,每个月最多可以编辑 10 次。
  • 每个 WhatsApp Business 商业帐号每小时只能创建 100 个消息模板。
  • 包含 4 个或以上按钮的模板或包含 1 个快速回复按钮和 1 个或多个其他类型按钮的模板无法在 WhatsApp 桌面版客户端上查看。如果 WhatsApp 用户收到一条包含此类模板的消息,系统会提示他们改用手机查看该消息。

本地化

在创建模板时,您可以添加特定语言的消息模板。这些模板会计入您的模板数限额。各消息模板所提供的翻译语言应保持一致。有关详情,请参阅帮助中心文章为什么我会在回调中看见“structure unavailable”错误?

创建模板

WhatsApp Business 业务账户 > 消息模板端点发送 POST 请求,以创建模板。

请求语法

POST /<WHATSAPP_BUSINESS_ACCOUNT_ID>/message_templates

POST 请求正文

{
  "name": "<NAME>",
  "category": "<CATEGORY>",
  "allow_category_change": <ALLOW_CATEGORY_CHANGE>,
  "language": "<LANGUAGE>",
  "components": [<COMPONENTS>]
}

正文属性

占位符描述示例值

<NAME>

字符串

必要。


模板的名称。

不超过 512 个字符。

order_confirmation

<CATEGORY>

枚举

必要。


模板类别。

请参阅下方模板类别部分。

UTILITY

<ALLOW_CATEGORY_CHANGE>

布尔值

非必要。


设置为 true,可允许我们自动分配类别。如果此属性未设置,模板可能会因分类错误而被拒绝。

true

<LANGUAGE>

枚举

必要。


模板的语言和区域代码

en_US

<LIBRARY_TEMPLATE_NAME>

字符串

非必要。


交易相关模板库模板的确切名称。

了解如何使用交易相关模板库创建模板

delivery_update_1

<COMPONENTS>

对象数组

必要。


构成模板的组件。

请参阅下方模板组件部分。

请参阅下方模板组件部分。

占位符描述示例值

<LIBRARY_TEMPLATE_BUTTON_INPUTS>

JSON 对象

非必要。


从模板库创建模板时的可选数据。这些是按钮组件的可选字段。


注意:对于包含按钮的交易相关模板,此属性不是选填项。

了解如何使用模板库创建模板

“[ {'type': 'URL', 'url': {'base_url' : 'https://www.example.com/{{1}}', 'url_suffix_example' : 'https://www.example.com/demo'}}, {type: 'PHONE_NUMBER', 'phone_number': '+16315551010'} ]"

type

枚举

按钮类型

QUICK_REPLY, URL, PHONE_NUMBER, OTP, MPM, CATALOG, FLOW, VOICE_CALL, APP

必要

OTP

phone_number

字符串

按钮对应电话号码。

可选

"+13057652345"

url

JSON 对象

在此处查看 JSON 对象 URL 参数 base_urlurl_suffix_example

非必要

zero_tap_terms_accepted

布尔值

用户是否接受零轻触条款。

非必要

TRUE

otp_type

枚举

OTP 类型。

COPY_CODE, ONE_TAP, ZERO_TAP

非必要

TRUE

supported_apps

JSON 对象数组

在此处查看 JSON 对象支持的应用参数 package_namesignature_hash

非必要

占位符描述示例值

<LIBRARY_TEMPLATE_BODY_INPUTS>

JSON 对象

非必要。


从模板库创建模板时的可选数据。这些是按钮组件的可选字段。


了解如何使用模板库创建模板

add_contact_number

布尔值

用于在模板中添加企业电话号码联系方式的布尔值。

非必要

TRUE

add_learn_more_link

布尔值

用于在模板中添加网址链接(针对“了解详情”)信息的布尔值。

此属性并非广受支持;如不受支持,此属性将被忽略。

非必要

TRUE

add_security_recommendation

布尔值

用于在模板中添加有关不与任何人分享验证码信息的布尔值。

非必要

TRUE

add_track_package_link

布尔值

用于在模板中添加配送包裹追踪所需信息的布尔值。

此属性并非广受支持;如不受支持,此属性将被忽略。

非必要

TRUE

code_expiration_minutes

int64

用于在模板中添加代码过期时间信息的整数值。

非必要

5

模板类别

模板必须使用以下类别之一进行分类。模板的类别会成为定价的一个参考因素,而且您指定的类别将在创建模板时接受验证

  • AUTHENTICATION
  • MARKETING
  • UTILITY

请参阅我们的模板分类文档,确定您在创建模板时要使用哪个类别。

模板组件

模板由各种文本、媒体和互动组件组成,具体取决于您的业务需求。请参阅模板组件文档,获取包含所有可用组件及其要求以及示例和示例查询的清单。

创建模板时,将一个组件对象数组分配到请求正文中的 components 属性,以定义模板的组件。

例如,以下数组中包含一个文本正文组件(含两个变量及其值示例)、一个电话号码按钮组件和一个网址按钮组件:

[
  {
    "type": "BODY",
    "text": "Thank you for your order, {{1}}! Your confirmation number is {{2}}. If you have any questions, please use the buttons below to contact support. Thank you for being a customer!",
    "example": {
      "body_text": [
        [
          "Pablo","860198-230332"
        ]
      ]
    }
  },
  {
    "type": "BUTTONS",
    "buttons": [
      {
        "type": "PHONE_NUMBER",
        "text": "Call",
        "phone_number": "15550051310"
      },
      {
        "type": "URL",
        "text": "Contact Support",
        "url": "https://www.luckyshrub.com/support"
      }
    ]
  }
]

请参阅模板组件文档,获取包含所有可用组件及其要求以及示例和示例查询的清单。

请注意,分类为 AUTHENTICATION 的模板存在特别的组件要求。请参阅身份验证模板

类别验证

您发送模板创建请求时,我们会立即使用模板分类指南验证该模板的类别。

  • 如果我们同意您指定的类别,我们会创建模板并将其 status 设为 PENDING。然后模板将进入模板审核流程。
  • 如果我们不同意您指定的类别,我们会创建模板,但会将其 status 设为 REJECTED,这会触发消息模板状态更新 Webhooks,其中包含 reason(设为 INCORRECT_CATEGORY)。建议您留意该 Webhooks,以便确定被拒的模板;或在新建模板上请求获取 rejected_reason 字段,该字段值将为 TAG_CONTENT_MISMATCH

在这两种情况下,返回的 API 响应中都将包含模板的初始状态。

在类别验证过程中,如果您的模板状态已设为 REJECTED,您有以下几个选择:

自动分类

您可以在请求中加入 allow_category_change 属性,以便我们根据该模板的内容和模板分类指南对该模板进行自动分类。这可以防止模板状态因分类错误而被立即设为 REJECTED

请注意,仅在创建模板时才能进行自动分类。

模板审核

状态为 PENDING 的模板将进入模板审核流程。我们会对每个新建或编辑的模板进行内容审核,以确保其内容符合我们的内容指南和政策。我们会根据审核结果,自动将模板状态更改为 APPROVEDREJECTED,这会触发消息模板状态更新 Webhooks。

模板状态

根据类别验证和模板审核的结果,我们会将模板的 status 设置或更改为以下值之一:

  • APPROVED — 模板已通过模板审核并获得批准,现在可通过模板消息发送
  • PENDING — 模板已通过类别验证,将进入模板审核流程。
  • REJECTED — 模板未通过类别验证或模板审核。您可以在模板上请求获取 rejected_reason 字段,以获取原因。

请参阅 WhatsApp 消息模板端点参考文档,了解所有可能的字段和状态。

响应

若请求成功,API 响应中将包含新建模板的编号、状态和类别信息。可能会有三种结果:

  • 我们同意您指定的模板类别,现在模板进入模板审核流程(statusPENDING)。
  • 我们不同意您指定的模板类别(statusREJECTED
  • 我们自动批准了模板(statusAPPROVED)。此结果仅适用于包含一次性密码按钮的身份验证模板
{
    "id": "<ID>",
    "status": "<STATUS>",
    "category": "<CATEGORY>"
}

响应属性

占位符描述示例值

<ID>

模板编号。

572279198452421

<STATUS>

模板状态

PENDING

<CATEGORY>

您指定或我们分配模板类别

MARKETING

请求示例

使用以下组件创建季节性促销模板的示例请求:

  • 1 个文本标头
  • 1 个文本正文
  • 1 个页脚
  • 2 个快速回复按钮

如需更多示例,请参阅示例请求

curl 'https://graph.facebook.com/v21.0/102290129340398/message_templates' \
-H 'Authorization: Bearer EAAJB...' \
-H 'Content-Type: application/json' \
-d '
{
  "name": "seasonal_promotion",
  "language": "en_US",
  "category": "MARKETING",
  "components": [
    {
      "type": "HEADER",
      "format": "TEXT",
      "text": "Our {{1}} is on!",
      "example": {
        "header_text": [
          "Summer Sale"
        ]
      }
    },
    {
      "type": "BODY",
      "text": "Shop now through {{1}} and use code {{2}} to get {{3}} off of all merchandise.",
      "example": {
        "body_text": [
          [
            "the end of August","25OFF","25%"
          ]
        ]
      }
    },
    {
      "type": "FOOTER",
      "text": "Use the buttons below to manage your marketing subscriptions"
    },
    {
      "type":"BUTTONS",
      "buttons": [
        {
          "type": "QUICK_REPLY",
          "text": "Unsubscribe from Promos"
        },
        {
          "type":"QUICK_REPLY",
          "text": "Unsubscribe from All"
        }
      ]
    }
  ]
}'

响应示例

{
    "id": "572279198452421",
    "status": "PENDING",
    "category": "MARKETING"
}

发送模板

使用云端 APIOn-Premises API 通过模板消息发送模板。

存留时间 (TTL):自定义值、默认值、最小/最大值和兼容性

如果我们无法将消息送达 WhatsApp 用户,我们会在一个称为“存留时间 (TTL)”或“消息有效期”的时间段内重试传递。

您可以自定义身份验证模板、交易模板和营销模板的默认留存时间。

建议您为自己的所有身份验证模板都设置存留时间,以不长于验证码有效期为宜,从而确保您的客户仅在验证码仍然可用时收到消息。

默认值、最低/最大值和兼容性表

身份验证交易营销

默认留存时间

10 分钟

30 天

30 天

兼容性

云端 API + 本地 API

仅适用于云端 API

营销信息 (MM) Lite API

可定制范围

30 秒至 15 分钟

30 秒至 12 小时

12 小时至 30 天

自定义模板存留时间的方法

对于 2024 年 10 月 23 日之前创建的身份验证模板,默认存留时间为 30 天。

如要设置身份验证模板、交易模板或营销模板的自定义存留时间,请在 POST /<PHONE_NUMBER_ID>/messages 通话中包含并设置 message_send_ttl_seconds 属性值。

留存时间可按 1 秒的增量进行定制。

有效 message_send_ttl_seconds 属性值

  • 身份验证模板:30900 秒(30 秒至 15 分钟)
  • 交易相关模板:3043200 秒(30 秒至 12 小时)
  • 营销模板:432002592000(12 小时至 30 天)

对于身份验证和交易模板,您可以将 message_send_ttl_seconds 属性值设置为 -1,可将自定义留存时间设为 30 天。

当超过存留时间时:丢弃的消息

在默认或自定义存留时间内无法送达的消息将被丢弃。

如果您在超出存留时间之前未收到送达的消息 Webhook,即可认为该消息已丢弃。

如果您发送的消息未送达,可能是在收到 Webhook 之前略有延迟,因此在假定消息被丢弃之前,您可能想设置一小段缓冲时间。

营销模板最佳实践

营销内容退订按钮

建议您在 MARKETING 类模板中添加快速回复按钮,便于客户退订您的营销消息。客户可借此选择退订您的营销信息,而无需拉黑您的公司。这样一来,您可能会更快地增加消息量。请参阅这篇文章,详细了解在您的营销模板中添加退订按钮所带来的好处。

您的企业必须采取必要的措施来停止向已经选择退订营销信息的客户发送相关信息。否则,这会对您的拉黑率和质量评分产生负面影响。

获取模板

WhatsApp Business 业务账户 > 消息模板端点发送 GET 请求,获取 WhatsApp Business 业务账户拥有的模板清单。

请求语法

GET /<WHATSAPP_BUSINESS_ACCOUNT_ID>/message_templates
  ?fields=<FIELDS>
  &limit=<LIMIT>

查询字符串参数

占位符描述示例值

<FIELDS>

逗号分隔列表

非必要。


您希望返回的模板字段列表。

name,status

<LIMIT>

整数

非必要。


您希望在每页结果中返回的模板数量上限。

10

请求示例

curl 'https://graph.facebook.com/v21.0/102290129340398/message_templates?fields=name,status&limit=3' \
-H 'Authorization: Bearer EAAJB...'

响应示例

{
  "data": [
    {
      "name": "seasonal_promotion_text_only",
      "status": "APPROVED",
      "id": "564750795574598"
    },
    {
      "name": "seasonal_promotion_video",
      "status": "PENDING",
      "id": "1252715608684590"
    },
    {
      "name": "seasonal_promotion_image_header",
      "status": "PENDING",
      "id": "1372429296936443"
    }
  ],
  "paging": {
    "cursors": {
      "before": "MAZDZD",
      "after": "MgZDZD"
    },
    "next": "https://graph.facebook.com/v21.0/102290129340398/message_templates?fields=name%2Cstatus&limit=3&after=MgZDZD"
  }
}

请求示例(遭拒模板)

您可以通过在请求中加入字段和所需值,仅返回包含特定字段值的模板。例如,在请求中加入 status=REJECTED 以仅获取遭拒的模板。

curl 'https://graph.facebook.com/v21.0/104996122399160/message_templates?fields=name,status&status=REJECTED' \
-H 'Authorization: Bearer EAAJB...'

响应示例

{
  "data": [
    {
      "name": "seasonal_promotion_text_only_v4",
      "status": "REJECTED",
      "id": "564750795574598"
    },
    {
      "name": "discount_qualifier",
      "status": "REJECTED",
      "id": "163917509772674"
    },
    {
      "name": "limited_time_offer_tuscan_getaway_2023",
      "status": "REJECTED",
      "id": "202389039167147"
    },
    {
      "name": "2023_mar_promo_2",
      "status": "REJECTED",
      "id": "1116034925734553"
    },
    {
      "name": "2023_mar_promo",
      "status": "REJECTED",
      "id": "952600926095321"
    }
  ]
}

检索模板命名空间

需要具有消息模板命名空间,才能使用消息模板发送消息。

如要获取模板的命名空间,请向 /{whatsapp-business-account-ID} 端点发送 GET 请求,并在其中添加 message_template_namespace 字段。

请求示例

为方便阅读,示例格式已经过调整。
curl -i -X GET "https://graph.facebook.com/v21.0/{whatsapp-business-account-ID}
  ?fields=message_template_namespace
  &access_token={system-user-access-token}"

若请求成功,系统将返回包含 WhatsApp Business 商业帐号编号和命名空间的 JSON 对象:

{
    "id": "1972385232742141",
    "message_template_namespace": "12abcdefghijk_34lmnop" 
}

编辑模板

WhatsApp 消息模板端点发送 POST 请求,以编辑模板。您还可以使用 WhatsApp 管理工具 > 账户工具 > 消息模板面板,手动编辑模板。

限制

  • 仅可编辑带有 APPROVEDREJECTEDPAUSED 状态的模板。
  • 您仅可编辑模板的 categorycomponents
  • 您无法编辑已批准模板的 category
  • 您在连续 30 天内至多可以编辑 10 次处于已批准状态的模板(或每 24 小时编辑 1 次),对处于被拒或已暂停状态的模板的编辑次数则不受限制。
  • 在您编辑处于已批准或已暂停状态的模板后,系统会自动批准该模板,除非该模板未通过模板审核。

请求语法

POST /<WHATSAPP_MESSAGE_TEMPLATE_ID>

POST 请求正文

{
  "category": "<CATEGORY>",
  "components": [<COMPONENTS>]
}

属性

占位符描述示例值

<CATEGORY>

字符串

如果省略 components 属性,则为必要项。


模板类别。

AUTHENTICATION

<COMPONENTS>

数组

如果省略 category 属性,则为必要项。


模板组件对象数组。

请参阅下方请求示例(编辑组件)部分。

请求示例(编辑组件)

将模板正文文本由包含营销和交易相关内容更改为仅包含营销内容的请求示例。

curl 'https://graph.facebook.com/v21.0/564750795574598' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer EAAJB...' \
-d '
{
  "components": [
    {
      "type": "HEADER",
      "format": "TEXT",
      "text": "Our {{1}} is on!",
      "example": {
        "header_text": [
          "Spring Sale"
        ]
      }
    },
    {
      "type": "BODY",
      "text": "Shop now through {{1}} and use code {{2}} to get {{3}} off of all merchandise.",
      "example": {
        "body_text": [
          [
            "the end of April",
            "25OFF",
            "25%"
          ]
        ]
      }
    },
    {
      "type": "FOOTER",
      "text": "Use the buttons below to manage your marketing subscriptions"
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "QUICK_REPLY",
          "text": "Unsubcribe from Promos"
        },
        {
          "type": "QUICK_REPLY",
          "text": "Unsubscribe from All"
        }
      ]
    }
  ]
}'

请求示例(仅编辑类别)

将模板类别由 UTILITY 更改为 MARKETING 的请求示例。

curl 'https://graph.facebook.com/v21.0/1252715608684590' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer EAAJB...' \
-d '
{
  "category": "MARKETING"
}'

响应示例

请求成功时的响应示例。

{
  "success": true
}

删除模板

使用 WhatsApp Business 商业帐号 > 消息模板端点可按名称或编号删除模板。

备注

  • 如果您删除已通过模板消息发送但尚未送达的模板(例如因客户电话已关机),模板的状态将设为 PENDING_DELETION,我们将尝试在 30 天内送达此消息。30 天后,您会收到“structure unavailable”错误消息,且客户将收不到此模板消息。
  • 删除已批准的模板后,您在 30 天内将无法再使用此模板的名称。

按名称删除

按名称删除模板会删除所有与此名称一致的模板(这意味着,同名但语言不同的模板也将被删除)。

请求语法

DELETE /<WHATSAPP_BUSINESS_ACCOUNT_ID>/message_templates
  ?name=<NAME>

请求示例

curl -X DELETE 'https://graph.facebook.com/v16.0/102290129340398/message_templates?name=order_confirmation' \
-H 'Authorization: Bearer EAAJB...'

响应示例

{
  "success": true
}

按编号删除

如要按编号删除模板,请在请求中加入模板的编号和名称;仅模板编号一致的模板将被删除。

请求语法

DELETE /<WHATSAPP_BUSINESS_ACCOUNT_ID>/message_templates
  ?hsm_id=<HSM_ID>,
  &name=<NAME>

请求示例

curl -X DELETE 'https://graph.facebook.com/v21.0/102290129340398/message_templates?hsm_id=1407680676729941&name=order_confirmation' \
-H 'Authorization: Bearer EAAJB...'

响应示例

{
  "success": true
}