gopush/pushbullet/pushbullet.go

195 lines
3.8 KiB
Go

package pushbullet
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const (
host = "https://api.pushbullet.com/v2"
)
func New(apiKey string) PushBullet {
return PushBullet{apiKey: apiKey}
}
type PushBullet struct {
apiKey string
client *http.Client
ActiveDevice Device
Devices []Device
}
// Loads all devices for account into instance
func (pb *PushBullet) LoadDevices() []Device {
dl := new(DeviceList)
err := pb.pbRequest("GET", host+"/devices", nil, dl)
if err != nil {
fmt.Println("error on pbRequest")
fmt.Println(err)
}
pb.Devices = dl.Devices
return dl.Devices
}
// Lazy loaded version of LoadDevices
func (pb *PushBullet) GetDevices() []Device {
if len(pb.Devices) == 0 {
pb.LoadDevices()
}
return pb.Devices
}
func (pb PushBullet) PushNote(message string) {
body := map[string]interface{}{
"type": "note",
"body": message,
}
pb.Push(body)
}
func (pb PushBullet) PushLink(title string, url string) {
pb.PushLinkWithBody(title, url, "")
}
func (pb PushBullet) PushLinkWithBody(title string, url string, messBody string) {
body := map[string]interface{}{
"type": "link",
"title": title,
"url": url,
"body": messBody,
}
pb.Push(body)
}
// Pushes a text message to active device
// TODO: handle response
func (pb PushBullet) Push(body map[string]interface{}) {
body["device_iden"] = pb.ActiveDevice.Iden
result := new(interface{})
pb.pbRequest("POST", host+"/pushes", body, result)
}
// Sets active device by Nickname or Iden
func (pb *PushBullet) SetActiveDevice(key string) {
if len(pb.Devices) == 0 {
pb.LoadDevices()
}
for _, d := range pb.Devices {
if d.Match(key) && d.CanPush() {
pb.ActiveDevice = d
}
}
}
// Method for communicating with PushBullet
func (pb *PushBullet) pbRequest(method string, url string, body map[string]interface{}, result interface{}) error {
if pb.client == nil {
pb.client = &http.Client{}
}
jsonBody, err := json.Marshal(body)
if err != nil {
fmt.Println("Error marshalling body")
fmt.Println(err)
}
r, err := http.NewRequest(method, url, bytes.NewBuffer(jsonBody))
if err != nil {
fmt.Println("Error on request create")
return err
}
r.Header.Add("Content-Type", "application/json")
r.Header.Add("Application-Type", "application/json")
r.Header.Add("User-Agent", "gopush")
r.SetBasicAuth(pb.apiKey, "")
resp, err := pb.client.Do(r)
if err != nil {
fmt.Println("Error on request do")
fmt.Println(err)
return err
}
defer resp.Body.Close()
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error on request read")
return err
}
err = json.Unmarshal(responseBody, result)
return err
}
// Response types
type DeviceList struct {
Aliases []interface{}
Clients []interface{}
Devices []Device
Grants []interface{}
Pushes []interface{}
}
type DeviceFingerprint struct {
mac_address string
android_id string
}
type Device struct {
Iden string
Created float32
Nickname string
Modified float32
Push_token string
Fingerprint string
Active bool
Model string
App_version int32
Type string
Kind string
Pushable bool
Manufacturer string
}
// Returns Android Fingerprint
func (d Device) AndroidFingerprint() (DeviceFingerprint, error) {
fp := new(DeviceFingerprint)
err := json.Unmarshal([]byte(d.Fingerprint), fp)
return *fp, err
}
// Returns if the device is available for pushing
func (d Device) CanPush() bool {
return d.Active && d.Pushable
}
// Outputs the device in a friendly string format
func (d Device) Format() string {
return fmt.Sprintf("%s (%s)", d.Nickname, d.Kind)
}
// Returns true if key matches Nickname or Iden
func (d Device) Match(key string) bool {
if d.Nickname == key || d.Iden == key {
return true
}
return false
}