如何使用Faraday的POST方法发送URL编码表单数据?Twilio API请求报错排查
你的问题出在两个关键地方:参数键名的大小写不匹配,以及请求体的序列化方式错误,导致Twilio API无法识别你发送的参数。
1. 参数键名大小写问题
Twilio的Messages API要求参数名必须是首字母大写的格式(比如From、To、Body),但你在form_data中使用的是小写符号键(:from、:to、:body)。即使Faraday将哈希转换成表单格式,生成的参数名会是from=、to=,而Twilio只识别From=、To=这类格式,自然会提示缺少To参数。
2. 请求体序列化方式错误
你当前使用req.body = form_data直接赋值哈希,这会让Faraday默认将哈希序列化为JSON格式(从你给出的request_body是JSON字符串也能看出来),但Twilio需要的是application/x-www-form-urlencoded格式的表单数据,所以API无法解析JSON里的参数。
修改后的代码
第一步:修正参数键名
把form_data的键改成首字母大写的字符串(或者通过转换确保键名符合要求):
def form_data { 'From' => "whatsapp:+5491112312312", 'Body' => "Hello. Your order is on the way", 'To' => "whatsapp:+541132132121", } end
如果你偏好使用符号键,可以通过transform_keys自动转换:
def form_data { from: "whatsapp:+5491112312312", body: "Hello. Your order is on the way", to: "whatsapp:+541132132121", }.transform_keys { |key| key.to_s.capitalize } end
第二步:正确设置请求体格式
将req.body = form_data替换为req.form_data = form_data,这样Faraday会自动触发url_encoded中间件,将哈希转换成Twilio需要的表单格式:
def send_whatsapp_notification connector.post do |req| req.form_data = form_data end end
验证修改效果
修改后,你的请求体应该会变成类似Postman中的x-www-form-urlencoded格式:From=whatsapp%3A%2B5491112312312&Body=Hello.%20Your%20order%20is%20on%20the%20way&To=whatsapp%3A%2B541132132121
此时Twilio API就能正确识别所有参数,不会再返回21604错误了。
内容的提问来源于stack exchange,提问作者pinkfloyd90

