├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README.md └── Rakefile /.gitignore: -------------------------------------------------------------------------------- 1 | data 2 | data.json 3 | start 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | ruby "2.1.2" 3 | gem "kindle-highlights", "1.0.1" 4 | gem "htmlentities" 5 | gem "mail" 6 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | domain_name (0.5.20160615) 5 | unf (>= 0.0.5, < 1.0.0) 6 | htmlentities (4.3.4) 7 | http-cookie (1.0.2) 8 | domain_name (~> 0.5) 9 | kindle-highlights (1.0.1) 10 | mechanize (>= 2.7.2) 11 | mail (2.6.4) 12 | mime-types (>= 1.16, < 4) 13 | mechanize (2.7.4) 14 | domain_name (~> 0.5, >= 0.5.1) 15 | http-cookie (~> 1.0) 16 | mime-types (>= 1.17.2, < 3) 17 | net-http-digest_auth (~> 1.1, >= 1.1.1) 18 | net-http-persistent (~> 2.5, >= 2.5.2) 19 | nokogiri (~> 1.6) 20 | ntlm-http (~> 0.1, >= 0.1.1) 21 | webrobots (>= 0.0.9, < 0.2) 22 | mime-types (2.99.2) 23 | mini_portile2 (2.1.0) 24 | net-http-digest_auth (1.4) 25 | net-http-persistent (2.9.4) 26 | nokogiri (1.6.8) 27 | mini_portile2 (~> 2.1.0) 28 | pkg-config (~> 1.1.7) 29 | ntlm-http (0.1.1) 30 | pkg-config (1.1.7) 31 | unf (0.1.4) 32 | unf_ext 33 | unf_ext (0.0.7.2) 34 | webrobots (0.1.2) 35 | 36 | PLATFORMS 37 | ruby 38 | 39 | DEPENDENCIES 40 | htmlentities 41 | kindle-highlights (= 1.0.1) 42 | mail 43 | 44 | BUNDLED WITH 45 | 1.11.2 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | Automatically email yourself a random Amazon Kindle highlight from your collection with this script. I run it on Heroku for free and email you a highlight each day. 4 | 5 | ## Heroku Setup Instructions 6 | 7 | 1. Clone this repository. 8 | 9 | 2. [Install the Heroku toolbelt.](https://toolbelt.heroku.com/) (and run ```heroku login```) 10 | 11 | 3. In the highlights repository, create a new Heroku app: 12 | ``` 13 | heroku apps:create 14 | ``` 15 | 16 | 4. Push your Ruby app to Heroku: 17 | ``` 18 | git push heroku master 19 | ``` 20 | 21 | 5. Add the Heroku Scheduler add on to your app: 22 | ``` 23 | heroku addons:create scheduler 24 | ``` 25 | 26 | 6. Add the free Heroku Mailgun add on to your app. This will automatically set your email environment variables as well: 27 | ``` 28 | heroku addons:create mailgun 29 | ``` 30 | 31 | 7. Set your additional environment variables in Heroku: 32 | ``` 33 | heroku config:set AMAZON_USER="youramazonusername@email.com" 34 | heroku config:set AMAZON_PASS="youramazonpassword" 35 | heroku config:set TO="youraddress@email.com" 36 | ``` 37 | 38 | 8. On your [Heroku scheduler dashboard](https://scheduler.heroku.com/dashboard), schedule the default rake task daily (or at an interval of your choosing): 39 | ``` 40 | bundle exec rake 41 | ``` 42 | 43 | 9. Add and verify your own [Mailgun SMTP Domain](https://help.mailgun.com/hc/en-us/articles/202052074-How-do-I-verify-my-domain-) from the dashboard or add your email as an authorized receipient. 44 | 45 | 46 | Optionally you can test the script via ```heroku run bundle exec rake``` 47 | 48 | ## Notes 49 | The default rake task first downloads and updated list of your highlights, then emails a random one to the TO address. This is because the file system on the Heroku Cedar stack is ephemeral. Each time a dyno is spun up, the file system is wiped, including any previous copies of data.json, the JSON file containing your highlights. For this reason, the script naively downloads an updated copy each time. 50 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | require 'kindle_highlights' 3 | require 'fileutils' 4 | require 'json' 5 | require 'cgi' 6 | require 'mail' 7 | require 'htmlentities' 8 | 9 | Mail.defaults do 10 | delivery_method :smtp, 11 | address: ENV['MAILGUN_SMTP_SERVER'] || "smtp.mailgun.org", 12 | port: ENV['MAILGUN_SMTP_PORT'] || 587, 13 | user_name: ENV['MAILGUN_SMTP_LOGIN'], 14 | password: ENV['MAILGUN_SMTP_PASSWORD'], 15 | to: ENV['TO'] || "youremail@domain.com", 16 | authentication: 'plain', 17 | enable_starttls_auto: true 18 | end 19 | 20 | class Kindle 21 | def initialize(path = 'data.json') 22 | @path = path 23 | end 24 | 25 | def simpleTest 26 | 27 | kindle = KindleHighlights::Client.new(email_address: ENV["AMAZON_USER"] || "youremail@domain.com", password: ENV["AMAZON_PASS"] || "youramazonpassword") 28 | 29 | # begin 30 | # puts kindle.books.sample 31 | # rescue Exception => e 32 | # puts e 33 | # end 34 | 35 | begin 36 | puts kindle.books.sample 37 | rescue Exception => e 38 | puts e 39 | end 40 | 41 | return kindle 42 | end 43 | 44 | def update(kindle) 45 | html = HTMLEntities.new 46 | # kindle = KindleHighlights::Client.new(email_address: ENV["AMAZON_USER"] || "youremail@domain.com", password: ENV["AMAZON_PASS"] || "youramazonpassword") 47 | @highlights = [] 48 | 49 | kindle.books.each do |key, title| 50 | kindle.highlights_for(key).each do |highlight| 51 | highlight["book"] = html.decode(title) 52 | highlight["highlight"] = html.decode(highlight["highlight"]) 53 | @highlights << highlight 54 | end 55 | end 56 | end 57 | 58 | def save 59 | File.open(@path, "w+") do |fp| 60 | fp << @highlights.to_json 61 | end 62 | end 63 | 64 | def highlights 65 | @highlights ||= JSON.load(open(@path)) 66 | end 67 | 68 | def random_highlight 69 | highlights[rand(highlights.length)] 70 | end 71 | end 72 | 73 | task :download do 74 | data = Kindle.new 75 | data.update(data.simpleTest) 76 | data.save 77 | end 78 | 79 | task :print do 80 | data = Kindle.new 81 | highlight = data.random_highlight 82 | puts "\"#{highlight["highlight"]}\"" 83 | puts 84 | puts " -- #{highlight["book"]}, #{highlight["howLongAgo"]}" 85 | puts 86 | end 87 | 88 | 89 | task :email do 90 | data = Kindle.new 91 | highlight = data.random_highlight 92 | 93 | puts "OK, sent email" 94 | 95 | mail = Mail.new do 96 | from 'Kindle Highlights ' 97 | to ENV['TO'] 98 | subject "#{Time.now.strftime("%b %d")}: #{highlight["book"]}" 99 | html_part do 100 | content_type 'text/html; charset=UTF-8' 101 | 102 | body "

#{highlight["highlight"]}


— #{highlight["book"]}, #{highlight["howLongAgo"]}

" 103 | end 104 | end 105 | 106 | mail.deliver 107 | end 108 | 109 | task default: [:download, :email] 110 | --------------------------------------------------------------------------------