Integration von Pushbullet.com?

Hallo,

hat schon jemand den Dienst Pushbullet integriert?

Pushbullet - Your devices working better together

Hab den gerade durch Zufall entdeckt. Praktisch finde ich z.B. die Möglichkeit auch Anhänge also z.B. Fotos zu Pushen. Gut für Alarmmeldungen bei Überwachungskameras etc…

Eine API gibts auch:
API

und eine php lib ebenfalls:
PHP Lib

Schöne Grüße
Stephan

Hallo Stephan,

ich hab mit Pushbullet schon mal ein wenig rumgespielt. Die Implementierung ist aber schon über 1 Jahr alt.
Könnte sein, dass sich an der API etwas verändert hat.

Folgendes Script habe ich im Skripte-Ordner reingelegt mit dem Namen
„__pushBullet.inc.php“.

<?php


class PushBulletException extends Exception {
  // Exception thrown by PushBullet
}


class PushBullet {
  public function __construct($secret) {
    // Check if cURL is loaded
    if (!function_exists('curl_init')) {
      throw new PushBulletException('cURL library is not loaded.');
    }


    $this->_apiKey = $secret;


    // Get all devices associated with the API key.
    // This is also a more reliable way of API key validation.
    $curl = curl_init();


    curl_setopt($curl, CURLOPT_URL, self::API_HOST . '/devices');
    curl_setopt($curl, CURLOPT_USERPWD, $this->_apiKey);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($curl);


    if ($response === false) {
      throw new PushBulletException('cURL Error: ' . curl_error($curl));
    }


    $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);


    if ($httpCode != 200) {
      throw new PushBulletException('Unable to authenticate. HTTP Error ' . $this->_pushBulletErrors[$httpCode]);
    }


