First let's figure out what went wrong. Here's an approximation of your code trimmed for brevity:
ids = ["d_sample_id1","d_sample_id2"]
puts %(curl ... -d '{"registration_ids": "#{ids}"}')
Here I'm using puts %() instead of %x(...) to just print the string instead of executing it. Here's the output:
curl ... -d '{"registration_ids": "["d_sample_id1", "d_sample_id2"]"}'
Spot the problem? It's here: "["d_.... You've put your array inside double-quotes. When the JSON parser sees the first double-quote it thinks "ah, this is the beginning of a string". Then it gets to the next double-quote, right after the square bracket, and thinks, "and here is the end of the string." But the very next character is the letter d, which doesn't make any sense right after a string, so the parser throws an error and calls it a day.
You could fix that by removing the extra quotation marks. But it would be a band-aid at best, for this reason: It would only work incidentally. When you use string interpolation in Ruby, Ruby calls to_s on the expression inside #{...}. But it's only incidental that when you call to_s on an array of Ruby strings you get valid JSON. What if the expression is a Hash, or a Date? String interpolation will fail you.
But even if you know you've just got an array of Strings, interpolation will fail you for a second reason: You're building command-line arguments, which need to be properly escaped. Take this for example:
arr = ["I can't even"]
%(curl ... -d '#{arr}')
Spot the problem? This is going to try to execute the following:
curl ... -d '["I can't even"]'
Spot the problem? This time you've got mismatched single-quotes.
What a nightmare!
This leads us to two important rules of thumb:
Don't build JSON with string concatenation/interpolation unless you enjoy pain and suffering.
Be very careful using string concatenation/interpolation to build command-line arguments unless you enjoy pain and suffering.
Fortunately we don't have to worry about our JSON being formatted properly or our command-line arguments being properly escaped, because much smarter people than us have already worried about those things and put the solutions right into Ruby's standard library, in the delightful JSON and Shellwords modules. And so:
require "json"
require "shellwords"
ids = [ "d_sample_id1", "d_sample_id2" ]
data = {
registration_ids: ids,
collapse_key: "Turn",
data: {
title: "test",
sound: true,
body: "test",
badge: "1" ,
content_available: 1,
url: ""
}
}
json_arg = Shellwords.escape(data.to_json)
%x(curl \
--header 'Authorization: key=keynotmentioned' \
--header 'Content-Type: application/json' \
"https://android.googleapis.com/gcm/send" \
-d #{json_arg}
)
As a bonus, being able to set up our data as a Ruby Hash makes it way more readable, maintainable, and testable.