You are here

function push_notifications_gcm_send_message in Push Notifications 7

Send out push notifications through GCM.

@link http://developer.android.com/guide/google/gcm/index.html

Parameters

$tokens: Array of gcm tokens

$payload: Payload to send.

Return value

Array with the following keys:

  • count_attempted (# of attempted messages sent)
  • count_success (# of successful sends)
  • success (# boolean)
  • message (Prepared result message)
2 calls to push_notifications_gcm_send_message()
push_notifications_mass_push_form_submit in includes/push_notifications.admin.inc
Submit handler for sending out a mass-push notification.
push_notifications_send_alert in ./push_notifications.module
Handle delivery of simple alert message.

File

./push_notifications.module, line 910
Push Notifications functionality.

Code

function push_notifications_gcm_send_message($tokens, $payload) {
  if (!is_array($tokens) || empty($payload) || is_array($tokens) && empty($tokens)) {
    return FALSE;
  }

  // Define an array of result values.
  $result = array(
    'count_attempted' => 0,
    'count_success' => 0,
    'success' => 0,
    'message' => '',
  );

  // Define the header.
  $headers = array();
  $headers[] = 'Content-Type:application/json';
  $headers[] = 'Authorization:key=' . PUSH_NOTIFICATIONS_GCM_API_KEY;

  // Check of many token bundles can be build.
  $token_bundles = ceil(count($tokens) / 1000);
  $result['count_attempted'] = count($tokens);

  // Send a push notification to every recipient.
  for ($i = 0; $i < $token_bundles; $i++) {

    // Create a token bundle.
    $bundle_tokens = array_slice($tokens, $i * 1000, 1000, FALSE);

    // Convert the payload into the correct format for C2DM payloads.
    // Prefill an array with values from other modules first.
    $data = array();
    foreach ($payload as $key => $value) {
      if ($key != 'alert') {
        $data['data'][$key] = $value;
      }
    }

    // Fill the default values required for each payload.
    $data['registration_ids'] = $bundle_tokens;
    $data['collapse_key'] = (string) time();
    $data['data']['message'] = $payload['alert'];
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, PUSH_NOTIFICATIONS_GCM_SERVER_POST_URL);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_POST, TRUE);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
    $response_raw = curl_exec($curl);
    $info = curl_getinfo($curl);
    curl_close($curl);
    $response = FALSE;
    if (isset($response_raw)) {
      $response = json_decode($response_raw);
    }

    // If Google's server returns a reply, but that reply includes an error,
    // log the error message.
    if ($info['http_code'] == 200 && !empty($response->failure)) {
      watchdog('push_notifications', "Google's Server returned an error: " . $response_raw, NULL, WATCHDOG_ERROR);

      // Analyze the failure.
      foreach ($response->results as $token_index => $message_result) {
        if (!empty($message_result->error)) {

          // If the device token is invalid or not registered (anymore because the user
          // has uninstalled the application), remove this device token.
          if ($message_result->error == 'NotRegistered' || $message_result->error == 'InvalidRegistration') {
            push_notifications_purge_token($bundle_tokens[$token_index], PUSH_NOTIFICATIONS_TYPE_ID_ANDROID);
            watchdog('push_notifications', 'GCM token not valid anymore. Removing token ' . $bundle_tokens[$token_index]);
          }
        }
      }
    }

    // Count the successful sent push notifications if there are any.
    if ($info['http_code'] == 200 && !empty($response->success)) {
      $result['count_success'] += $response->success;
    }
  }
  $result['message'] = t('Successfully sent !count_success Android push messages (attempted to send !count messages).', array(
    '!count_success' => $result['count_success'],
    '!count' => $result['count_attempted'],
  ));
  $result['success'] = TRUE;

  // Invoke rules.
  if (module_exists('rules')) {
    rules_invoke_event_by_args('push_notifications_after_gcm_send', array(
      'type_id' => PUSH_NOTIFICATIONS_TYPE_ID_ANDROID,
      'payload' => $payload,
      'count_attempted' => $result['count_attempted'],
      'count_success' => $result['count_success'],
      'success' => $result['success'],
      'result_message' => $result['message'],
    ));
  }
  return $result;
}