    // Check PHP version to determine whether a JSON big int workaround should be used
    if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
      $this->_allDevices = json_decode($response, true, 512, JSON_BIGINT_AS_STRING);
    } else {
      $this->_allDevices = json_decode(preg_replace('/\"([a-zA-Z0-9_]+)\":\s?(\d{14,})/', '"${1}":"${2}"', $response), true);
    }


    if ($this->_allDevices) {
      $this->_myDevices = $this->_allDevices['devices'];
      $this->_sharedDevices = $this->_allDevices['shared_devices'];
    } else {
      throw new PushBulletException('Unable to decode JSON response.');
    }
  }


  public function getDevices() {
    return $this->_allDevices;
  }


  public function getMyDevices() {
    return $this->_myDevices;
  }


  public function getSharedDevices() {
    return $this->_sharedDevices;
  }


  public function pushNote($devices, $title, $body) {
    return $this->_push($devices, 'note', $title, $body);
  }


  public function pushAddress($devices, $name, $address) {
    return $this->_push($devices, 'address', $name, $address);
  }


  public function pushList($devices, $title, $items) {
    return $this->_push($devices, 'list', $title, $items);
  }


  public function pushFile($devices, $fileName) {
    return $this->_push($devices, 'file', $fileName, NULL);
  }


  public function pushLink($devices, $title, $url)
  {
    return $this->_push($devices, 'link', $title, $url);
  }




  const API_HOST = 'https://api.pushbullet.com/api';
  private $_apiKey;
  private $_allDevices;
  private $_myDevices;
  private $_sharedDevices;


  private $_pushBulletErrors = array(
    400 => '400 Bad Request. Missing a required parameter.',
    401 => '401 Unauthorized. No valid API key provided.',
    402 => '402 Request Failed.',
    403 => '403 Forbidden. The API key is not valid for that request.',
    404 => '404 Not Found. The requested item doesn\'t exist.',
    500 => '500 Internal Server Error.',
    502 => '502 Bad Gateway.',
    503 => '503 Service Unavailable.',
    504 => '504 Gateway Timeout.'
  );


  private function _buildCurlQuery($deviceId, $type, $primary, $secondary) {
    switch ($type) {
      case 'note':
        if (empty($primary) && !empty($secondary)) {
          // PushBullet doesn't set a placeholder title if it's not supplied, so we have to.
          $primary = 'Note';
        } else if (empty($primary) && empty($secondary)) {
          throw new PushBulletException('Note: No title and body supplied.');
        }


        $queryData = http_build_query(array(
          'device_iden' => $deviceId,
          'type' => 'note',
          'title' => $primary,
          'body' => $secondary
        ));
      break;


      case 'address':
        if (!$secondary) {
          throw new PushBulletException('Address: No address supplied.');
        }


        $queryData = http_build_query(array(
          'device_iden' => $deviceId,
          'type' => 'address',
          'name' => $primary,
          'address' => $secondary
        ));
      break;


      case 'list':
        if (empty($primary) && !empty($secondary)) {
          // PushBullet doesn't set a placeholder title if it's not supplied.
          $primary = 'List';
        }
        else if (empty($secondary)) {
          // PushBullet accepts absolutely empty to-do lists, but there's no point.
          throw new PushBulletException('List: No items supplied.');
        }


        $queryData = http_build_query(array(
          'device_iden' => $deviceId,
          'type' => 'list',
          'title' => $primary,
          'items' => $secondary
        ));


        // Remove array keys in square brackets
        $queryData = preg_replace('/%5B[0-9]+%5D/i', '', $queryData);
      break;


      case 'file':
        $fullFilePath = realpath($primary);


        if (!is_readable($fullFilePath)) {
          throw new PushBulletException('File: File does not exist or is unreadable.');
        }


        if (filesize($fullFilePath) > 25*1024*1024) {
          throw new PushBulletException('File: File size exceeds 25 MB.');
        }


        $queryData = array(
          'device_iden' => $deviceId,
          'type' => 'file',
          'file' => '@' . $fullFilePath . ';filename=' . basename($fullFilePath)
        );
      break;


      case 'link':
        if (empty($secondary)) {
          throw new PushBulletException('Link: No URL supplied.');
        }
        $queryData = http_build_query(array(
          'device_iden' => $deviceId,
          'type' => 'link',
          'title' => $primary,
          'url' => $secondary
        ));
    }


    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, self::API_HOST . '/pushes');
    curl_setopt($curl, CURLOPT_USERPWD, $this->_apiKey);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $queryData);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($curl);


    if ($response === false) {
      throw new PushBulletException('cURL Error: ' . curl_error($curl));
    }


    $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);


    if ($httpCode >= 400) {
      throw new PushBulletException('Push failed for device ' . $deviceId . '. HTTP Error ' . $this->_pushBulletErrors[$httpCode]);
    }


    return true;
  }


  private function _push($pushTo, $pushType, $primary, $secondary) {
    if (empty($this->_allDevices)) {
      throw new PushBulletException('Push: No devices found.');
    }


    if (is_string($pushTo) && $pushTo != 'all' && $pushTo != 'my' && $pushTo != 'shared') {
      return $this->_buildCurlQuery($pushTo, $pushType, $primary, $secondary);
    } else if (is_array($pushTo)) {
      // Push to multiple devices in an array.


      // Check if the device ID is in the list of devices we have permissions to push to.
      $failedDevices = array();
      foreach ($pushTo as $device) {
        if ($this->_in_array($device, $this->_allDevices)) {
          $this->_buildCurlQuery($device, $pushType, $primary, $secondary);
        } else {
          $failedDevices[] = $device;
        }
      }


      if (!empty($failedDevices)) {
        throw new PushBulletException('Push failed for devices: ' . implode(', ', $failedDevices));
      }
    } else if ($pushTo == 'all' || $pushTo == 'my' || $pushTo == 'shared') {
      // Push to my devices, if any.
      if (($pushTo == 'all' || $pushTo == 'my') && !empty($this->_myDevices)) {
        foreach ($this->_myDevices as $myDevice) {
          $this->_buildCurlQuery($myDevice['iden'], $pushType, $primary, $secondary);
        }
      } else if ($pushTo == 'my' && empty($this->_myDevices)) {
        throw new PushBulletException('Push: No own devices found.');
      }


      // Push to shared devices, if any.
      if (($pushTo == 'all' || $pushTo == 'shared') && !empty($this->_sharedDevices)) {
        foreach ($this->_sharedDevices as $sharedDevice) {
          $this->_buildCurlQuery($sharedDevice['iden'], $pushType, $primary, $secondary);
        }
      } else if ($pushTo == 'shared' && empty($this->_sharedDevices)) {
        throw new PushBulletException('Push: No shared devices found.');
      }
    } else {
      throw new PushBulletException('Push: Invalid device definition (' . $pushTo . ').');
    }


    return true;
  }


  // Multidimensional in_array()
  private function _in_array($needle, $haystack, $strict = false) {
    if (is_array($haystack)) {
      foreach ($haystack as $item) {
        if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && $this->_in_array($needle, $item, $strict))) {
          return true;
        }
      }
    }


    return false;
  }
}


