├── pushbullet_test.go ├── .gitignore ├── requests ├── pushes_test.go ├── requests.go └── pushes.go ├── responses ├── responses_test.go ├── responses.go ├── devices.go ├── upload_request.go ├── users_me.go └── pushes.go ├── goveralls.bash ├── endpoints.go ├── wercker.yml ├── coverage.bash ├── users_me.go ├── devices.go ├── LICENSE.txt ├── pushbullet.go ├── multipart.go ├── README.md ├── upload.go └── pushes.go /pushbullet_test.go: -------------------------------------------------------------------------------- 1 | package pushbullet 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | coverprofile/ 4 | -------------------------------------------------------------------------------- /requests/pushes_test.go: -------------------------------------------------------------------------------- 1 | package requests 2 | -------------------------------------------------------------------------------- /responses/responses_test.go: -------------------------------------------------------------------------------- 1 | package responses 2 | -------------------------------------------------------------------------------- /responses/responses.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package "responses" provides structs to represent the response of Pushbullet HTTP API. 3 | */ 4 | package responses 5 | -------------------------------------------------------------------------------- /goveralls.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | profile=coverprofile/gover.coverprofile 4 | service=wercker.com 5 | 6 | goveralls -coverprofile ${profile} -service ${service} -repotoken ${COVERALLS_TOKEN} 7 | -------------------------------------------------------------------------------- /requests/requests.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package "request" provides structs to represent the request for Pushbullet HTTP API. 3 | 4 | This packages contains types of "push". 5 | See the API documentation for the details: https://docs.pushbullet.com/#pushes 6 | */ 7 | package requests 8 | -------------------------------------------------------------------------------- /endpoints.go: -------------------------------------------------------------------------------- 1 | package pushbullet 2 | 3 | const ( 4 | _BASE_URL = "https://api.pushbullet.com" 5 | ENDPOINT_DEVICES = _BASE_URL + "/v2/devices" 6 | ENDPOINT_PUSHES = _BASE_URL + "/v2/pushes" 7 | ENDPOINT_UPLOADREQ = _BASE_URL + "/v2/upload-request" 8 | ENDPOINT_USERS_ME = _BASE_URL + "/v2/users/me" 9 | ) 10 | -------------------------------------------------------------------------------- /wercker.yml: -------------------------------------------------------------------------------- 1 | box: mitsuse/golang 2 | build: 3 | steps: 4 | - setup-go-workspace 5 | - script: 6 | name: build 7 | code: | 8 | go get -t ./... 9 | - script: 10 | name: coverage 11 | code: | 12 | bash coverage.bash 13 | bash goveralls.bash 14 | after-steps: 15 | - mitsuse/bullet-send: 16 | title: "${WERCKER_GIT_REPOSITORY} - Build ${WERCKER_RESULT}." 17 | path: "${WERCKER_BUILD_URL}" 18 | -------------------------------------------------------------------------------- /responses/devices.go: -------------------------------------------------------------------------------- 1 | package responses 2 | 3 | type Device struct { 4 | Iden string `json:"iden"` 5 | PushToken string `json:"push_token"` 6 | FinderPrint string `jsonL"fingerprint"` 7 | Nickname string `json:"nickname"` 8 | Manufacturer string `json:"manufacturer"` 9 | Type string `json:"type"` 10 | Model string `json:"model"` 11 | AppVersion int `json:"app_version"` 12 | Created float64 `json:"created"` 13 | Modified float64 `json:"modified"` 14 | Active bool `json:"active"` 15 | Pushable bool `json:"pushable"` 16 | } 17 | -------------------------------------------------------------------------------- /responses/upload_request.go: -------------------------------------------------------------------------------- 1 | package responses 2 | 3 | type Upload struct { 4 | Data *UploadData `json:"data"` 5 | FileName string `json:"file_name"` 6 | FileType string `json:"file_type"` 7 | FileUrl string `json:"file_url"` 8 | UploadUrl string `json:"upload_url"` 9 | } 10 | 11 | type UploadData struct { 12 | Acl string `json:"acl"` 13 | AwsAccessKeyId string `json:"awsaccesskeyid"` 14 | ContentType string `json:"content-type"` 15 | Key string `json:"key"` 16 | Policy string `json:"policy"` 17 | Signature string `json:"signature"` 18 | } 19 | -------------------------------------------------------------------------------- /coverage.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | base_package=github.com/mitsuse/pushbullet-go 4 | base_path=${GOPATH}/src/${base_package} 5 | 6 | package_list=( 7 | ${base_package} 8 | ${base_package}/requests 9 | ${base_package}/responses 10 | ) 11 | 12 | if [ ! -d ${base_path}/coverprofile ] 13 | then 14 | mkdir ${base_path}/coverprofile 15 | else 16 | rm ${base_path}/coverprofile/*.coverprofile 17 | fi 18 | 19 | for package in ${package_list[@]} 20 | do 21 | cover_name=$(echo ${package} | sed -e "s/\//__/g").coverprofile 22 | cover_path=${base_path}/coverprofile/${cover_name} 23 | go test -covermode=count -coverprofile ${cover_path} ${package} 24 | done 25 | 26 | cd ${base_path}/coverprofile && gover 27 | -------------------------------------------------------------------------------- /responses/users_me.go: -------------------------------------------------------------------------------- 1 | package responses 2 | 3 | type User struct { 4 | Iden string `json:"iden"` 5 | Email string `json:"email"` 6 | EmailNormalized string `json:"email_normalized"` 7 | Name string `json:"name"` 8 | ImageUrl string `json:"image_url"` 9 | Created float64 `json:"created"` 10 | Modified float64 `json:"modified"` 11 | Preferences *Preferences `json:"preferences"` 12 | } 13 | 14 | type Preferences struct { 15 | OnBoarding *OnBoarding `json:"onboarding"` 16 | Social bool `json:"social"` 17 | } 18 | 19 | type OnBoarding struct { 20 | App bool `json:"app"` 21 | Friends bool `json:"friends"` 22 | Extension bool `json:"extension"` 23 | } 24 | -------------------------------------------------------------------------------- /users_me.go: -------------------------------------------------------------------------------- 1 | package pushbullet 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "net/http" 7 | 8 | "github.com/mitsuse/pushbullet-go/responses" 9 | ) 10 | 11 | // Get the current user. 12 | func (pb *Pushbullet) GetUsersMe() (*responses.User, error) { 13 | req, err := http.NewRequest("GET", ENDPOINT_USERS_ME, nil) 14 | if err != nil { 15 | return nil, err 16 | } 17 | 18 | req.SetBasicAuth(pb.token, "") 19 | 20 | res, err := pb.client.Do(req) 21 | if err != nil { 22 | return nil, err 23 | } 24 | 25 | // TODO: Return an error value with human friendly message. 26 | if res.StatusCode != 200 { 27 | return nil, errors.New(res.Status) 28 | } 29 | 30 | var me *responses.User 31 | 32 | decoder := json.NewDecoder(res.Body) 33 | if err := decoder.Decode(&me); err != nil { 34 | return nil, err 35 | } 36 | 37 | return me, nil 38 | } 39 | -------------------------------------------------------------------------------- /devices.go: -------------------------------------------------------------------------------- 1 | package pushbullet 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "net/http" 7 | 8 | "github.com/mitsuse/pushbullet-go/responses" 9 | ) 10 | 11 | // Get the devices thath can be pushed to. 12 | func (pb *Pushbullet) GetDevices() ([]*responses.Device, error) { 13 | req, err := http.NewRequest("GET", ENDPOINT_DEVICES, nil) 14 | if err != nil { 15 | return nil, err 16 | } 17 | 18 | req.SetBasicAuth(pb.token, "") 19 | 20 | res, err := pb.client.Do(req) 21 | if err != nil { 22 | return nil, err 23 | } 24 | 25 | // TODO: Return an error value with human friendly message. 26 | if res.StatusCode != 200 { 27 | return nil, errors.New(res.Status) 28 | } 29 | 30 | var devices *devicesResponse 31 | 32 | decoder := json.NewDecoder(res.Body) 33 | if err := decoder.Decode(&devices); err != nil { 34 | return nil, err 35 | } 36 | 37 | return devices.Devices, nil 38 | } 39 | 40 | type devicesResponse struct { 41 | Devices []*responses.Device `json:"devices"` 42 | } 43 | -------------------------------------------------------------------------------- /responses/pushes.go: -------------------------------------------------------------------------------- 1 | package responses 2 | 3 | import ( 4 | "github.com/mitsuse/pushbullet-go/requests" 5 | ) 6 | 7 | type Push struct { 8 | Iden string `json:"iden"` 9 | Created float64 `json:"created"` 10 | Modified float64 `json:"modified"` 11 | Active bool `json:"active"` 12 | Dismissed bool `json:"dismissed"` 13 | SenderIden string `json:"sender_iden"` 14 | SenderEmail string `json:"sender_email"` 15 | SenderEmailNormalized string `json:"sender_email_normalized"` 16 | RecieverIden string `json:"reciever_iden"` 17 | RecieverEmail string `json:"reciever_email"` 18 | RecieverEmailNormalized string `json:"reciever_email_normalized"` 19 | } 20 | 21 | type Note struct { 22 | *Push 23 | *requests.Note 24 | } 25 | 26 | type Link struct { 27 | *Push 28 | *requests.Link 29 | } 30 | 31 | type Address struct { 32 | *Push 33 | *requests.Address 34 | } 35 | 36 | type Checklist struct { 37 | *Push 38 | *requests.Checklist 39 | } 40 | 41 | type File struct { 42 | *Push 43 | *requests.File 44 | } 45 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Tomoya Kose. 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /pushbullet.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package "pushbullet" provides interfaces for Pushbullet HTTP API. 3 | 4 | Pushbullet is a web service, 5 | which makes your devices work better together by allowing you to move things between them easily. 6 | 7 | The official url: https://www.pushbullet.com/ 8 | 9 | Currently, this package supports only "pushes" except file. 10 | 11 | See the API documentation for the details: https://docs.pushbullet.com/#http 12 | */ 13 | package pushbullet 14 | 15 | import ( 16 | "net/http" 17 | ) 18 | 19 | type Pushbullet struct { 20 | client *http.Client 21 | token string 22 | } 23 | 24 | /* 25 | Create a client to call Pushbullet HTTP API. 26 | This requires the access token. 27 | The token is found in account settings. 28 | 29 | Account settings: https://www.pushbullet.com/account 30 | */ 31 | func New(token string) *Pushbullet { 32 | return NewClient(token, http.DefaultClient) 33 | } 34 | 35 | /* 36 | Create a client to call Pushbullet HTTP API. 37 | This requires the access token and an aribitary *http.Client. 38 | The token is found in account settings. 39 | 40 | Account settings: https://www.pushbullet.com/account 41 | */ 42 | func NewClient(token string, c *http.Client) *Pushbullet { 43 | pb := &Pushbullet{ 44 | token: token, 45 | client: c, 46 | } 47 | 48 | return pb 49 | } 50 | 51 | func (pb *Pushbullet) Client() *http.Client { 52 | return pb.client 53 | } 54 | -------------------------------------------------------------------------------- /requests/pushes.go: -------------------------------------------------------------------------------- 1 | package requests 2 | 3 | const ( 4 | TYPE_NOTE = "note" 5 | TYPE_LINK = "link" 6 | TYPE_ADDRESS = "address" 7 | TYPE_CHEKCKLIST = "list" 8 | TYPE_FILE = "file" 9 | ) 10 | 11 | type Push struct { 12 | Type string `json:"type"` 13 | DeviceIden string `json:"device_iden,omitempty"` 14 | Email string `json:"email,omitempty"` 15 | ChannelTag string `json:"channel_tag,omitempty"` 16 | ClientIden string `json:"client_iden,omitempty"` 17 | } 18 | 19 | type Note struct { 20 | *Push 21 | Title string `json:"title"` 22 | Body string `json:"body"` 23 | } 24 | 25 | func NewNote() *Note { 26 | p := &Push{ 27 | Type: TYPE_NOTE, 28 | } 29 | 30 | return &Note{Push: p} 31 | } 32 | 33 | type Link struct { 34 | *Push 35 | Title string `json:"title"` 36 | Body string `json:"body"` 37 | Url string `json:"url"` 38 | } 39 | 40 | func NewLink() *Link { 41 | p := &Push{ 42 | Type: TYPE_LINK, 43 | } 44 | 45 | return &Link{Push: p} 46 | } 47 | 48 | type Address struct { 49 | *Push 50 | Name string `json:"name"` 51 | Address string `json:"address"` 52 | } 53 | 54 | func NewAddress() *Address { 55 | p := &Push{ 56 | Type: TYPE_ADDRESS, 57 | } 58 | 59 | return &Address{Push: p} 60 | } 61 | 62 | type Checklist struct { 63 | *Push 64 | Title string `json:"title"` 65 | ItemSeq []string `json:"items"` 66 | } 67 | 68 | func NewChecklist() *Checklist { 69 | p := &Push{ 70 | Type: TYPE_CHEKCKLIST, 71 | } 72 | 73 | return &Checklist{Push: p} 74 | } 75 | 76 | type File struct { 77 | *Push 78 | Title string `json:"title"` 79 | Body string `json:"body"` 80 | FileName string `json:"file_name"` 81 | FileUrl string `json:"file_url"` 82 | FileType string `json:"file_type"` 83 | } 84 | 85 | func NewFile() *File { 86 | p := &Push{ 87 | Type: TYPE_FILE, 88 | } 89 | 90 | return &File{Push: p} 91 | } 92 | -------------------------------------------------------------------------------- /multipart.go: -------------------------------------------------------------------------------- 1 | package pushbullet 2 | 3 | import ( 4 | "io" 5 | "mime/multipart" 6 | "net/textproto" 7 | ) 8 | 9 | type multipartWriter struct { 10 | writer *multipart.Writer 11 | err error 12 | } 13 | 14 | func newMultipartWriter(writer io.Writer) *multipartWriter { 15 | m := &multipartWriter{ 16 | writer: multipart.NewWriter(writer), 17 | } 18 | 19 | return m 20 | } 21 | 22 | func (m *multipartWriter) Error() error { 23 | return m.err 24 | } 25 | 26 | func (m *multipartWriter) Boundary() string { 27 | return m.writer.Boundary() 28 | } 29 | 30 | func (m *multipartWriter) Close() error { 31 | return m.writer.Close() 32 | } 33 | 34 | func (m *multipartWriter) CreateFormField(fieldname string) (io.Writer, error) { 35 | if m.err != nil { 36 | return nil, m.err 37 | } 38 | 39 | fw, err := m.writer.CreateFormField(fieldname) 40 | m.err = err 41 | 42 | return fw, err 43 | } 44 | 45 | func (m *multipartWriter) CreateFormFile(fieldname, filename string) (io.Writer, error) { 46 | if m.err != nil { 47 | return nil, m.err 48 | } 49 | 50 | fw, err := m.writer.CreateFormFile(fieldname, filename) 51 | m.err = err 52 | 53 | return fw, err 54 | } 55 | 56 | func (m *multipartWriter) CreatePart(header textproto.MIMEHeader) (io.Writer, error) { 57 | if m.err != nil { 58 | return nil, m.err 59 | } 60 | 61 | pw, err := m.writer.CreatePart(header) 62 | m.err = err 63 | 64 | return pw, err 65 | } 66 | 67 | func (m *multipartWriter) FormDataContentType() string { 68 | return m.writer.FormDataContentType() 69 | } 70 | 71 | func (m *multipartWriter) SetBoundary(boundary string) error { 72 | if m.err != nil { 73 | return m.err 74 | } 75 | 76 | m.err = m.SetBoundary(boundary) 77 | 78 | return m.err 79 | } 80 | 81 | func (m *multipartWriter) WriteField(fieldname, value string) error { 82 | if m.err != nil { 83 | return m.err 84 | } 85 | 86 | m.err = m.writer.WriteField(fieldname, value) 87 | 88 | return m.err 89 | } 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pushbullet-go 2 | 3 | [![License](https://img.shields.io/badge/license-MIT-yellowgreen.svg?style=flat-square)][license] 4 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)][godoc] 5 | [![Wercker](http://img.shields.io/wercker/ci/54eb41b6d9b14636631c567f.svg?style=flat-square)][wercker] 6 | 7 | [license]: LICENSE.txt 8 | [godoc]: http://godoc.org/github.com/mitsuse/pushbullet-go 9 | [wercker]: https://app.wercker.com/project/bykey/2153719836dc1ecc109b8daf75beb7e1 10 | 11 | A library to call [Pushbullet HTTP API](https://docs.pushbullet.com/#http) for Golang. 12 | 13 | ## Installation 14 | 15 | Just execute the following command: 16 | 17 | ```bash 18 | $ go get -u github.com/mitsuse/pushbullet-go/... 19 | ``` 20 | 21 | ## Example 22 | 23 | This is an example to send a simple note via Pushbullet. 24 | 25 | ```go 26 | package main 27 | 28 | import ( 29 | "fmt" 30 | "os" 31 | 32 | "github.com/mitsuse/pushbullet-go" 33 | "github.com/mitsuse/pushbullet-go/requests" 34 | ) 35 | 36 | func main() { 37 | // Set the access token. 38 | token := "" 39 | 40 | // Create a client for Pushbullet. 41 | pb := pushbullet.New(token) 42 | 43 | // Create a push. The following codes create a note, which is one of push types. 44 | n := requests.NewNote() 45 | n.Title = "Hello, world!" 46 | n.Body = "Send via Pushbullet." 47 | 48 | // Send the note via Pushbullet. 49 | if _, err := pb.PostPushesNote(n); err != nil { 50 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 51 | return 52 | } 53 | } 54 | ``` 55 | 56 | ## License 57 | 58 | The MIT License (MIT) 59 | 60 | Copyright (c) 2015 Tomoya Kose. 61 | 62 | Permission is hereby granted, free of charge, to any person obtaining a copy 63 | of this software and associated documentation files (the "Software"), to deal 64 | in the Software without restriction, including without limitation the rights 65 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 66 | copies of the Software, and to permit persons to whom the Software is 67 | furnished to do so, subject to the following conditions: 68 | 69 | The above copyright notice and this permission notice shall be included in 70 | all copies or substantial portions of the Software. 71 | 72 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 73 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 74 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 75 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 76 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 77 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 78 | THE SOFTWARE. 79 | -------------------------------------------------------------------------------- /upload.go: -------------------------------------------------------------------------------- 1 | package pushbullet 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "errors" 7 | "io" 8 | "net/http" 9 | "net/url" 10 | "strings" 11 | 12 | "github.com/mitsuse/pushbullet-go/responses" 13 | ) 14 | 15 | // Post the information of file and get the information of upload destination. 16 | func (pb *Pushbullet) PostUploadRequest(name, mime string) (*responses.Upload, error) { 17 | res, err := pb.postUploadRequest(name, mime) 18 | if err != nil { 19 | return nil, err 20 | } 21 | 22 | // TODO: Return an error value with human friendly message. 23 | if res.StatusCode != 200 { 24 | return nil, errors.New(res.Status) 25 | } 26 | 27 | decoder := json.NewDecoder(res.Body) 28 | 29 | var upload *responses.Upload 30 | if err := decoder.Decode(&upload); err != nil { 31 | return nil, err 32 | } 33 | 34 | return upload, nil 35 | } 36 | 37 | func (pb *Pushbullet) postUploadRequest(name, mime string) (*http.Response, error) { 38 | values := url.Values{ 39 | "file_name": []string{name}, 40 | "file_type": []string{mime}, 41 | } 42 | reader := strings.NewReader(values.Encode()) 43 | 44 | req, err := http.NewRequest("POST", ENDPOINT_UPLOADREQ, reader) 45 | if err != nil { 46 | return nil, err 47 | } 48 | 49 | req.Header.Add("Content-Type", "application/x-www-form-urlencoded") 50 | req.SetBasicAuth(pb.token, "") 51 | 52 | return pb.client.Do(req) 53 | } 54 | 55 | // Upload a file to S3 specified with the response of PostUploadRequest. 56 | func Upload(client *http.Client, upload *responses.Upload, reader io.Reader) error { 57 | req, err := createUploadReq(upload, reader) 58 | if err != nil { 59 | return err 60 | } 61 | 62 | res, err := client.Do(req) 63 | if err != nil { 64 | return err 65 | } 66 | 67 | // TODO: Return an error value with human friendly message. 68 | if res.StatusCode < 200 || 300 <= res.StatusCode { 69 | return errors.New(res.Status) 70 | } 71 | 72 | return nil 73 | } 74 | 75 | func createUploadReq(upload *responses.Upload, reader io.Reader) (*http.Request, error) { 76 | dest := upload.Data 77 | 78 | buffer := &bytes.Buffer{} 79 | 80 | writer := newMultipartWriter(buffer) 81 | 82 | writer.WriteField("awsaccesskeyid", dest.AwsAccessKeyId) 83 | writer.WriteField("acl", dest.Acl) 84 | writer.WriteField("key", dest.Key) 85 | writer.WriteField("signature", dest.Signature) 86 | writer.WriteField("policy", dest.Policy) 87 | writer.WriteField("content-type", dest.ContentType) 88 | 89 | if err := writer.Error(); err != nil { 90 | return nil, err 91 | } 92 | 93 | fw, err := writer.CreateFormFile("file", upload.FileName) 94 | if err != nil { 95 | return nil, err 96 | } 97 | 98 | if _, err := io.Copy(fw, reader); err != nil { 99 | return nil, err 100 | } 101 | 102 | if err := writer.Close(); err != nil { 103 | return nil, err 104 | } 105 | 106 | req, err := http.NewRequest("POST", upload.UploadUrl, buffer) 107 | if err != nil { 108 | return nil, err 109 | } 110 | 111 | req.Header.Add("Content-Type", writer.FormDataContentType()) 112 | 113 | return req, nil 114 | } 115 | -------------------------------------------------------------------------------- /pushes.go: -------------------------------------------------------------------------------- 1 | package pushbullet 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "errors" 7 | "net/http" 8 | 9 | "github.com/mitsuse/pushbullet-go/requests" 10 | "github.com/mitsuse/pushbullet-go/responses" 11 | ) 12 | 13 | // Push a note, which consists of "title" and "message" strings. 14 | func (pb *Pushbullet) PostPushesNote(n *requests.Note) (*responses.Note, error) { 15 | res, err := pb.postPushes(n) 16 | if err != nil { 17 | return nil, err 18 | } 19 | 20 | var noteRes *responses.Note 21 | decoder := json.NewDecoder(res.Body) 22 | if err := decoder.Decode(¬eRes); err != nil { 23 | return nil, err 24 | } 25 | 26 | return noteRes, err 27 | } 28 | 29 | // Push a link, which consists of "title", "message" and "url" strings. 30 | func (pb *Pushbullet) PostPushesLink(l *requests.Link) (*responses.Link, error) { 31 | res, err := pb.postPushes(l) 32 | if err != nil { 33 | return nil, err 34 | } 35 | 36 | var linkRes *responses.Link 37 | decoder := json.NewDecoder(res.Body) 38 | if err := decoder.Decode(&linkRes); err != nil { 39 | return nil, err 40 | } 41 | 42 | return linkRes, err 43 | } 44 | 45 | // Push an address, which consists of the place "name" and "address (searchquery)" for map. 46 | func (pb *Pushbullet) PostPushesAddress(a *requests.Address) (*responses.Address, error) { 47 | res, err := pb.postPushes(a) 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | var addressRes *responses.Address 53 | decoder := json.NewDecoder(res.Body) 54 | if err := decoder.Decode(&addressRes); err != nil { 55 | return nil, err 56 | } 57 | 58 | return addressRes, err 59 | } 60 | 61 | // Push a checklist, which consists of "title" and the list of items. 62 | func (pb *Pushbullet) PostPushesChecklist(c *requests.Checklist) (*responses.Checklist, error) { 63 | res, err := pb.postPushes(c) 64 | if err != nil { 65 | return nil, err 66 | } 67 | 68 | var checkRes *responses.Checklist 69 | decoder := json.NewDecoder(res.Body) 70 | if err := decoder.Decode(&checkRes); err != nil { 71 | return nil, err 72 | } 73 | 74 | return checkRes, err 75 | } 76 | 77 | // Push a file, which consists of "title", "message" and the information of uploaded file. 78 | func (pb *Pushbullet) PostPushesFile(f *requests.File) (*responses.File, error) { 79 | res, err := pb.postPushes(f) 80 | if err != nil { 81 | return nil, err 82 | } 83 | 84 | var fileRes *responses.File 85 | decoder := json.NewDecoder(res.Body) 86 | if err := decoder.Decode(&fileRes); err != nil { 87 | return nil, err 88 | } 89 | 90 | return fileRes, err 91 | } 92 | 93 | func (pb *Pushbullet) postPushes(p interface{}) (*http.Response, error) { 94 | buffer := &bytes.Buffer{} 95 | 96 | encoder := json.NewEncoder(buffer) 97 | if err := encoder.Encode(p); err != nil { 98 | return nil, err 99 | } 100 | 101 | req, err := http.NewRequest("POST", ENDPOINT_PUSHES, buffer) 102 | if err != nil { 103 | return nil, err 104 | } 105 | 106 | req.Header.Add("Content-Type", "application/json") 107 | req.SetBasicAuth(pb.token, "") 108 | 109 | res, err := pb.client.Do(req) 110 | if err != nil { 111 | return nil, err 112 | } 113 | 114 | // TODO: Return an error value with human friendly message. 115 | if res.StatusCode != 200 { 116 | return nil, errors.New(res.Status) 117 | } 118 | 119 | return res, nil 120 | } 121 | --------------------------------------------------------------------------------