使用Azure Communication Service发WhatsApp报InvalidParameter:(#100)偶发故障
问题背景
使用Azure Communication Service(ACS)发送WhatsApp模板消息稳定运行5个月后,近期开始偶发BadRequest错误,错误提示参数无效(包含Channel ID或模板参数),但部分报错场景下消息仍能成功发送,故障频率约每3-4条消息出现1次。已确认传入参数、模板变量及名称均无问题。
错误日志如下:
An unexpected error occurred: (BadRequest) Given request contains a parameter for WhatsApp which was invalid. This includes channel ID and template parameters.
Code: BadRequest
Message: Given request contains a parameter for WhatsApp which was invalid. This includes channel ID and template parameters.
Inner error: {
"code": "WhatsAppAdminClient+WaErrorCode.InvalidParameter",
"message": "InvalidParameter: (#100) Invalid parameter. Invalid parameter."
}
排查步骤
检查模板参数的特殊字符与格式
当前代码中给模板参数额外包裹了单引号(如f"'{topic}'"),若参数本身包含引号、换行或特殊符号,会导致嵌套格式异常,触发WhatsApp的参数校验失败。建议移除额外的单引号,或对参数中的特殊字符做转义处理。验证语言代码与模板名称的一致性
检查search_pandas_df返回的lang_code和template是否存在偶发的空值或错误值。可在代码中添加日志,记录每次请求的session['selected_language']、lang_code、template值,对比成功与失败请求的差异。排查Channel Registration ID的临时异常
尽管已确认Channel ID正确,但ACS端的临时状态波动或网络问题可能导致偶发校验失败。可尝试重新获取最新的Channel Registration ID,或针对此类错误添加重试机制。升级ACS SDK版本
运行5个月后可能存在SDK版本过时的情况,偶发问题可能与SDK已知bug有关。执行pip install --upgrade azure-communication-messages升级至最新版本。精细化日志对比
在调用send方法前,序列化打印template_options的完整内容,对比成功与失败请求的参数差异:import json # 发送前打印完整请求参数 print(json.dumps(template_options.to_dict(), indent=2))
解决建议
修正模板参数格式
移除参数中的额外单引号,直接传入原始值:value1 = MessageTemplateText(name="1", text=topic) value2 = MessageTemplateText(name="2", text=user_name) value3 = MessageTemplateText(name="3", text=subject) value4 = MessageTemplateText(name="4", text=email) value5 = MessageTemplateText(name="5", text=phone_number)添加重试逻辑
针对偶发的HttpResponseError(BadRequest类型)添加有限次数的重试:from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type from azure.core.exceptions import HttpResponseError @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10), retry=retry_if_exception_type(HttpResponseError)) def send_with_retry(client, options): return client.send(options) # 替换原send调用 message_responses = send_with_retry(messaging_client, template_options)添加参数校验
确保所有模板参数符合WhatsApp的限制(如单参数字符长度不超过1024、不含控制字符),可在参数传入时做校验过滤:def clean_template_param(text): # 移除控制字符和多余换行 cleaned = ' '.join(text.split()) # 截断过长内容 return cleaned[:1024] # 使用时 value1 = MessageTemplateText(name="1", text=clean_template_param(topic))
内容的提问来源于stack exchange,提问作者Kakobo kakobo