function IPS_PushBullet($type, $device, $d) {
  #### AUTHENTICATION ####
  // Get your API key here: https://www.pushbullet.com/account
  $p = new PushBullet('#################### API-Key ######################## ');






  #### LIST OF DEVICES ####
  #### These methods return arrays containing device definitions, or NULL if there are no devices.
  #### Use them to get 'device_iden' which is a unique ID for every device and is used with push methods below.




  // Print an array containing all available devices (including other people's devices shared with you).
  //print_r($p->getDevices());


  // Print an array with your own devices
   print_r($p->getMyDevices());


  // Print an array with devices shared with you
  //print_r($p->getSharedDevices());
//exit;


// Hier habe ich die Geräte definiert, welche ich ansprechen kann.
Die ### IDen ### kannst du dir ausgeben lassen mit  // print_r($p->getMyDevices());


$g["Handy1"] = "### IDen ###";
$g["Handy2"] = "### IDen ###";





// hier reagiert das skript auf den Typ. Habe momentan nur "note" integriert. Ist ja aber beliebig erweiterbar.
switch ( $type ) {


    case "note":
         $p->pushNote($g[$device], $d["title"], $d["content"]);
    break;




}


//exit;
// $p->pushNote($g["nexus"], 'Title', 'It works!');
// $p->pushAddress($g["arbeit"], 'Google HQ', '1600 Amphitheatre Parkway');
// $p->pushList($g["arbeit"], 'Shopping List', array('Milk', 'Butter'));
//  $p->pushFile($g["nexus"], 'image/pic.jpg');
// $p->pushLink($g["arbeit"], 'ivkos at GitHub', 'https://github.com/ivkos');




/*
  #### PUSHING TO A SINGLE DEVICE ####
  #### Methods return TRUE on success, or throw an exception on failure.


  // Push to device s2GBpJqaq9IzY5nx a note with a title 'Hey!' and a body 'It works!'
  $p->pushNote('s2GBpJqaq9IzY5nx', 'Hey!', 'It works!');


  // Push to device a91kkT2jIICzD4JH a Google Maps address with a title 'Google HQ' and an address '1600 Amphitheatre Parkway'
  $p->pushAddress('a91kkT2jIIzCD4JH', 'Google HQ', '1600 Amphitheatre Parkway');


  // Push to device qVNRhnXzxZzzJ95zz a to-do list with a title 'Shopping List' and items 'Milk' and 'Butter'
  $p->pushList('qVNRhnXxZzJz95zz', 'Shopping List', array('Milk', 'Butter'));


  // Push to device 0PpyWzAzRDK0w6et the file '../pic.jpg'.
  // Method accepts absolute and relative paths.
  $p->pushFile('0PpyWzARzDK0w6et', '../pic.jpg');


  // Push to device gXVZDd2hLY6TOB1 a link with a title 'ivkos at GitHub' and a URL 'https://github.com/ivkos'
  $p->pushLink('gXVZDd2hLY6TOB1', 'ivkos at GitHub', 'https://github.com/ivkos');






  #### PUSHING TO MULTIPLE DEVICES ####


  // Push to all available devices
  $p->pushNote('all', 'Some title', 'Some text');


  // Push to all of your own devices
  $p->pushList('my', 'Buy these', array('PHP for Dummies', 'New charger'));


  // Push to all devices shared with you
  $p->pushAddress('shared', "Let's meet here", 'The Lake, Central Park, NY');


  // Push to multiple devices defined by their IDs
  // When pushing to multiple device IDs, some of them might fail. If so, an exception saying
  // which devices have failed will be thrown. If a device ID isn't in the message, it means push is successful.
  $p->pushLink(array('5ZUC8hKOqLU0Jv7', 'SwZLKGn6M0fe7tO', 'tc7JSzKJLGLcKII'), 'Check this out!', 'http://youtu.be/dQw4w9WgXcQ');


 */


}
?>


In diesem Skript muss man jetzt noch seinen API-Key (#################### API-Key ########################) eintragen
und die Device-Ids (### IDen ###) holen und mappen.

Diese Datei habe ich dann im Skript __autoinclude.inc.php mit hinzugefügt.

if(file_exists(IPS_GetKernelDir()."\\scripts\\__pushBullet.inc.php")) 
    require_once(IPS_GetKernelDir()."\\scripts\\__pushBullet.inc.php");    

Jetzt solltes du in jedem Script diese Funktion nutzen können.

$d["title"]   = "Bewegung";
$d["content"] = "vor der Haustuer ". date("Y-m-d H:i:s");


IPS_PushBullet("note", "Handy1", $d );

Gruß
Christian

super, werde ich am WE mal testen.

Danke!

Gruß Stephan

Vielen Dank Euch beiden für den Tipp und den Quelltext. Funktioniert auch auf dem Raspberry prima.

Eine Kleinigkeit: In __pushBullet.inc.php muss noch eine Zeile auskommentiert werden:

// Hier habe ich die Geräte definiert, welche ich ansprechen kann.
// Die ### IDen ### kannst du dir ausgeben lassen mit // print_r($p->getMyDevices());

Auf dem Raspberry sieht die Ergänzung in /etc/symcon/scripts/__autoinclude.inc.php folgendermaßen aus:

if(file_exists(IPS_GetKernelDir(). „/scripts/__pushBullet.inc.php“))
require_once(IPS_GetKernelDir()."/scripts/__pushBullet.inc.php");

sofern die Datei __pushBullet.inc.php unter /usr/share/symcon/scripts abgelegt ist.

Gruß
Peter

Hallo zusammen,

habe das Script eben auch getestet.
Zeile auskommentiert und meinen APIKey eingetragen.
Leider bekomme ich dann folgende Fehlermeldung im IPS Script.

Fatal error: Uncaught exception ‚PushBulletException‘ with message ‚cURL Error: SSL certificate problem: unable to get local issuer certificate‘ in C:\IP-Symcon\scripts__pushBullet.inc.php:33
Stack trace:

hat jemand von euch eine Idee woran das liegen könnte?

Viele Grüße
Chris

Moin!

Klingt irgendwie nach dem üblichen SSL Problem!? Sprich…SSL Version austauschen…

Openssl mal wieder

Grüße,
Chris

Ich habs jetzt mal so gelöst und damit Zertifikatsvalidierung deaktiviert.

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

Da ich jedoch beruflich täglich mit Zertifikaten zu tun habe finde ich diesen Workaround nicht wirklich toll und werde mal das testen.

http://christ.media/ssl-certificate-problem-unable-get-local-issuer-certificate-howto/

Soweit funktioniert es. Ich werde jetzt noch versuchen Fotos zu verschicken. Damit ich ein Foto meiner Webcam an der Haustüre verschicken kann wenn jemand klingelt.

Vielen Dank und viele Grüße
Chris

Hallo,

hatte bis vor ca. 2-3 Monaten pushbullet mit IP-Symcon erfolgreich im Einsatz um Bilder meiner Türklingel zu versenden.
Jedoch funktioniert jetzt das Versenden von Bildern nicht mehr.
Vielleicht hatte ja jemand dasselbe Problem und dieses auch erfolgreich gelöst.
Wäre für jede Hilfe dankbar :wink:

Daniel

hallo Leute!

Frage … funktioniert bei euch noch das Pushbullet ? … hab das Skript installiert aber bekomme immer wieder Fehler.

Parse error: syntax error, unexpected ‚$g‘ (T_VARIABLE) in C:\IP-Symcon\scripts__pushBullet.inc.php on line 351
Abort Processing during Fatal-Error: syntax error, unexpected ‚$g‘ (T_VARIABLE)
Error in Script C:\IP-Symcon\scripts__pushBullet.inc.php on Line 351

könnt ihr mir da weiter helfen?

vielen Dank!

lg
Christian