Question

I'm working with the Urban Airship (v3) API to push out messages to Android/iPhone/Blackberry and hopefully soon Windows phones. I'm not responsible for that; instead, I'm setting up the backend to allow users to send out a broadcast.

Another guy built the original backend, but I chose to rebuilt it from the bottom up to add in some additional functionality. Everything works in it, except the whole pushing of the broadcast part. Well, it sort of works; let me explain:

When a form is submitted, the data goes into the database via MYSQL and then with mysql_fetch_id() I get the new id and toss that id into a PHP function called sentBroadcast. It looks like the following:

function sentBroadcast($id){

$alertinfo = getAlertInfo($id);//this just gets all the data matching the id
$alert = mysql_fetch_assoc($alertinfo);     

    //these just get extra values   
$organization = getOrganizationById($alert['broadcast_organization_id']);
$cityinfo =  getCityInfo($organization['organization_city_id']);
$city = mysql_fetch_assoc($cityinfo);

// Create Airship object
$airship = new Airship(APP_KEY, APP_MASTER_SECRET);

$apiurl = "https://go.urbanairship.com/api/location/?q=".str_replace(" ","",strtolower($city['city_name']));

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $apiurl); 
curl_setopt($ch, CURLOPT_USERPWD, APP_KEY.":".APP_MASTER_SECRET);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close ($ch);

$json = json_decode($output);

$locationid = "all";

if(count($json->features) > 0){
    $locationid = $json->features[0]->id;
}


//send the message

$broadcasttype = "";
if($alert['broadcast_broadcasttypeother'] != ""){
    $broadcasttype = $alert['broadcast_broadcasttypeother'];
}
else {
            //this just gets data, nothing to see here
    $broadcasttype = getCategoryInfo($alert['broadcast_broadcasttype_id'],'broadcasttype_name');
}

$message = html_entity_decode($broadcasttype)."\r\n".html_entity_decode($organization['organization_name'])."\r\n". html_entity_decode($alert['broadcast_subject']);
$blackberry_message = html_entity_decode($organization['organization_name'])."\r\n". html_entity_decode($alert['broadcast_subject']);


//calc as UTC
$timestamp = strtotime($alert['broadcast_sentdatetime']) + strtotime("+1 minute"); //add an hour
$offset = new DateTime(date("Y-m-d H:i:s T",$timestamp)); 
$offset->setTimezone(new DateTimeZone('UTC'));

$minutes_to_add = 10;

$time = new DateTime($alert['broadcast_sentdatetime']);
$time->add(new DateInterval('PT' . $minutes_to_add . 'S'));

$stamp = $time->format('Y-m-d H:i:s');

//echo $stamp;

$broadcast_message = array( 
                            'schedule' => array("scheduled_time" => $stamp), 
                            'push' => array("audience" => "all",
                                             "notification" => array("alert"    => $message), 
                                             "device_types" => array()
                                            ),
                            );
$device_types = array();
$device_types[] = "ios";
$device_types[] = "android";
$device_types[] = "blackberry";
$broadcast_message["push"]["device_types"] = $device_types;

if(in_array("ios", $device_types)){
    $broadcast_message["push"]["notification"]["ios"] = array("sound" => "police.mp3", "extra" => array("id"=>$alert['broadcast_id']), "badge"  => "+1");
}
if(in_array("android", $device_types)){
    $broadcast_message["push"]["notification"]["android"] = array("extra"=>array("id"=>$alert['broadcast_id']));
}
if(in_array("blackberry", $device_types)){
    $broadcast_message["push"]["notification"]["blackberry"] = array("content-type"=>"text/plain","body"=> json_encode(array("id"=>$alert['broadcast_id'], "body"=>$blackberry_message, "type"=>$broadcasttype)));
}


$data_string = json_encode($broadcast_message);

$apiurl = "https://go.urbanairship.com/api/schedules/";
$ch = curl_init(); 


