X-Git-Url: https://git.octo.it/?p=kraftakt.git;a=blobdiff_plain;f=gfit%2Fgfit.go;h=ed8f7cb840acdc7f7b23cb3a4a116984f65f884e;hp=028eee0cc8f8d5c844545e04410567aa3d97c671;hb=43223a02eecd68642404b09c3085f435722cb144;hpb=a1803b210e15430a724d10e7370fd0a0e3256f8b diff --git a/gfit/gfit.go b/gfit/gfit.go index 028eee0..ed8f7cb 100644 --- a/gfit/gfit.go +++ b/gfit/gfit.go @@ -4,11 +4,14 @@ import ( "context" "fmt" "net/http" + "time" "github.com/octo/gfitsync/app" "golang.org/x/oauth2" oauth2google "golang.org/x/oauth2/google" fitness "google.golang.org/api/fitness/v1" + "google.golang.org/appengine" + "google.golang.org/appengine/log" ) var oauthConfig = &oauth2.Config{ @@ -24,6 +27,14 @@ var oauthConfig = &oauth2.Config{ const csrfToken = "@CSRFTOKEN@" +func Application(ctx context.Context) *fitness.Application { + return &fitness.Application{ + Name: "Fitbit to Google Fit sync", + Version: appengine.VersionID(ctx), + DetailsUrl: "", // optional + } +} + func AuthURL() string { return oauthConfig.AuthCodeURL(csrfToken, oauth2.AccessTypeOffline) } @@ -60,3 +71,58 @@ func NewClient(ctx context.Context, u *app.User) (*Client, error) { Service: service, }, nil } + +func (c *Client) SetSteps(ctx context.Context, steps int, date time.Time) error { + const userID = "me" + const dataTypeName = "com.google.step_count.delta" + dataSource := &fitness.DataSource{ + Application: Application(ctx), + DataStreamName: "", // "daily summary"? + DataType: &fitness.DataType{ + Field: []*fitness.DataTypeField{ + &fitness.DataTypeField{ + Format: "integer", + Name: "steps", + }, + }, + Name: dataTypeName, + }, + Name: "Step Count", + Type: "raw", + } + + dataSource, err := c.Service.Users.DataSources.Create(userID, dataSource).Context(ctx).Do() + if err != nil { + log.Errorf(ctx, "c.Service.Users.DataSources.Create() = (%+v, %v)", dataSource, err) + return err + } + dataSourceID := dataSource.DataStreamId + + startTimeNanos := date.UnixNano() + endTimeNanos := date.Add(86399999999999 * time.Nanosecond).UnixNano() + datasetID := fmt.Sprintf("%d-%d", startTimeNanos, endTimeNanos) + dataset := &fitness.Dataset{ + MinStartTimeNs: startTimeNanos, + MaxEndTimeNs: endTimeNanos, + Point: []*fitness.DataPoint{ + &fitness.DataPoint{ + ComputationTimeMillis: time.Now().UnixNano() / 1000000, + DataTypeName: dataTypeName, + StartTimeNanos: startTimeNanos, + EndTimeNanos: endTimeNanos, + Value: []*fitness.Value{ + &fitness.Value{ + IntVal: int64(steps), + }, + }, + }, + }, + } + + dataset, err = c.Service.Users.DataSources.Datasets.Patch(userID, dataSourceID, datasetID, dataset).Context(ctx).Do() + if err != nil { + log.Errorf(ctx, "c.Service.Users.DataSources.Datasets.Patch() = (%+v, %v)", dataset, err) + return err + } + return nil +}