Package fitbit: Ignore 404 (Not Found) errors when unsubscribing.
[kraftakt.git] / fitbit / fitbit.go
index 394cfd8..36a6e87 100644 (file)
@@ -17,7 +17,6 @@ import (
        "google.golang.org/appengine/log"
 )
 
-
 func oauthConfig() *oauth2.Config {
        return &oauth2.Config{
                ClientID:     app.Config.FitbitClientID,
@@ -193,13 +192,45 @@ func (c *Client) Subscribe(ctx context.Context, collection string) error {
 
        if res.StatusCode >= 400 && res.StatusCode != http.StatusConflict {
                data, _ := ioutil.ReadAll(res.Body)
-               log.Errorf(ctx, "creating subscription failed: status %d %q", res.StatusCode, data)
-               return fmt.Errorf("creating subscription failed")
+               log.Errorf(ctx, "creating %q subscription failed: status %d %q", collection, res.StatusCode, data)
+               return fmt.Errorf("creating %q subscription failed", collection)
        }
 
        return nil
 }
 
+func (c *Client) Unsubscribe(ctx context.Context, collection string) error {
+       subscriberID, err := c.appUser.ID(ctx)
+       if err != nil {
+               return err
+       }
+
+       url := fmt.Sprintf("https://api.fitbit.com/1/user/%s/%s/apiSubscriptions/%s.json",
+               c.fitbitUserID, collection, subscriberID)
+       req, err := http.NewRequest(http.MethodDelete, url, nil)
+       if err != nil {
+               return err
+       }
+
+       res, err := c.client.Do(req.WithContext(ctx))
+       if err != nil {
+               return err
+       }
+       defer res.Body.Close()
+
+       if res.StatusCode >= 400 && res.StatusCode != http.StatusNotFound {
+               data, _ := ioutil.ReadAll(res.Body)
+               log.Errorf(ctx, "deleting %q subscription failed: status %d %q", collection, res.StatusCode, data)
+               return fmt.Errorf("deleting %q subscription failed", collection)
+       }
+
+       return nil
+}
+
+func (c *Client) DeleteToken(ctx context.Context) error {
+       return c.appUser.DeleteToken(ctx, "Fitbit")
+}
+
 type Profile struct {
        Name     string
        Timezone *time.Location