Git Product home page Git Product logo

meteor-google-spreadsheets's Introduction

meteor-google-spreadsheets

Google Spreadsheets for Meteor

meteor add ongoworks:google-spreadsheets

Option 1

Provides a way to pull a published, public google spreadsheet into a cache collection.

Methods

Client:

Meteor.call "spreadsheet/fetch","<spreadsheet key>"

spreadsheetData = GASpreadsheet.findOne({spreadsheet:'<spreadsheet name or number>'})
if  spreadsheetData
for index,row of spreadsheetData.cells
 if ( row[1] ) then value = row[1].value
 ...

Or you could call on server:

if ( Meteor.is_server ) {
    Meteor.startup(function () {
       Meteor.setInterval(function() {
        Meteor.call('spreadsheet/fetch', key, worksheet, range, rowOneHeader)
       },50000);
    });
}

Exports

GoogleSpreadsheets

GoogleClientLogin

See:

node-google-spreadsheets

GoogleClientLogin

Collection

Used as a cache for results GASpreadsheet

Option 2

Provides a way to push the data from any collection to a Google spreadsheet, which can be either public or private. Then you can also make changes in the spreadsheet and pull them back, overwriting the data in the collection with the data from the spreadsheet.

Requirements

The collection must have a simple-schema attached using the collection2 package.

Limitations

The collection must have a simple structure with only top-level fields that are strings, numbers, etc. There is no sub-object or array support yet.

Package Setup

  1. Add the google-spreadsheets package to your Meteor app.
  2. Create a "private" folder at the top level of your Meteor app folder, if you don't already have it.
  3. Go to the Google Developers Console.
  4. Select or create a project for your Meteor app.
  5. Create a service account if you don't already have one for this project: 5. In the sidebar on the left, expand APIs & auth. Select Credentials. 6. Under the OAuth heading, select Create new Client ID. 7. When prompted, select Service Account and click Create Client ID. 8. A dialog box appears. To proceed, click Okay, got it.
  6. Your service account should have a private key associated. Save that private key into a file named "google-key.pem" in your app's "private" folder. You might be given the key within a JSON file, in which case you need to extract and parse it into the separate PEM file (replace "\n" with actual line breaks, etc.).
  7. Make note of the email address created for your service account (a long, random address). You will need this address in later steps.

Spreadsheet Setup

There are only three things you need to do to prep the spreadsheet:

  1. Create a new Google spreadsheet.
  2. Change the name from "Untitled" to something appropriate, like the name of the collection you will import into it. Don't skip this step; a unique name is required.
  3. Share the spreadsheet with the service account email address you created during the "Package Setup" task.

Using the Package in Your App

The package creates two server methods. Currently these do not do all of the work of integrating with your collection. Instead, you can make your own server methods to do that. Here are some example methods you could create in your app:

pullAllSteps: function () {
  var spreadsheetName = 'Steps'; // must match exactly the name you gave your Google spreadsheet
  var serviceEmail = '795073958503-qukpg8tt7vbsjqtufgc379ag24200fr3@developer.gserviceaccount.com'; // this is fake; replace with your own

  var result = Meteor.call("spreadsheet/fetch2", spreadsheetName, "1", {email: serviceEmail});

  // Remove all existing
  Steps.remove({});

  // Gather property names
  var propNames = {};
  _.each(result.rows, function (rowCells, rowNum) {
    var doc = {};
    _.each(rowCells, function (val, colNum) {
      if (+rowNum === 1) {
        propNames[colNum] = val;
      } else {
        var propName = propNames[colNum];
        if (propName) {
          doc[propName] = val;
        }
      }
    });
    if (+rowNum > 1) {
      Steps.insert(doc);
    }
  });
},
writeAllSteps: function () {
  var spreadsheetName = 'Steps'; // must match exactly the name you gave your Google spreadsheet
  var serviceEmail = '795073958503-qukpg8tt7vbsjqtufgc379ag24200fr3@developer.gserviceaccount.com'; // this is fake; replace with your own

  var obj = {};
  obj[1] = {}
  var colPropNames = {};
  var col = 1;
  _.each(Steps.simpleSchema().schema(), function (def, key) {
    obj[1][col] = key;
    colPropNames[key] = col;
    col++;
  });

  var row = 2;
  Steps.find().forEach(function (step) {
    obj[row] = {};
    _.each(step, function (val, prop) {
      var pCol = colPropNames[prop];
      if (!pCol)
        return;
      obj[row][pCol] = val.toString();
    });
    row++;
  });

  Meteor.call("spreadsheet/update", spreadsheetName, "1", obj, {email: serviceEmail});
}

TODO - the above methods could be pulled into the package methods, just passing in the collection object.

So if you are building an app that needs to pull or push content from any unknown spreadsheets that are owned by any random users, you simply need to ask the user what the name of the spreadsheet is, and then tell the user to share that spreadsheet with your service account email address. (XXX not sure about potential name contention?)

meteor-google-spreadsheets's People

Contributors

aaronjudd avatar aldeed avatar gouthamve avatar jasonparekh avatar lukasvan3l avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meteor-google-spreadsheets's Issues

Ideas

@aaronjudd

We should figure out what direction this should take. Since I needed to do read/write, my new stuff ended up using a different NPM package, which is also nice because it handles the oauth stuff for us. (See the new "option 2" section in the readme.) But it's currently using the "rows" api instead of "cells", which it seems has the downside of sending over the cell formulas as strings rather than as the calculated values of the formulas. I read somewhere that the cells api can handle formulas, but haven't tested.