curl_setopt($ch, CURLOPT_URL, $apiurl); 
curl_setopt($ch, CURLOPT_USERPWD, APP_KEY.":".APP_MASTER_SECRET);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                                            'Content-type: application/json',
                                            'Accept: application/vnd.urbanairship+json; version=3;',
                                            'Content-Length: ' . strlen($data_string)
                                            ));

$json = curl_exec($ch);
$output = json_decode($json, true);

if(!is_array($output) || empty($output["ok"])){
  echo "<h1>ERROR: (".(isset($output["error"]) ? $output["error"] : "An unknown error has occurred while trying to send your message.").")</h1>";
  echo $data_string;
  print_r($output);
  $error = true;
}


curl_close ($ch);

$debug = false;
if($debug || $error){
  if($error) echo "<!--";
    var_dump($broadcast_message);
    echo "<hr><br>";
    echo $json."<hr><br>";
    echo "<pre>";
    print_r($output);
    echo "</pre>";

    if(!empty($output['ok'])){
      //maybe we should save the status, or the json in the db.
      echo 'yay it sent';
    }
  if($error) echo "-->";
}
        if($error){
          exit;
        }
}//end sendBroadcast

When I do this query, I get hit by an error "Could not parse body request body". That wasn't very helpful, so I printed the response (look under "if(!is_array($output) || empty($output["ok"])){"). I get the following error message:

Array ( [ok] => [error] => Could not parse request body. [error_code] => 40700 [details] => Array ( [error] => Cannot schedule for the past 2013-10-12T06:46:00.000Z ) [operation_id] => 6fde4fa0-4b64-11e3-8903-90e2ba0253a0 )

The error I'm getting is "Cannot schedule for the past", however at the time of submitting this, it was the future. I began doing some research and read that I had to set it to UTC time. That being said, whatever my time is now, it will always be 6 hours into the past in UTC, so I have to convert it up to UTC.

So, I did that and the message went out and the phones received it and all went well. Except when we went to read the message: we then got an error that said the message was deleted.

We didn't delete it, so I think maybe (it hasn't been 6 hours yet) the users phone will get the new broadcast in the future, but they got informed of the alert now. That alert isn't visible yet, so it throws an error. At least that's what I think; it hasn't been 6 hours yet so I can't prove that.

My problem is this: How do I tell Urban Airship I want an immediate post to go out, without having to add 6 hours to the current time to make it in the "present", as well as actually having the phones get it at the correct time?

I contacted UA but they said to "expect a week delay in responding to you" (No rush, eh?) and I googled the error code (40700) and came up with nothing. I then emailed the guy who built the original and all he said was the "UTC was very important". Thank you for that.

If anybody can help me out I would be very thankful.

Thank you.

Oh, and if anybody is wondering, the json I'm submitting looks like the following:

{"schedule":{"scheduled_time":"2013-10-12 06:46:00"},"push":{"audience":"all","notification":{"alert":"Message\r\nKenton Industries\r\nKenton Test","ios":{"sound":"police.mp3","extra":{"id":"406"},"badge":"+1"},"android":{"extra":{"id":"406"}},"blackberry":{"content-type":"text\/plain","body":"{\"id\":\"406\",\"body\":\"Kenton Industries\\r\\nKenton Test\",\"type\":\"Message\"}"}},"device_types":["ios","android","blackberry"]}}

Thanks :)

Was it helpful?

Solution

I'm not sure I understand the second part of your question of, "having the phones get it at the correct time". In regards to the question of, "How do I tell Urban Airship I want an immediate post to go out, without having to add 6 hours to the current time to make it in the "present"":

If you want your users to receive the message as soon as possible then you shouldn't be scheduling your message. Via their curl examples an immediate push message curl request should look as thus:

curl -v -X POST -u "<AppKey>:<MasterSecret>" -H "Content-type: application/json" -H "Accept: application/vnd.urbanairship+json; version=3;" --data '{"audience" : "all", "device_types" : "all", "notification" : {"alert": "This is a broadcast"} }' https://go.urbanairship.com/api/push/ 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top