bwatson30
bwatson30

Reputation: 263

Create event on my GSuite Calendar and inviting attendees using Service Account

I can't figure out what I'm doing wrong. Trying to invite someone to an event through a google service account.

Step one - I went to the developer console and added a service account, got the key (stored in better.json in the code below), gave it Calendar API permissions, and it's got oath2 permissions:

snapshot of my credentials panel

Step two - I gave my service account 'GSuite Domain-wide Delegation'

enter image description here

Step three - On the GSuite side, I went logged in to my admin panel, found this little guy and made the proper updates. I think? Scope? :

snapshot of my advanced security settings

Last but not least, here's the code I'm running.

require 'googleauth'

scope = 'https://www.googleapis.com/auth/calendar'

authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
  json_key_io: File.open('better.json'),
  scope: scope)

authorizer.fetch_access_token!

service = Google::Apis::CalendarV3::CalendarService.new
service.authorization = authorizer

calendar_id = 'primary'



event = Google::Apis::CalendarV3::Event.new(
  summary: 'douchin',
  location: '800 Howard St., San Francisco, CA 94103',
  description: 'A chance to hear more about Google\'s developer products.',
  start: Google::Apis::CalendarV3::EventDateTime.new(
    date_time: '2020-04-06T09:00:00-07:00',
    time_zone: 'America/New_York'
  ),
  end: Google::Apis::CalendarV3::EventDateTime.new(
    date_time: '2020-04-06T10:00:00-07:00',
    time_zone: 'America/New_York'
  ),
  recurrence: [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  guestsCanModify: 'TRUE',
  attendees: [
    Google::Apis::CalendarV3::EventAttendee.new(
      email: '[email protected]'
    )
  ],
  reminders: Google::Apis::CalendarV3::Event::Reminders.new(
    use_default: false,
    overrides: [
      Google::Apis::CalendarV3::EventReminder.new(
        reminder_method: 'email',
        minutes: 24 * 60
      ),
      Google::Apis::CalendarV3::EventReminder.new(
        reminder_method: 'popup',
        minutes: 10
      )
    ]
  )
)

result = service.insert_event('primary', event)

puts "Event created: #{result.html_link}"


response = service.list_events(calendar_id,
                               max_results: 10,
                               single_events: true,
                               order_by: 'startTime',
                               time_min: Time.now.iso8601)
puts 'Upcoming events:'
puts 'No upcoming events found' if response.items.empty?
response.items.each do |event|
  start = event.start.date || event.start.date_time
  puts "- #{event.summary} (#{event.html_link})"
end

I have two problems.

1) If I try to create an event with an attendee (this is what I'm really after), I get the error: forbiddenForServiceAccounts: Service accounts cannot invite attendees without Domain-Wide Delegation of Authority. (Google::Apis::ClientError)

2)If I try to create an event WITHOUT any attendees, it says it works, and stores the information in some magical calendar somewhere...but it does not show up in my GSuite calendar when I login to my admin account on Google. So my auth worked..I think..It kicks back an event link, but when I try to go to it I get another error: "could not find requested event" on the google calendar ui.

Upvotes: 2

Views: 1035

Answers (1)

bwatson30
bwatson30

Reputation: 263

OK - figured this out. I just needed to use Signet to produce a token instead of whatever I was using, example below where privatekey = my service accounts private key cred:

signing_key = OpenSSL::PKey::RSA.new(privatekey.gsub("\\n", "\n"), 'notasecret')
authorizer = Signet::OAuth2::Client.new(
  {
    signing_key: signing_key,
    token_credential_uri: "https://accounts.google.com/o/oauth2/token",
    audience: "https://accounts.google.com/o/oauth2/token",
    issuer: ENV['service_account_email'],
    person: ENV['email_on_my_domain_i_want_to_impersonate'],
    scope: scope
  })

token = authorizer.fetch_access_token!

Hope this helps someone someday! upvote if it does.

Upvotes: 3

Related Questions