percolatestudio / meteor-google-api

A simple API encapsulating some common patterns regarding Google's APIs
https://atmospherejs.com/percolate/google-api
MIT License
48 stars 30 forks source link

calendar json issue #38

Open amitrahav opened 8 years ago

amitrahav commented 8 years ago

this is my code:

    Auth = 'Bearer ' + accessToken,
            resource = JSON.stringify({
                'end': {
                    'date': moment(day).format('YYYY-MM-DD') 
                },
                'start': {
                    'date': moment(day).format('YYYY-MM-DD') 
                },
                'summary': Meteor.user().profile.name,
                'description': Meteor.user().profile.name + 'עושה היום סידור'
            });
        console.log(resource);

        GoogleApi.post('calendar/v3/calendars/some_id/events/', {
            'headers': {
                'Content-Type': 'application/json',
            },
            'data' : resource
        }, function(err,res){
            console.log(res);
            console.log(err);
        });

threws this error: Error: failed [400] { "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Missing end time." } ], "code": 400, "message": "Missing end time." } } (…)

any ideas? can it be related to the json issue?

guidouil commented 7 years ago

I did get access to calendar \o/ here is my code

let moment = require('moment');

Meteor.methods({
  'syncProfessionalGoogleCalendar': function (professionalId) {
    check(professionalId, String);
    let professional = Professionals.findOne({_id: professionalId});
    if (professional && professional.owners) {
      let userId = professional.owners[0]; // TODO manage multiple owners
      if (userId) {
        let user = Meteor.users.findOne({_id: userId});
        if (user && user.services && user.services.google) {
          if (moment(user.services.google.expiresAt).isAfter(moment())) {
            Meteor.call('exchangeRefreshToken', userId);
          }
          let deleteProfessionalEvents = Meteor.bindEnvironment(function() {
            Events.remove({professional: professionalId});
            return true;
          });
          // Get all events
          GoogleApi.get('calendar/v3/calendars/primary/events', {
            user: user,
            params: {
              'calendarId': 'primary',
              'timeMin': new Date().toISOString(),
              // 'timeMax': new Date(new Date().setFullYear(new Date().getFullYear() + 1)).toISOString(),
              'showDeleted': false,
              'singleEvents': true,
              'orderBy': 'startTime',
              'access_type': 'offline'
            }
          }, function (error, result) {
            if (result && result.items && result.items.length > 0) {
              deleteProfessionalEvents();
              _.each(result.items, function (event) {
                Events.insert({
                  professional: professionalId,
                  id: event.id,
                  startDate: moment(event.start.dateTime).toDate(),
                  endDate: moment(event.end.dateTime).toDate(),
                  calendar: 'primary',
                  title: event.summary,
                });
              });
              return true;
            }
            if(error){
              console.error(error);
            }
          });
        }

      }
    }
    return false;
  },
});

also you need the scope to be set client side before the user 'connect with google' like this

// permission to Google calendar offline
Meteor.loginWithGoogle({requestPermissions: ['https://www.googleapis.com/auth/calendar'], forceApprovalPrompt: true, requestOfflineToken: true});
Accounts.ui.config({requestPermissions:{google:['https://www.googleapis.com/auth/calendar']}, forceApprovalPrompt: {google: true}, requestOfflineToken: {google: true}});

Hope it helps