Skip to content

Instantly share code, notes, and snippets.

@adamotte
Forked from jmb/README.md
Last active October 9, 2016 15:07
Show Gist options
  • Save adamotte/cda7b8345ae50018c716 to your computer and use it in GitHub Desktop.
Save adamotte/cda7b8345ae50018c716 to your computer and use it in GitHub Desktop.
Dashing.io Google Calendar

Description

Dashing widget to display the next and some subsequent Google Calendar events using the Google Calendar API v3.

I use this widget to display my shift calendar - see the screenshot below

Step 1: Turn on the Google Calendar API

  • Use this wizard to create or select a project in the Google Developers Console and automatically turn on the API. Click Continue, then Go to credentials.
  • At the top of the page, select the OAuth consent screen tab. Select an Email address, enter a Product name if not already set, and click the Save button.
  • Select the Credentials tab, click the Add credentials button and select OAuth 2.0 client ID.
  • Select the application type Other, enter the name "dashing.io.google.calendar", and click the Create button.
  • Click OK to dismiss the resulting dialog.
  • Click the (Download JSON) button to the right of the client ID.
  • Move this file to jobs directory and rename it client_secret.json.

Step 2: Install the Google Client Library

Add to Gemfile:

gem 'google-api-client', '>= 0.8'

Run

bundle install

Step 3: Add Moment librairy

Download the Moment javascript library and add to your javascript assets. Add #= require moment.js to the application.coffee script. You can also use moment.min.js if you've downloaded that.

Step 4: Authorize your script

The first time you run the script, it will prompt you to authorize access:

The script will attempt to open a new window or tab in your default browser. If this fails, copy the URL from the console and manually open it in your browser.

If you are not already logged into your Google account, you will be prompted to log in. If you are logged into multiple Google accounts, you will be asked to select one account to use for the authorization. Click the Accept button. The script will proceed automatically, and you may close the window/tab.

class Dashing.GoogleCalendar extends Dashing.Widget
onData: (data) =>
event = rest = null
getEvents = (first, others...) ->
event = first
rest = others
getEvents data.events.items...
start = moment(event.start.dateTime)
end = moment(event.end.dateTime)
@set('event',event)
@set('event_date', start.format('dddd Do MMMM'))
@set('event_times', start.format('HH:mm') + " - " + end.format('HH:mm'))
next_events = []
for next_event in rest
start = moment(next_event.start.dateTime)
start_date = start.format('ddd Do MMM')
start_time = start.format('HH:mm')
next_events.push { summary: next_event.summary, start_date: start_date, start_time: start_time }
@set('next_events', next_events)
<h1 class="subtitle" >Next event:</h1>
<h3 class="times" data-bind="event_date"></h3>
<h2 class="title" data-bind="event.summary"></h2>
<h3 class="times" data-bind="event_times"></h3>
<h4 data-bind="next_count"></h4>
<table class="next">
<tr data-foreach-e='next_events'>
<td data-bind="e.start_date"></td>
<td data-bind="e.start_time"></td>
<td data-bind="e.summary"></td>
</tr>
</table>
<div class="updated-at" data-bind="updatedAtMessage"></div>
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'google/api_client/auth/storage'
require 'google/api_client/auth/storages/file_store'
require 'fileutils'
APPLICATION_NAME = 'dashing.io.google.calendar'
CLIENT_SECRETS_PATH = 'jobs/client_secret.json'
CREDENTIALS_PATH = File.join(Dir.home, '.credentials',
"google-calendar-dashing-job.json")
SCOPE = 'https://www.googleapis.com/auth/calendar.readonly'
##
# Ensure valid credentials, either by restoring from the saved credentials
# files or intitiating an OAuth2 authorization request via InstalledAppFlow.
# If authorization is required, the user's default browser will be launched
# to approve the request.
#
# @return [Signet::OAuth2::Client] OAuth2 credentials
def authorize
FileUtils.mkdir_p(File.dirname(CREDENTIALS_PATH))
file_store = Google::APIClient::FileStore.new(CREDENTIALS_PATH)
storage = Google::APIClient::Storage.new(file_store)
auth = storage.authorize
if auth.nil? || (auth.expired? && auth.refresh_token.nil?)
app_info = Google::APIClient::ClientSecrets.load(CLIENT_SECRETS_PATH)
flow = Google::APIClient::InstalledAppFlow.new({
:client_id => app_info.client_id,
:client_secret => app_info.client_secret,
:scope => SCOPE})
auth = flow.authorize(storage)
puts "Credentials saved to #{CREDENTIALS_PATH}" unless auth.nil?
end
auth
end
# Initialize the API
client = Google::APIClient.new(:application_name => APPLICATION_NAME)
client.authorization = authorize
calendar_api = client.discovered_api('calendar', 'v3')
# Start the scheduler
SCHEDULER.every '15m', :first_in => 4 do |job|
results = client.execute!(
:api_method => calendar_api.events.list,
:parameters => {
:calendarId => 'primary',
:maxResults => 3,
:singleEvents => true,
:orderBy => 'startTime',
:timeMin => Time.now.iso8601 })
send_event('google_calendar', { events: results.data })
end
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #47bbb3; //#ec663c;
$title-color: rgba(255, 255, 255, 1);
$subtitle-color: rgba(255, 255, 255, 0.7);
$moreinfo-color: rgba(255, 255, 255, 0.7);
// ----------------------------------------------------------------------------
// Widget-calendar styles
// ----------------------------------------------------------------------------
.widget-google-calendar {
background-color: $background-color;
.subtitle {
color: $subtitle-color;
font-size: 0.75em;
margin: 15px 0;
}
.title {
color: $title-color;
font-size: 1.4em;
}
.times {
font-size: 0.9em;
}
.next {
font-size: 0.75em;
margin-top: 30px;
.tr {
border-bottom: 1px solid $subtitle-color;
.td {
text-align: left;
}
}
}
.more-info {
color: $moreinfo-color;
}
.updated-at {
color: $subtitle-color;
bottom: 5px;
right: 5px;
left: auto;
font-size: 0.5em;
}
&.large h3 {
font-size: 65px;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment