├── .gitignore ├── public ├── iphone.png └── app.css ├── Gemfile ├── views ├── thanks.erb ├── layout.erb └── index.erb ├── README.md └── Gemfile.lock /.gitignore: -------------------------------------------------------------------------------- 1 | client_secret.json 2 | -------------------------------------------------------------------------------- /public/iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philnash/ruby-google-sheets-sinatra/HEAD/public/iphone.png -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | source "https://rubygems.org" 3 | 4 | gem "sinatra" 5 | gem "google_drive" 6 | -------------------------------------------------------------------------------- /views/thanks.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

Thanks!

6 |

We'll let you know when the fancy new app is ready.

7 |
8 |
9 |
10 |
11 | 12 | -------------------------------------------------------------------------------- /public/app.css: -------------------------------------------------------------------------------- 1 | .jumbotron{ 2 | padding-bottom: 0; 3 | } 4 | 5 | .iphone { 6 | background: transparent url(/iphone.png) no-repeat center calc(100% + 350px); 7 | padding-bottom:300px; 8 | } 9 | 10 | @media (min-width: 768px) { 11 | .iphone { 12 | background: transparent url(/iphone.png) no-repeat 80% top; 13 | padding-bottom:48px; 14 | } 15 | } 16 | 17 | .bg-danger { 18 | padding: 15px; 19 | } 20 | -------------------------------------------------------------------------------- /views/layout.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Fancy new app! 9 | 10 | 11 | 12 | 13 | 14 | 15 | <%= yield %> 16 | 17 |
18 |
19 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Using Google Sheets with Ruby and Sinatra 2 | 3 | This is a sample application that uses Sinatra to host a site that saves data in a Google Sheet. 4 | 5 | ## Running the application 6 | 7 | ### Get setup with Google Sheets 8 | 9 | Follow the steps in [this blog post](https://www.twilio.com/blog/2017/03/google-spreadsheets-ruby.html) to create the credentials for a service account in the Google APIs Console. Download the credentials and copy them to this project with the filename `client_secret.json`. 10 | 11 | You will also need to create a blank spreadsheet and give your service account access to edit. 12 | 13 | ### Download and prepare the app 14 | 15 | Clone this repository with the command: 16 | 17 | ```bash 18 | git clone https://github.com/philnash/ruby-google-sheets-sinatra.git 19 | cd ruby-google-sheets-sinatra 20 | ``` 21 | 22 | Install the dependencies: 23 | 24 | ```bash 25 | bundle install 26 | ``` 27 | 28 | ### Read the blog post! 29 | 30 | Follow the instructions to [create a landing page with Sinatra, Google Spreadsheets, and Ruby](https://www.twilio.com/blog/2017/03/create-a-landing-page-with-sinatra-google-spreadsheets-and-ruby.html). 31 | 32 | You can also inspect the final code in the [save-data](https://github.com/philnash/ruby-google-sheets-sinatra/tree/save-data) branch. 33 | 34 | Want to take it further? Learn how to [validate Ruby objects with Active Model Validations](https://www.twilio.com/blog/2017/06/validate-ruby-objects-with-active-model-validations.html) and see how it applies in the [validations](https://github.com/philnash/ruby-google-sheets-sinatra/tree/validations) branch. 35 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.8.0) 5 | public_suffix (>= 2.0.2, < 5.0) 6 | declarative (0.0.10) 7 | declarative-option (0.1.0) 8 | faraday (0.15.4) 9 | multipart-post (>= 1.2, < 3) 10 | google-api-client (0.30.2) 11 | addressable (~> 2.5, >= 2.5.1) 12 | googleauth (>= 0.5, < 0.10.0) 13 | httpclient (>= 2.8.1, < 3.0) 14 | mini_mime (~> 1.0) 15 | representable (~> 3.0) 16 | retriable (>= 2.0, < 4.0) 17 | signet (~> 0.10) 18 | google_drive (3.0.3) 19 | google-api-client (>= 0.11.0, < 0.31.0) 20 | googleauth (>= 0.5.0, < 1.0.0) 21 | nokogiri (>= 1.5.3, < 2.0.0) 22 | googleauth (0.8.1) 23 | faraday (~> 0.12) 24 | jwt (>= 1.4, < 3.0) 25 | memoist (~> 0.16) 26 | multi_json (~> 1.11) 27 | os (>= 0.9, < 2.0) 28 | signet (~> 0.7) 29 | httpclient (2.8.3) 30 | jwt (2.2.1) 31 | memoist (0.16.0) 32 | mini_mime (1.0.1) 33 | mini_portile2 (2.8.0) 34 | multi_json (1.13.1) 35 | multipart-post (2.1.1) 36 | mustermann (2.0.2) 37 | ruby2_keywords (~> 0.0.1) 38 | nokogiri (1.13.10) 39 | mini_portile2 (~> 2.8.0) 40 | racc (~> 1.4) 41 | os (1.0.1) 42 | public_suffix (4.0.6) 43 | racc (1.6.1) 44 | rack (2.2.4) 45 | rack-protection (2.2.3) 46 | rack 47 | representable (3.0.4) 48 | declarative (< 0.1.0) 49 | declarative-option (< 0.2.0) 50 | uber (< 0.2.0) 51 | retriable (3.1.2) 52 | ruby2_keywords (0.0.5) 53 | signet (0.11.0) 54 | addressable (~> 2.3) 55 | faraday (~> 0.9) 56 | jwt (>= 1.5, < 3.0) 57 | multi_json (~> 1.10) 58 | sinatra (2.2.3) 59 | mustermann (~> 2.0) 60 | rack (~> 2.2) 61 | rack-protection (= 2.2.3) 62 | tilt (~> 2.0) 63 | tilt (2.0.11) 64 | uber (0.1.0) 65 | 66 | PLATFORMS 67 | ruby 68 | 69 | DEPENDENCIES 70 | google_drive 71 | sinatra 72 | 73 | BUNDLED WITH 74 | 1.16.0 75 | -------------------------------------------------------------------------------- /views/index.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

Fancy new app!

6 |

This is going to be really useful for you!

7 |
8 |
9 |
10 |
11 | <% if defined? error_message %> 12 |

<%= error_message %>

13 | <% end %> 14 |
15 |
16 | 17 | 18 |
19 |
20 | 21 | 22 |
23 |
24 | 25 | 26 |
27 | 28 |
29 |
30 |
31 |
32 |
33 | 34 |
35 |
36 |
37 |

It's fancy!

38 |

You've never seen an app this fancy. Making the app fancy was never on the backlog, it was always in progress. We have a dedicated team of testers ensuring it meets our self imposed fanciness standards.

39 |
40 |
41 |

It's new!

42 |

You've never seen an app like this before because it's totally new. We've barely seen it, it's that new. And for one glorious moment it will be the newest thing in the world available to you.

43 |
44 |
45 |

It's an app

46 |

Don't start fretting that we're going to release a fancy new banana or fancy new species of dog. We've definitely been working on an app. It's fancy, it's new, it's an app. What more could you want?

47 |
48 |
49 |
50 | --------------------------------------------------------------------------------