Either way, we might want to convert your stuff to use the NPM pkg that mine is using?

We might also want to export an object with API methods instead of or in addition to the server methods. I had mentioned elsewhere that we could move the collection updating code into this package and potentially do it on the collection prototype. So the API could be something like this:

Steps = new Meteor.Collection("steps");
Steps.pullFromGSheet("Steps", {email: serviceEmailAddress});
Steps.pushToGSheet("Steps", {email: serviceEmailAddress});

And those would call methods similar to the examples in the readme, so they could be called on either client or server.

Not working on Modulus with Meteor 1.2.x

After update to 1.2, must remove this package for app to work.
Do you have a sense of when you might be able to resolve this? This is mission-critical for us.

Thank you for your help, and your helpful package.

Problem with .pem key

Since last week I am getting some errors:

Error: SignFinal error
W20160427-12:42:39.368(3)? (STDERR) 139835110377344:error:0906D06C:PEM routines:PEM_read_bio:no start line:../deps/openssl/openssl/crypto/pem/pem_lib.c:696:Expecting: ANY PRIVATE KEY

I think something went wrong mby with some last updates or etc, coz earlier everything was good.
And my code looks like this:

 serverRoot = fs.realpathSync(process.cwd())
 key = serverRoot + '/assets/app/google-key.pem'
 drive = googleapis.drive('v2')
 myMail = Meteor.settings.googleSpreadsheet.mail
 serviceMail = Meteor.settings.googleSpreadsheet.serviceMail
 authClient = new (googleapis.auth.JWT)(serviceMail, key, 'key',['https://www.googleapis.com/auth/drive'], myMail)
 authClient.authorize (err, tokens) ->
    if err
      log.info 'There is error with authorize: ' + err
    else
      console.log 'everything is good'

Current package cannot be added on Windows

When attempting to add your package from Windows I get:

 => Errors while adding packages:

While checking for ongoworks:[email protected]:
error: No compatible binary build found for this package. Contact the package author and ask
them to publish it for your platform.

Version 0.1.0 is the most recent version I can add, but this version doesn't have the 0.4.0 updates to node-google.spreadsheets necessary to work with Googles newer API.

exit code 3 troubleshooting

I was having success importing a large (42k row) Google Spreadsheet, it stopped working today. I have made no changes to either my code, my sheet's sharing, or my Google service account and I am finding no clues anywhere.

I have a console.log just before and just after my call to "spreadsheet/fetch2" so I know what line of code is triggering the error, which worked perfection find the other day with the same hard coded variables:

 ssheet = Meteor.call("spreadsheet/fetch2", ssName, "1", {
    email: serviceEmail
  });

The console output is a bit odd. I see my "before" log entry. Then the error, which has the same format as a message coming directly from the meteor command: => Exited with code: 3. Then it seems to restart, because I'm getting my normal app start log messages again. (I don't get the problem the second time because I'm using migrations and since it crashed during a migration, the migration lock prevents a second try).

The debugging steps I've tried:

  1. rename the original sheet (and the name assigned to ssName) - no effect
  2. tried a different, smaller sheet that I've used before from the same Google Drive location - works
  3. tried giving it a bad sheet name to see what happens. - logs that it couldn't find my name.
  4. tried to no avail to figure out if these were any debugging logs or way of listing shared documents from the Google service account console.

I don't think it is an error in your code, because all the error checks I've seen seem to create a log entry, but Is it possible? If not, how do I even start to figure out where the exit is being generated from and why?

Can't use in Reaction

This does not have any checks implemented which means you get the following error when trying to use it in Reaction

I20150410-15:19:07.273(5.5)? Exception while invoking method 'spreadsheet/fetch' Error: Did not check() all arguments during call to 'spreadsheet/fetch'
I20150410-15:19:07.273(5.5)?     at [object Object]._.extend.throwUnlessAllArgumentsHaveBeenChecked (packages/check/match.js:357:1)
I20150410-15:19:07.273(5.5)?     at Object.Match._failIfArgumentsAreNotAllChecked (packages/check/match.js:112:1)
I20150410-15:19:07.273(5.5)?     at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1614:1)
I20150410-15:19:07.273(5.5)?     at packages/ddp/livedata_server.js:648:1
I20150410-15:19:07.273(5.5)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20150410-15:19:07.273(5.5)?     at packages/ddp/livedata_server.js:647:1
I20150410-15:19:07.273(5.5)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20150410-15:19:07.273(5.5)?     at [object Object]._.extend.protocol_handlers.method (packages/ddp/livedata_server.js:646:1)
I20150410-15:19:07.274(5.5)?     at packages/ddp/livedata_server.js:546:1

Do you want me to implement check package and send a PR?

Using spreadsheetId instead of spreadsheetName

First of all thanks for putting together this package. It's pretty handy and I'm using it to manage keys for i18n purpose.

EditGoogleSpreadsheet.load({
      //debug: true,
      spreadsheetId: spreadsheetName,
...

I needed to change the package to use the spreadsheetId instead of the name. I'm using subfolders in google drive etc. so using simply the name didn't work. Now I'm wondering if it's not the better solution using the ID anyways?

Not sure if this package is still under development but just in case :)

windows build

building for windows has errors.

"install"
npm ERR! node v0.10.36
npm ERR! npm  v2.7.3
npm ERR! code ELIFECYCLE

npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 7
npm ERR!
npm ERR! Failed at the [email protected] install script 'node-gyp rebuild'.
npm ERR! This is most likely a problem with the iconv package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get their info via:
npm ERR!     npm owner ls iconv
npm ERR! There is likely additional logging output above.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.