├── Gulpfile.js ├── LICENSE ├── README.md ├── composer.json ├── package.json └── src ├── Connection.php ├── Device.php ├── PHPushbullet.php └── Request ├── PushAddress.php ├── PushFile.php ├── PushLink.php ├── PushList.php ├── PushNote.php └── Request.php /Gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require("gulp"); 2 | var notify = require("gulp-notify"); 3 | var run = require("gulp-run"); 4 | var phpunit = require("gulp-phpunit"); 5 | 6 | gulp.task("tests", function () 7 | { 8 | gulp.src("./tests/PHPushbulletTest.php") 9 | .pipe( run("clear") ) 10 | .pipe( phpunit("phpunit", { 11 | debug: true, 12 | notify: true 13 | })) 14 | .on("error", function() { 15 | run("notify-send 'Tests Failed' 'Got some problems dude.'").exec(); 16 | }) 17 | .pipe( run("notify-send 'Tests Passed' 'Nailed it.'")); 18 | }); 19 | 20 | gulp.task("watch", function() 21 | { 22 | gulp.watch([ "./src/**/*.php", "./tests/**/*"], [ "tests" ]); 23 | }) 24 | 25 | gulp.task("default", [ "tests", "watch" ]); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Joe Tannenbaum 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHPushbullet 2 | 3 | [![Latest Version](https://img.shields.io/github/release/joetannenbaum/phpushbullet.svg?style=flat)](https://github.com/joetannenbaum/phpushbullet/releases) 4 | [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](LICENSE.md) 5 | [![Build Status](https://img.shields.io/travis/joetannenbaum/phpushbullet/master.svg?style=flat)](https://travis-ci.org/joetannenbaum/phpushbullet) 6 | [![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/joetannenbaum/phpushbullet.svg?style=flat)](https://scrutinizer-ci.com/g/joetannenbaum/phpushbullet/code-structure) 7 | [![Quality Score](https://img.shields.io/scrutinizer/g/joetannenbaum/phpushbullet.svg?style=flat)](https://scrutinizer-ci.com/g/joetannenbaum/phpushbullet) 8 | [![Total Downloads](https://img.shields.io/packagist/dt/joetannenbaum/phpushbullet.svg?style=flat)](https://packagist.org/packages/joetannenbaum/phpushbullet) 9 | 10 | A PHP library for the [Pushbullet](https://www.pushbullet.com/) API. 11 | 12 | ## Table of Contents 13 | 14 | + [Installation](#installation) 15 | + [Listing Devices](#listing-devices) 16 | + [Pushing](#pushing) 17 | + [To Devices](#to-devices) 18 | + [To Users](#to-users) 19 | + [Types](#types) 20 | + [Notes](#notes) 21 | + [Links](#links) 22 | + [Addresses](#addresses) 23 | + [Lists](#lists) 24 | + [Files](#files) 25 | 26 | ## Installation 27 | 28 | Using [composer](https://packagist.org/packages/joetannenbaum/phpushbullet): 29 | 30 | ``` 31 | { 32 | "require": { 33 | "joetannenbaum/phpushbullet": "~1.0" 34 | } 35 | } 36 | ``` 37 | 38 | PHPushbullet takes one optional parameter, your [Pushbullet access token](https://www.pushbullet.com/account): 39 | 40 | ```php 41 | require_once('vendor/autoload.php'); 42 | 43 | $pushbullet = new PHPushbullet\PHPushbullet('YOUR_ACCESS_TOKEN_HERE'); 44 | ``` 45 | 46 | If you do not wish to put your access token in your code (understandable), simply set it to the environment variable `pushbullet.access_token` and PHPushbullet will automatically pick it up. 47 | 48 | ## Listing Devices 49 | 50 | To list the available devices on your account: 51 | 52 | ```php 53 | $pushbullet->devices(); 54 | ``` 55 | 56 | This will return an array of objects with all of the device information. 57 | 58 | ## Pushing 59 | 60 | ### To Devices 61 | 62 | When pushing a to a device, simply use the device's `nickname` or their `iden` from the list above. 63 | 64 | To push to a single device: 65 | 66 | ```php 67 | $pushbullet->device('Chrome')->note('Remember', 'Buy some eggs.'); 68 | ``` 69 | 70 | To push to multiple devices: 71 | 72 | ```php 73 | $pushbullet->device('Chrome')->device('Galaxy S4')->note('Remember', 'Buy some eggs.'); 74 | // or 75 | $pushbullet->device('Chrome', 'Galaxy S4')->note('Remember', 'Buy some eggs.'); 76 | // or 77 | $pushbullet->device(['Chrome', 'Galaxy S4'])->note('Remember', 'Buy some eggs.'); 78 | ``` 79 | 80 | ### To Users 81 | 82 | When pushing a to a user, simply use the user's email address: 83 | 84 | To push to a single user: 85 | 86 | ```php 87 | $pushbullet->user('joe@example.com')->note('Remember', 'Buy some eggs.'); 88 | ``` 89 | 90 | To push to multiple users: 91 | 92 | ```php 93 | $pushbullet->user('joe@example.com')->user('anne@example.com')->note('Remember', 'Buy some eggs.'); 94 | // or 95 | $pushbullet->user('joe@example.com', 'anne@example.com')->note('Remember', 'Buy some eggs.'); 96 | // or 97 | $pushbullet->user(['joe@example.com', 'anne@example.com'])->note('Remember', 'Buy some eggs.'); 98 | ``` 99 | ## Types 100 | 101 | ### Notes 102 | 103 | Arguments: 104 | 105 | + Title 106 | + Body 107 | 108 | ```php 109 | $pushbullet->device('Chrome')->note('Musings', 'Why are fudgy brownies better than cakey brownies?'); 110 | ``` 111 | 112 | ### Links 113 | 114 | Arguments: 115 | 116 | + Title 117 | + URL 118 | + Body (optional) 119 | 120 | ```php 121 | $pushbullet->device('Chrome')->link('Look It Up', 'http://google.com', 'I hear this is a good site for finding things.'); 122 | ``` 123 | 124 | ### Addresses 125 | 126 | Arguments: 127 | + Name 128 | + Address 129 | 130 | ```php 131 | $pushbullet->device('Chrome')->address('The Hollywood Sign', '4059 Mt Lee Drive Hollywood, CA 90068'); 132 | ``` 133 | 134 | Alternatively, you can pass in an associative array: 135 | 136 | ```php 137 | $address = [ 138 | 'address' => '4059 Mt Lee Drive', 139 | 'city' => 'Hollywood', 140 | 'state' => 'CA', 141 | 'zip' => '90068', 142 | ]; 143 | 144 | $pushbullet->device('Chrome')->address('The Hollywood Sign', $address); 145 | ``` 146 | 147 | ### Lists 148 | 149 | Arguments: 150 | + Title 151 | + Items (array) 152 | 153 | ```php 154 | $items = [ 155 | 'Socks', 156 | 'Pants', 157 | 'Keys', 158 | 'Wallet', 159 | ]; 160 | 161 | $pushbullet->device('Chrome')->list('Do Not Forget', $items); 162 | ``` 163 | 164 | ### Files 165 | 166 | Arguments: 167 | + File Name 168 | + File URL (must be publicly available) 169 | + Body (optional) 170 | 171 | ```php 172 | $pushbullet->device('Chrome')->file('The Big Presentation', 'http://example.com/do-not-lose-this.pptx', 'Final version of slides.'); 173 | ``` 174 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "joetannenbaum/phpushbullet", 3 | "description": "PHP API wrapper for Pushbullet.", 4 | "keywords": [ "pushbullet", "php", "api", "push", "bullet", "notification" ], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Joe Tannenbaum", 9 | "email": "hey@joe.codes" 10 | } 11 | ], 12 | "require": { 13 | "php": ">=5.4.0", 14 | "guzzlehttp/guzzle": "~5.3|~6.0" 15 | }, 16 | "require-dev": { 17 | "phpunit/phpunit": "4.1.*" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "PHPushbullet\\": "src/" 22 | } 23 | }, 24 | "minimum-stability": "stable" 25 | } 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": {}, 3 | "repository": {}, 4 | "devDependencies": { 5 | "gulp": "^3.8.7", 6 | "gulp-notify": "^1.5.0", 7 | "gulp-phpunit": "^0.6.3", 8 | "gulp-run": "^1.6.4" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Connection.php: -------------------------------------------------------------------------------- 1 | client = $client ?: new Client($this->getClientParams($access_token, $config)); 27 | } 28 | 29 | /** 30 | * @return \GuzzleHttp\Client 31 | */ 32 | public function client() 33 | { 34 | return $this->client; 35 | } 36 | 37 | protected function getClientParams($access_token, array $config = []) 38 | { 39 | $headers = [ 40 | 'Access-Token' => $access_token, 41 | 'Content-Type' => 'application/json', 42 | ]; 43 | 44 | $config = array_merge(compact('headers'), $config); 45 | 46 | if (version_compare(Client::VERSION, 6, '>=')) { 47 | return array_merge([ 48 | 'base_uri' => $this->base_url, 49 | ], $config); 50 | } 51 | 52 | return [ 53 | 'base_url' => [$this->base_url, []], 54 | 'defaults' => $config, 55 | ]; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Device.php: -------------------------------------------------------------------------------- 1 | fields as $field) { 27 | $this->{$field} = $this->getFieldValue($attr, $field); 28 | } 29 | } 30 | 31 | /** 32 | * @param array $attr 33 | * @param string $field 34 | * 35 | * @return string 36 | */ 37 | protected function getFieldValue(array $attr, $field) 38 | { 39 | $method = 'set' . ucwords($field); 40 | 41 | if (method_exists($this, $method)) { 42 | // If there is a setter for this field, use that 43 | return $this->{$method}($attr[$field]); 44 | } 45 | 46 | // Otherwise just set the property 47 | return (isset($attr[$field])) ? $attr[$field] : null; 48 | } 49 | 50 | /** 51 | * Format the date so that it's readable 52 | * 53 | * @param integer $date 54 | * @return string 55 | */ 56 | 57 | protected function setCreated($date) 58 | { 59 | return date('Y-m-d h:i:sA T', $date); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/PHPushbullet.php: -------------------------------------------------------------------------------- 1 | api = $connection->client(); 62 | } 63 | 64 | /** 65 | * Get a list of all of the devices available 66 | * 67 | * @return array 68 | */ 69 | public function devices() 70 | { 71 | if (empty($this->all_devices)) { 72 | $response = $this->fromJson($this->api->get('devices')); 73 | 74 | $this->all_devices = array_map(function ($device) { 75 | return new Device($device); 76 | }, $response['devices']); 77 | } 78 | 79 | return $this->all_devices; 80 | } 81 | 82 | public function user() 83 | { 84 | $this->users = array_merge($this->argsToArray(func_get_args()), $this->users); 85 | $this->users = array_filter($this->users); 86 | $this->users = array_unique($this->users); 87 | 88 | return $this; 89 | } 90 | 91 | /** 92 | * Set the passed in device(s) for the current push 93 | * 94 | * @return \PHPushbullet\PHPushbullet 95 | */ 96 | public function device() 97 | { 98 | $devices = $this->argsToArray(func_get_args()); 99 | 100 | foreach ($devices as $destination) { 101 | $device = $this->getDeviceIden($destination); 102 | 103 | if (!$device) { 104 | throw new \Exception("{$destination} is not a valid device."); 105 | } 106 | 107 | $this->devices[] = $device; 108 | } 109 | 110 | return $this; 111 | } 112 | 113 | /** 114 | * Set the passed in channel(s) for the current push 115 | * 116 | * @return \PHPushbullet\PHPushbullet 117 | */ 118 | public function channel() 119 | { 120 | $this->channels = array_merge($this->argsToArray(func_get_args())); 121 | 122 | return $this; 123 | } 124 | 125 | /** 126 | * Set all of the devices for the current push 127 | * 128 | * @return \PHPushbullet\PHPushbullet 129 | */ 130 | public function all() 131 | { 132 | foreach ($this->devices() as $device) { 133 | if ($device->pushable == true) { 134 | $this->devices[] = $device->iden; 135 | } 136 | } 137 | 138 | return $this; 139 | } 140 | 141 | /** 142 | * Actually send the push 143 | * 144 | * @return array 145 | */ 146 | public function push($request) 147 | { 148 | if (empty($this->devices) && empty($this->users) && empty($this->channels)) { 149 | throw new \Exception('You must specify something to push to.'); 150 | } 151 | 152 | $responses = []; 153 | 154 | $destinations = [ 155 | 'devices' => 'device_iden', 156 | 'users' => 'email', 157 | 'channels' => 'channel_tag', 158 | ]; 159 | 160 | foreach ($destinations as $destination => $key) { 161 | foreach ($this->{$destination} as $dest) { 162 | $responses[] = $this->pushRequest($request, [$key => $dest]); 163 | } 164 | } 165 | 166 | $this->devices = []; 167 | $this->users = []; 168 | $this->channels = []; 169 | 170 | return $responses; 171 | } 172 | 173 | public function getClient() 174 | { 175 | return $this->api; 176 | } 177 | 178 | /** 179 | * Create push request and... push it 180 | * 181 | * @param array $request 182 | * @param array $merge 183 | * 184 | * @return array 185 | */ 186 | protected function pushRequest($request, $merge) 187 | { 188 | $request = array_merge($request, $merge); 189 | $response = $this->api->post('pushes', ['json' => $request]); 190 | 191 | return $this->fromJson($response); 192 | } 193 | 194 | /** 195 | * Get the `iden` for the device by either the iden or nickname 196 | * 197 | * @param string $device 198 | * 199 | * @return mixed (boolean|string) 200 | */ 201 | protected function getDeviceIden($device) 202 | { 203 | foreach ($this->devices() as $available_device) { 204 | foreach (['iden', 'nickname'] as $field) { 205 | if ($available_device->$field == $device) { 206 | return $available_device->iden; 207 | } 208 | } 209 | } 210 | 211 | return false; 212 | } 213 | 214 | /** 215 | * @param type $args 216 | * 217 | * @return array 218 | */ 219 | protected function argsToArray($args) 220 | { 221 | if (is_array($args[0])) { 222 | return $args[0]; 223 | } 224 | 225 | return $args; 226 | } 227 | 228 | protected function fromJson($response) 229 | { 230 | return json_decode((string) $response->getBody(), true); 231 | } 232 | 233 | /** 234 | * Magic method, figures out what sort of push the user is trying to do 235 | */ 236 | public function __call($method, $arguments) 237 | { 238 | $request_class = 'PHPushbullet\Request\Push' . ucwords($method); 239 | 240 | if (!class_exists($request_class)) { 241 | throw new \Exception(sprintf('Unknown method "%s"', $method)); 242 | } 243 | 244 | $class = new \ReflectionClass($request_class); 245 | $request = $class->newInstanceArgs($arguments); 246 | 247 | return $this->push($request->request()); 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /src/Request/PushAddress.php: -------------------------------------------------------------------------------- 1 | parameters['name'] = $name; 18 | $this->parameters['address'] = $this->setAddress($address); 19 | } 20 | 21 | /** 22 | * The address can either be a string or an array, 23 | * make sure it's a string in the end 24 | * 25 | * @param string|array $address 26 | * @return string 27 | */ 28 | 29 | protected function setAddress($address) 30 | { 31 | if (is_array($address)) { 32 | $new_address = []; 33 | 34 | foreach (['address', 'city', 'state', 'zip'] as $field) { 35 | if (array_key_exists($field, $address)) { 36 | $new_address[] = $address[$field]; 37 | } 38 | } 39 | 40 | $address = implode(' ', $new_address); 41 | } 42 | 43 | return $address; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Request/PushFile.php: -------------------------------------------------------------------------------- 1 | parameters['file_name'] = $file_name; 20 | $this->parameters['file_url'] = $file_url; 21 | $this->parameters['file_type'] = $this->getFileType($file_url); 22 | $this->parameters['body'] = $body; 23 | } 24 | 25 | /** 26 | * Get the file type based on the file url 27 | * 28 | * @param string $file_url 29 | * 30 | * @return string 31 | */ 32 | 33 | protected function getFileType($file_url) 34 | { 35 | $file_info = (new Client())->head($file_url); 36 | $file_type = $file_info->getHeader('content-type'); 37 | 38 | if (is_array($file_type)) { 39 | return reset($file_type); 40 | } 41 | 42 | return $file_type; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Request/PushLink.php: -------------------------------------------------------------------------------- 1 | parameters['title'] = $title; 18 | $this->parameters['url'] = $url; 19 | $this->parameters['body'] = $body; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Request/PushList.php: -------------------------------------------------------------------------------- 1 | parameters['title'] = $title; 18 | $this->parameters['items'] = $items; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Request/PushNote.php: -------------------------------------------------------------------------------- 1 | parameters['title'] = $title; 18 | $this->parameters['body'] = $body; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Request/Request.php: -------------------------------------------------------------------------------- 1 | $this->type], $this->parameters); 26 | } 27 | } 28 | --------------------------------------------------------------------------------