function myFunction() {
try {
var out = [];
if (GmailApp.getInboxUnreadCount() > 0 ){
var threads = GmailApp.getInboxThreads();
for (var i = 0; i < threads.length; i++) {
out.push([threads[i].getMessages()[0].getFrom(), threads[i].getFirstMessageSubject(), threads[i].getMessages()[0].getDate()]);
View application.js
var Grailbird = function (type, date, data) { = || {};[type+'_'+date] = data;
(function(exports) {
"use strict";
var User = {},
Tweets = {},
To use you need to create an application on Github at
The callback in this needs to be set to{SCRIPT ID}/usercallback
Where {SCRIPT ID} is the ID of the script that is using this library. You can find your script's ID in the Apps Script code editor by clicking on the menu item "File > Project properties".
In this example code I've stored the apllicaitons clientId and clientSecret in the Script Properties:
- git_clientId
- git_clientSecret
View FL Data Processing.ipynb
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View gist:105a4f6e5e2dcdba69b8c5e2868da373
# Extension of
def plot_cumulativeCount(df, group, groupset, index, title, start, end):
plt.rc("figure", figsize=(15, 10))
df=date_limiter(df, start, end)
df['Total enrollments']=range(len(df))
View gist:c6dd723a79d8b5ca646ceb8827f67242
#generate a calendar heatmap of step visits
# Extension of
import datetime as dt
def generate_data():
num = 100
data = np.random.randint(0, 20, num)
start = pd.to_datetime(COURSE_START_DATE)
View gist:99ea405a8aac79f4bc0becfbc950479b
# Enrollment summary graph
# Extension of
import matplotlib.ticker as tkr
cat = ['Enrolled learners', 'Visited at least one step', 'Completed at least one step', 'Commented at least once']
count = [len(enrolled_learners),
// setRowsData fills in one row of data per object defined in the objects Array.
// For every Column, it checks if data objects define a value for it.
// Arguments:
// - sheet: the Sheet Object where the data will be written
// - objects: an Array of Objects, each of which contains data for a row
// - optHeadersRange: a Range of cells where the column headers are defined. This
// defaults to the entire first row in sheet.
// - optFirstDataRowIndex: index of the first row where data should be written. This
// defaults to the row immediately below the headers.
function setRowsData(sheet, objects, optHeadersRange, optFirstDataRowIndex) {
function getService() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
return OAuth2.createService('blogger')
// Set the endpoint URLs, which are the same for all Google services.
var DOC_ID = '1K5IJLwK7qBUfLAG-tic9hOK3L8x4qUIQgd3gryHNE6Y';
function doGet() {
var doc =SpreadsheetApp.openById(DOC_ID);
var auth_user = doc.getViewers();
var auth = {
return String(user);
var user = Session.getActiveUser().getEmail();
if (auth.indexOf(user) > -1){