feat: check unused package (#232)

* feat: check unused package

update edganiukov/fcm to appleboy/go-fcm

* update readme

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>

* update comment

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
Bo-Yi Wu
2017-06-01 02:52:01 -05:00
committed by GitHub
parent 77bce18c9f
commit 14dc899b02
42 changed files with 47 additions and 2661 deletions

21
vendor/github.com/appleboy/go-fcm/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 Eduard Ganiukov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

64
vendor/github.com/appleboy/go-fcm/README.md generated vendored Normal file
View File

@@ -0,0 +1,64 @@
# go-fcm
[![GoDoc](https://godoc.org/github.com/edganiukov/fcm?status.svg)](https://godoc.org/github.com/edganiukov/fcm)
[![Build Status](https://travis-ci.org/edganiukov/fcm.svg?branch=master)](https://travis-ci.org/edganiukov/fcm)
[![Go Report Card](https://goreportcard.com/badge/github.com/edganiukov/fcm)](https://goreportcard.com/report/github.com/edganiukov/fcm)
This project was forked from [github.com/edganiukov/fcmfcm](https://github.com/edganiukov/fcm).
Golang client library for Firebase Cloud Messaging. Implemented only [HTTP client](https://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream).
More information on [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging/)
## Getting Started
To install fcm, use `go get`:
```bash
go get github.com/appleboy/go-fcm
```
or `govendor`:
```bash
govendor fetch github.com/appleboy/go-fcm
```
or other tool for vendoring.
## Sample Usage
Here is a simple example illustrating how to use FCM library:
```go
package main
import (
"github.com/edganiukov/fcm"
)
func main() {
// Create the message to be sent.
msg := &fcm.Message{
Token: "sample_device_token",
Data: map[string]interface{}{
"foo": "bar",
}
}
// Create a FCM client to send the message.
client := fcm.NewClient("sample_api_key")
// Send the message and receive the response without retries.
response, err := client.Send(msg)
if err != nil {
/* ... */
}
/* ... */
}
```
#### TODO:
---------
- [ ] Retry only failed messages while multicast messaging.

133
vendor/github.com/appleboy/go-fcm/client.go generated vendored Normal file
View File

@@ -0,0 +1,133 @@
package fcm
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
)
const (
// DefaultEndpoint contains endpoint URL of FCM service.
DefaultEndpoint = "https://fcm.googleapis.com/fcm/send"
)
var (
// ErrInvalidAPIKey occurs if API key is not set.
ErrInvalidAPIKey = errors.New("client API Key is invalid")
)
// Client abstracts the interaction between the application server and the
// FCM server via HTTP protocol. The developer must obtain an API key from the
// Google APIs Console page and pass it to the `Client` so that it can
// perform authorized requests on the application server's behalf.
// To send a message to one or more devices use the Client's Send.
//
// If the `HTTP` field is nil, a zeroed http.Client will be allocated and used
// to send messages.
type Client struct {
apiKey string
client *http.Client
endpoint string
}
// NewClient creates new Firebase Cloud Messaging Client based on API key and
// with default endpoint and http client.
func NewClient(apiKey string, opts ...Option) (*Client, error) {
if apiKey == "" {
return nil, ErrInvalidAPIKey
}
c := &Client{
apiKey: apiKey,
endpoint: DefaultEndpoint,
client: &http.Client{},
}
for _, o := range opts {
if err := o(c); err != nil {
return nil, err
}
}
return c, nil
}
// Send sends a message to the FCM server without retrying in case of service
// unavailability. A non-nil error is returned if a non-recoverable error
// occurs (i.e. if the response status is not "200 OK").
func (c *Client) Send(msg *Message) (*Response, error) {
// validate
if err := msg.Validate(); err != nil {
return nil, err
}
// marshal message
data, err := json.Marshal(msg)
if err != nil {
return nil, err
}
return c.send(data)
}
// SendWithRetry sends a message to the FCM server with defined number of
// retrying in case of temporary error.
func (c *Client) SendWithRetry(msg *Message, retryAttempts int) (*Response, error) {
// validate
if err := msg.Validate(); err != nil {
return nil, err
}
// marshal message
data, err := json.Marshal(msg)
if err != nil {
return nil, err
}
resp := new(Response)
err = retry(func() error {
var err error
resp, err = c.send(data)
return err
}, retryAttempts)
if err != nil {
return nil, err
}
return resp, nil
}
// send sends a request.
func (c *Client) send(data []byte) (*Response, error) {
// create request
req, err := http.NewRequest("POST", c.endpoint, bytes.NewBuffer(data))
if err != nil {
return nil, err
}
// add headers
req.Header.Add("Authorization", fmt.Sprintf("key=%s", c.apiKey))
req.Header.Add("Content-Type", "application/json")
// execute request
resp, err := c.client.Do(req)
if err != nil {
return nil, connectionError(err.Error())
}
defer resp.Body.Close()
// check response status
if resp.StatusCode != http.StatusOK {
if resp.StatusCode >= http.StatusInternalServerError {
return nil, serverError(fmt.Sprintf("%d error: %s", resp.StatusCode, resp.Status))
}
return nil, fmt.Errorf("%d error: %s", resp.StatusCode, resp.Status)
}
// build return
response := new(Response)
if err := json.NewDecoder(resp.Body).Decode(response); err != nil {
return nil, err
}
return response, nil
}

77
vendor/github.com/appleboy/go-fcm/message.go generated vendored Normal file
View File

@@ -0,0 +1,77 @@
package fcm
import (
"errors"
"strings"
)
var (
// ErrInvalidMessage occurs if push notitication message is nil.
ErrInvalidMessage = errors.New("message is invalid")
// ErrInvalidTarget occurs if message topic is empty.
ErrInvalidTarget = errors.New("topic is invalid or registration ids are not set")
// ErrToManyRegIDs occurs when registration ids more then 1000.
ErrToManyRegIDs = errors.New("too many registrations ids")
// ErrInvalidTimeToLive occurs if TimeToLive more then 2419200.
ErrInvalidTimeToLive = errors.New("messages time-to-live is invalid")
)
// Notification specifies the predefined, user-visible key-value pairs of the
// notification payload.
type Notification struct {
Title string `json:"title,omitempty"`
Body string `json:"body,omitempty"`
Icon string `json:"icon,omitempty"`
Sound string `json:"sound,omitempty"`
Badge string `json:"badge,omitempty"`
Tag string `json:"tag,omitempty"`
Color string `json:"color,omitempty"`
ClickAction string `json:"click_action,omitempty"`
BodyLocKey string `json:"body_loc_key,omitempty"`
BodyLocArgs string `json:"body_loc_args,omitempty"`
TitleLocKey string `json:"title_loc_key,omitempty"`
TitleLocArgs string `json:"title_loc_args,omitempty"`
}
// Message represents list of targets, options, and payload for HTTP JSON
// messages.
type Message struct {
To string `json:"to,omitempty"`
RegistrationIDs []string `json:"registration_ids,omitempty"`
Condition string `json:"condition,omitempty"`
CollapseKey string `json:"collapse_key,omitempty"`
Priority string `json:"priority,omitempty"`
ContentAvailable bool `json:"content_available,omitempty"`
DelayWhileIdle bool `json:"delay_while_idle,omitempty"`
TimeToLive *uint `json:"time_to_live,omitempty"`
DeliveryReceiptRequested bool `json:"delivery_receipt_requested,omitempty"`
DryRun bool `json:"dry_run,omitempty"`
RestrictedPackageName string `json:"restricted_package_name,omitempty"`
Notification *Notification `json:"notification,omitempty"`
Data map[string]interface{} `json:"data,omitempty"`
}
// Validate returns an error if the message is not well-formed.
func (msg *Message) Validate() error {
if msg == nil {
return ErrInvalidMessage
}
// validate target identifier: `to` or `condition`, or `registration_ids`
opCnt := strings.Count(msg.Condition, "&&") + strings.Count(msg.Condition, "||")
if msg.To == "" && (msg.Condition == "" || opCnt > 2) && len(msg.RegistrationIDs) == 0 {
return ErrInvalidTarget
}
if len(msg.RegistrationIDs) > 1000 {
return ErrToManyRegIDs
}
if msg.TimeToLive != nil && *msg.TimeToLive > uint(2419200) {
return ErrInvalidTimeToLive
}
return nil
}

28
vendor/github.com/appleboy/go-fcm/option.go generated vendored Normal file
View File

@@ -0,0 +1,28 @@
package fcm
import (
"errors"
"net/http"
)
// Option configurates Client with defined option.
type Option func(*Client) error
// WithEndpoint returns Option to configure FCM Endpoint.
func WithEndpoint(endpoint string) Option {
return func(c *Client) error {
if endpoint == "" {
return errors.New("invalid endpoint")
}
c.endpoint = endpoint
return nil
}
}
// WithHTTPClient returns Option to configure HTTP Client.
func WithHTTPClient(httpClient *http.Client) Option {
return func(c *Client) error {
c.client = httpClient
return nil
}
}

147
vendor/github.com/appleboy/go-fcm/response.go generated vendored Normal file
View File

@@ -0,0 +1,147 @@
package fcm
import (
"encoding/json"
"errors"
)
var (
// ErrMissingRegistration occurs if registration token is not set.
ErrMissingRegistration = errors.New("missing registration token")
// ErrInvalidRegistration occurs if registration token is invalid.
ErrInvalidRegistration = errors.New("invalid registration token")
// ErrNotRegistered occurs when application was deleted from device and
// token is not registered in FCM.
ErrNotRegistered = errors.New("unregistered device")
// ErrInvalidPackageName occurs if package name in message is invalid.
ErrInvalidPackageName = errors.New("invalid package name")
// ErrMismatchSenderID occurs when application has a new registration token.
ErrMismatchSenderID = errors.New("mismatched sender id")
// ErrMessageTooBig occurs when message is too big.
ErrMessageTooBig = errors.New("message is too big")
// ErrInvalidDataKey occurs if data key is invalid.
ErrInvalidDataKey = errors.New("invalid data key")
// ErrInvalidTTL occurs when message has invalid TTL.
ErrInvalidTTL = errors.New("invalid time to live")
// ErrUnavailable occurs when FCM service is unavailable. It makes sense
// to retry after this error.
ErrUnavailable = connectionError("timeout")
// ErrInternalServerError is internal FCM error. It makes sense to retry
// after this error.
ErrInternalServerError = serverError("internal server error")
// ErrDeviceMessageRateExceeded occurs when client sent to many requests to
// the device.
ErrDeviceMessageRateExceeded = errors.New("device message rate exceeded")
// ErrTopicsMessageRateExceeded occurs when client sent to many requests to
// the topics.
ErrTopicsMessageRateExceeded = errors.New("topics message rate exceeded")
)
var (
errMap = map[string]error{
"MissingRegistration": ErrMissingRegistration,
"InvalidRegistration": ErrInvalidRegistration,
"NotRegistered": ErrNotRegistered,
"InvalidPackageName": ErrInvalidPackageName,
"MismatchSenderId": ErrMismatchSenderID,
"MessageTooBig": ErrMessageTooBig,
"InvalidDataKey": ErrInvalidDataKey,
"InvalidTtl": ErrInvalidTTL,
"Unavailable": ErrUnavailable,
"InternalServerError": ErrInternalServerError,
"DeviceMessageRateExceeded": ErrDeviceMessageRateExceeded,
"TopicsMessageRateExceeded": ErrTopicsMessageRateExceeded,
}
)
// connectionError represents connection errors such as timeout error, etc.
// Implements `net.Error` interface.
type connectionError string
func (err connectionError) Error() string {
return string(err)
}
func (err connectionError) Temporary() bool {
return true
}
func (err connectionError) Timeout() bool {
return true
}
// serverError represents internal server errors.
// Implements `net.Error` interface.
type serverError string
func (err serverError) Error() string {
return string(err)
}
func (serverError) Temporary() bool {
return true
}
func (serverError) Timeout() bool {
return false
}
// Response represents the FCM server's response to the application
// server's sent message.
type Response struct {
MulticastID int64 `json:"multicast_id"`
Success int `json:"success"`
Failure int `json:"failure"`
CanonicalIDs int `json:"canonical_ids"`
Results []Result `json:"results"`
}
// Result represents the status of a processed message.
type Result struct {
MessageID string `json:"message_id"`
RegistrationID string `json:"registration_id"`
Error error `json:"error"`
}
// UnmarshalJSON implements json.Unmarshaler interface.
func (r *Result) UnmarshalJSON(data []byte) error {
var result struct {
MessageID string `json:"message_id"`
RegistrationID string `json:"registration_id"`
Error string `json:"error"`
}
if err := json.Unmarshal(data, &result); err != nil {
return err
}
r.MessageID = result.MessageID
r.RegistrationID = result.RegistrationID
r.Error = errMap[result.Error]
return nil
}
// Unregistered checks if the device token is unregistered,
// according to response from FCM server. Useful to determine
// if app is uninstalled.
func (r Result) Unregistered() bool {
switch r.Error {
case ErrNotRegistered, ErrMismatchSenderID, ErrMissingRegistration, ErrInvalidRegistration:
return true
default:
return false
}
}

34
vendor/github.com/appleboy/go-fcm/retry.go generated vendored Normal file
View File

@@ -0,0 +1,34 @@
package fcm
import (
"net"
"time"
)
const (
minBackoff = 100 * time.Millisecond
maxBackoff = 1 * time.Minute
factor = 2.7
)
func retry(fn func() error, attempts int) error {
var attempt int
for {
err := fn()
if err == nil {
return nil
}
if tErr, ok := err.(net.Error); !ok || !tErr.Temporary() {
return err
}
attempt++
backoff := minBackoff * time.Duration(attempt*attempt)
if attempt > attempts || backoff > maxBackoff {
return err
}
time.Sleep(backoff)
}
}