return err
}
+ wg := &sync.WaitGroup{}
+
for _, s := range subscriptions {
- if s.CollectionType != "activities" {
+ switch s.CollectionType {
+ case "activities":
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ if err := activitiesNotification(ctx, &s); err != nil {
+ log.Warningf(ctx, "activitiesNotification() = %v", err)
+ }
+ }()
+ case "sleep":
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ if err := sleepNotification(ctx, &s); err != nil {
+ log.Warningf(ctx, "sleepNotification() = %v", err)
+ }
+ }()
+ default:
log.Warningf(ctx, "ignoring collection type %q", s.CollectionType)
- continue
- }
- if err := handleNotification(ctx, &s); err != nil {
- log.Errorf(ctx, "handleNotification() = %v", err)
- continue
}
}
+ wg.Wait()
return nil
}
-func handleNotification(ctx context.Context, s *fitbit.Subscription) error {
+func activitiesNotification(ctx context.Context, s *fitbit.Subscription) error {
u, err := fitbit.UserFromSubscriberID(ctx, s.SubscriptionID)
if err != nil {
return err
}
return nil
}
+
+func sleepNotification(ctx context.Context, s *fitbit.Subscription) error {
+ u, err := fitbit.UserFromSubscriberID(ctx, s.SubscriptionID)
+ if err != nil {
+ return err
+ }
+
+ var (
+ wg = &sync.WaitGroup{}
+ gfitClient *gfit.Client
+ gfitErr error
+ )
+
+ wg.Add(1)
+ go func() {
+ gfitClient, gfitErr = gfit.NewClient(ctx, u)
+ wg.Done()
+ }()
+
+ fitbitClient, err := fitbit.NewClient(ctx, s.OwnerID, u)
+ if err != nil {
+ return err
+ }
+
+ profile, err := fitbitClient.Profile(ctx)
+ if err != nil {
+ return err
+ }
+
+ tm, err := time.ParseInLocation("2006-01-02", s.Date, profile.Timezone)
+ if err != nil {
+ return err
+ }
+
+ sleep, err := fitbitClient.Sleep(ctx, tm)
+ if err != nil {
+ return err
+ }
+
+ var activities []gfit.Activity
+ for _, stg := range sleep.Stages {
+ a := gfit.Activity{
+ Start: stg.StartTime,
+ End: stg.EndTime,
+ }
+ switch stg.Level {
+ case fitbit.SleepLevelDeep:
+ a.Type = 110 // Deep sleep
+ case fitbit.SleepLevelLight:
+ a.Type = 109 // Light sleep
+ case fitbit.SleepLevelREM:
+ a.Type = 111 // REM sleep
+ case fitbit.SleepLevelWake:
+ a.Type = 112 // Awake (during sleep cycle)
+ default:
+ log.Warningf(ctx, "unexpected sleep level %v", stg.Level)
+ continue
+ }
+ }
+
+ wg.Wait()
+ if gfitErr != nil {
+ return gfitErr
+ }
+
+ if err := gfitClient.SetActivities(ctx, activities, tm); err != nil {
+ return fmt.Errorf("SetActivities() = %v", err)
+ }
+
+ return nil
+}