Skip to content

Instantly share code, notes, and snippets.

@a-c-t-i-n-i-u-m
Last active March 8, 2016 06:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save a-c-t-i-n-i-u-m/927b6ec6b77ee40d5954 to your computer and use it in GitHub Desktop.
Save a-c-t-i-n-i-u-m/927b6ec6b77ee40d5954 to your computer and use it in GitHub Desktop.
digispark + node.js + google gmail api; notify unread message of gmail as digispark led blinking; http://actinium.org/electronics/avr/digispark/
var usb = require('usb');
var fs = require('fs');
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');
// const
var USBRQ_HID_SET_REPORT = 0x09;
var USB_HID_REPORT_TYPE_FEATURE = 0x03;
// define; default of digispark hid
var VID = 0x16c0;
var PID = 0x05df;
var sendDigispark = function (data, callback) {
if (typeof callback !== 'function') {
callback = function () {};
}
// search device
var device = usb.findByIds(VID, PID);
if (device) {
try {
// open device
device.open();
// send
var reportId = 0, len = 1;
device.controlTransfer(
// bmRequestType
usb.LIBUSB_REQUEST_TYPE_CLASS | usb.LIBUSB_RECIPIENT_DEVICE | usb.LIBUSB_ENDPOINT_OUT,
// bRequest
USBRQ_HID_SET_REPORT,
// wValue
(USB_HID_REPORT_TYPE_FEATURE << 8) | reportId,
// wIndex
data,
// data_or_length
new Buffer(len),
function (err) {
// end
device.close();
callback(err);
}
);
} catch (e) {
device.close();
callback(e);
}
} else {
callback(new Error('Device not found.'));
}
};
//
// from https://developers.google.com/gmail/api/quickstart/nodejs#step_3_set_up_the_sample
//
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-nodejs-quickstart.json
var SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];
//var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
// process.env.USERPROFILE) + '/.credentials/';
var TOKEN_DIR = process.cwd() + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'gmail-nodejs-quickstart.json';
// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
if (err) {
console.log('Error loading client secret file: ' + err);
return;
}
// Authorize a client with the loaded credentials, then call the
// Gmail API.
authorize(JSON.parse(content), main);
});
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
*
* @param {Object} credentials The authorization client credentials.
* @param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
var clientSecret = credentials.installed.client_secret;
var clientId = credentials.installed.client_id;
var redirectUrl = credentials.installed.redirect_uris[0];
var auth = new googleAuth();
var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, function(err, token) {
if (err) {
getNewToken(oauth2Client, callback);
} else {
oauth2Client.credentials = JSON.parse(token);
callback(oauth2Client);
}
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
*
* @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
* @param {getEventsCallback} callback The callback to call with the authorized
* client.
*/
function getNewToken(oauth2Client, callback) {
var authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES
});
console.log('Authorize this app by visiting this url: ', authUrl);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Enter the code from that page here: ', function(code) {
rl.close();
oauth2Client.getToken(code, function(err, token) {
if (err) {
console.log('Error while trying to retrieve access token', err);
return;
}
oauth2Client.credentials = token;
storeToken(token);
callback(oauth2Client);
});
});
}
/**
* Store token to disk be used in later program executions.
*
* @param {Object} token The token to store to disk.
*/
function storeToken(token) {
try {
fs.mkdirSync(TOKEN_DIR);
} catch (err) {
if (err.code != 'EEXIST') {
throw err;
}
}
fs.writeFile(TOKEN_PATH, JSON.stringify(token));
console.log('Token stored to ' + TOKEN_PATH);
}
//
// user application
//
// loop process
var tick = function () {
// gmail get unread message list
google.gmail('v1').users.messages.list({
userId: 'me',
q: 'is:unread',
}, function (err, res) {
// if unread message exists
if (!err && res && res.messages && res.messages.length) {
sendDigispark(1);// gmail blink mode
} else {
sendDigispark(0);// no blink
}
});
};
// setup user application
var main = function (auth) {
// set auth as a global default
google.options({auth: auth});
// start service
var f = function () {
tick();
setTimeout(f, 10 * 1000);// check interval[ms]
};
// init
f();
};
#include <DigiUSB.h>
#define LED_PORT 1
void setup() {
DigiUSB.begin();
pinMode(LED_PORT, OUTPUT);
}
int blinkMode = 0;
void loop() {
if (DigiUSB.available()) {
blinkMode = DigiUSB.read();
}
switch (blinkMode) {
// no blink
case 0:
digitalWrite(LED_PORT, LOW);
break;
// gmail unread
case 1:
for (int i = 0; i < 3; i++) {
digitalWrite(LED_PORT, HIGH);
DigiUSB.delay(100);
digitalWrite(LED_PORT, LOW);
DigiUSB.delay(100);
}
DigiUSB.delay(500);
break;
}
DigiUSB.refresh();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment