Eli
Eli

Reputation: 17825

Creating Google Calendar Events using API doesn't create Hangout link

I've been successful so far in hacking together the googleapis and gapitoken packages to create events on a Google Calendar via the API. The point of all this was to find a way to programmatically generate a Google Hangout link, which you cannot do via API, as far as I know. According to this post, you are supposed to be able to enable Automatic Creation of Hangout Links when creating events, which I have done for the account.

The code I am using is only going to be run from Node.js, so there is no user-facing portion. I am using the Service Account technique to authenticate via OAuth2.0. Everything seems to work fine, except the event that is created contains no property called 'hangoutLink'. Any ideas?

var moment = require('moment');
var googleapis = require('googleapis');
var GoogleToken = require('gapitoken');
var OAuth2Client = googleapis.OAuth2Client;

var token = new GoogleToken({
    iss: '*******************@developer.gserviceaccount.com',
    scope: 'https://www.googleapis.com/auth/calendar',
    keyFile: './*****************.pem'
}, function (err) {
    if (err) {
        return console.log(err);
    }

    token.getToken(function (err, token) {
        if (err) {
            return console.log(err);
        }

        googleapis.load('calendar', 'v3', function (err, client) {
            var oauthClient = new OAuth2Client('', '', '', {}, {
                token_type: 'Bearer',
                access_token: token
            });

            var now = moment().format();

            client
                .calendar
                .events
                .insert({
                    calendarId: 'primary',
                    resource: {
                        summary: 'hangout',
                        description: 'hangout',
                        reminders: {
                            overrides: {
                                method: 'popup',
                                minutes: 0
                            }
                        },
                        start: {
                            dateTime: now
                        },
                        end: {
                            dateTime: now
                        },
                        attendees: [{
                            email: '****@**********.com'
                        }]
                    }
                })
                .withAuthClient(oauthClient)
                .execute(function (err, event) {
                    // event does not contain hangoutLink
                    console.log(event.hangoutLink);
                });
        });
    });
});

Upvotes: 10

Views: 4740

Answers (3)

cutiko
cutiko

Reputation: 10527

Everything seems fine except you have to add the hangout data in 2 parts. First in the event you are going to create and also as a parameter representing the version on the arguments it is called conferenceDataVersion

    const event = {
        "summary": "Google I/O 2015",
        "location": "800 Howard St., San Francisco, CA 94103",
        "description": "A chance to hear more about Google\"s developer products.",
        "start": {
            "dateTime": "2015-05-28T09:00:00-07:00",
            "timeZone": "America/Los_Angeles",
        },
        "end": {
            "dateTime": "2015-05-28T17:00:00-07:00",
            "timeZone": "America/Los_Angeles",
        },
        "conferenceData": {
            "createRequest": {
                "requestId": "someRandomKey"
            }
        }
    };

    calendar.events.insert({
        auth: yourAuth,
        calendarId: 'primary',
        resource: event,
        conferenceDataVersion: 1
    }, function (error, event) {
        if (error) {
            console.log("CALENDAR_ERROR", error);
        }
        console.log("CALENDAR_SUCCESS", event.data);
        console.log("HANGOUT_LINK", event.data.hangoutLink);
    });

The const event is mostly copied from the example on the docs. The key here is to add the conference relevant data in both parts. Adding only the:

    "conferenceData": {
        "createRequest": {
            "requestId": "someRandomKey"
        }
    }

Doesn't work, you also have to the conferenceDataVersion: int on the arguments.

Upvotes: 3

drewww
drewww

Reputation: 2525

This isn't a complete solution, but I've had partial success by changing the constraints a little bit. The auto-creation of hangout links with events seems to be an account-specific setting, not a calendar specific setting. That means that using a service account model to create the events doesn't trigger the hangout creation, because we don't (as far as I can tell) have a way to turn on auto-create-hangouts on the google accounts created in the service account model.

To test this theory, I put together an OAuth-based version that gets a traditional google account token. It looks like this: https://gist.github.com/drewww/5665130

It's more or less the same as your example, except for the sort of token being used. In the callback, hangoutLink is reliably populated.

Obviously, this is not as clean as in your example. It depends on a traditional oauth flow, and the user creating the events must have auto-create hangout turned on in their personal account settings. This is obviously highly inconvenient from a user experience perspective. I'm going to try creating a dummy google account and having it own all my hangouts.

Upvotes: 2

Burcu Dogan
Burcu Dogan

Reputation: 9213

Set the credentials to the auth client explicitly:

var oauthClient = new OAuth2Client('', '', '');
oauthClient.credentials = {
  token_type: 'Bearer',
  access_token: token
};

Upvotes: 0

Related Questions