@@ -286,16 +286,23 @@ In your webhook handler, verify the signature, parse the payload, and
286286acknowledge it by replying with the string ` "100" ` :
287287
288288``` ruby
289+ # In Rails, params[:data] is ActionController::Parameters, not a Hash — convert
290+ # it with .to_unsafe_h first, or the numeric-key ordering the signature depends
291+ # on is skipped and the check below rejects the payload. The payload is
292+ # signature-verified, so to_unsafe_h is safe here (.to_h would drop keys).
293+ # In bare Rack params["data"] is already a Hash; pass it as-is.
294+ data = params[:data ].to_unsafe_h
295+
289296# Reject forged callbacks: SMS.ru signs every payload with your api_id.
290297# The check is constant-time (timing-attack safe).
291- unless SmsRu ::Webhook .valid?(params[ " data" ] , params[" hash" ], " YOUR_API_ID" )
298+ unless SmsRu ::Webhook .valid?(data, params[: hash ], " YOUR_API_ID" )
292299 return head(:forbidden )
293300end
294301
295302# SMS.ru sends up to 100 records as POST fields data[0]..data[N]
296- # (a Hash in Rack/Rails , an Array in PHP). #parse handles either shape and
303+ # (a Hash in Rack, an Array in PHP). #parse handles either shape and
297304# returns a typed event per record.
298- SmsRu ::Webhook .parse(params[ " data" ] ).each do |event |
305+ SmsRu ::Webhook .parse(data).each do |event |
299306 case event
300307 when SmsRu ::Events ::SmsStatus # delivery report
301308 # event.id, event.status_code, event.created_at; event.delivered? => 103
0 commit comments