Skip to content

Instantly share code, notes, and snippets.

@rondorkerin
Created March 5, 2014 22:21
Show Gist options
  • Save rondorkerin/9377867 to your computer and use it in GitHub Desktop.
Save rondorkerin/9377867 to your computer and use it in GitHub Desktop.
A Reddit Bot
require 'snoo'
require 'json'
require 'open-uri'
task :reddit do
@cfg = Rails.application.config
@after = nil
puts @cfg.minutes_between_posts.to_s + " minutes between posts... initializing @ #{Time.new()}"
replies = {}
puts "loading historical replies list... "
if File.exist? "replieslist.txt"
IO.foreach("replieslist.txt") do |reply|
replies[reply.strip] = 1
end
end
puts "replies so far... #{replies}"
puts "reddit bot initialized! Lasers are online!"
@r = Snoo::Client.new
@r.log_out
loop do
@r.log_in @cfg.reddit_uname, @cfg.reddit_pass
# progresspics has a much better thing going with respect to post titles
# being parseable, whereas /r/loseit posts are all over the place.
subreddit = 'progresspics'
puts "posts after #{@after}"
opts = {
:subreddit => subreddit,
:page => 'new',
:sort => 'new',
:after => @after,
:limit => 1
}
listings = @r.get_listing opts
body = JSON.parse listings.body
@after = body['data']['after']
post = body['data']['children'].first
title = post['data']['title']
puts "title: #{title}"
url = post['data']['permalink']
id = "#{post['kind']}_#{post['data']['id']}"
if replies.has_key? id then
puts "We've already replied to this post! Next!"
sleep 3
next
end
# parse the general format which is:
# sex / age / height [startingweight endingweight]
# alternatively:
# sex / age / height [endingweight startingweight]
# the left brackets are not optional.
# in the future we can add different ones.
# alternative formats (can do by request, but the people following the format are generating enough requests):
# xxxlbs/kgs xxxlbs/kgs (without sex/age/height) could be parsed
# down to xxxlbs/kgs
# xxx[lbs/kgs] - xxx[lbs/kgs]
# xxx[lbs/kgs] => xxx[lbs/kgs]
vitalStats = /([a-zA-Z])[\/|\s](\d+)[\/|\s](\d+)\'\s*(\d*)\"?/.match(title)
weightChange = /[\[|(](\d{2,3})\D+(\d{2,3})/.match(title)
if vitalStats and weightChange
weights = [weightChange[1].to_i, weightChange[2].to_i]
post= {
:sex => vitalStats[1],
:age => vitalStats[2],
:heightFeet => vitalStats[3],
:heightInches=> vitalStats[4],
:startingWeight => weights.max,
:currentWeight => weights.min,
:id => id,
:url => url,
:title => title
}
replies[post[:id]] = 1
params = {
"utm_source" => "reddit",
"utm_medium" => "social",
"utm_campaign" => "similar_search",
"utm_term" => "like_you",
"utm_content" => "progacc_starting"
}
search_params = {
"search_type" => "exact",
"gender" => post[:sex] == "F" || post[:sex] == "f" ? "female" : "male",
"height" => post[:heightFeet].to_i*12 + post[:heightInches].to_i,
"weight" => post[:startingWeight],
"start_end" => "start",
"keyword" => ""
}
# generate starting and ending weight urls
search_json = JSON.generate(search_params);
startingWeightURL = URI::HTTP.build(:host => "healthylikeme.org", :query => params.to_query, :fragment => "search/" + URI::encode(search_json.to_s))
search_params['start_end'] = 'end'
search_params['weight'] = post[:currentWeight]
search_json = JSON.generate(search_params);
currentWeightURL = URI::HTTP.build(:host => "healthylikeme.org", :query => params.to_query, :fragment => "search/" + URI::encode(search_json.to_s))
# have to un-indent it to avoid weird spacing issues with the string
text = "Thanks for sharing your inspiration! Keep at it. Just wanted to share some similarly inspiring people from /r/#{subreddit} who have gone through similar journeys.
[#{post[:sex]}/#{post[:heightFeet]}'#{post[:heightInches]}\"/Starting @ #{post[:startingWeight]}](#{startingWeightURL})
And here are others who started where you are now to keep that motivation up :)
[#{post[:sex]}/#{post[:heightFeet]}'#{post[:heightInches]}\"/Ending @ #{post[:currentWeight]}](#{currentWeightURL}) "
begin
puts "commenting on post of ID " + post[:id]
puts post[:url]
@r.comment text, post[:id]
File.open("replieslist.txt", "a") do |file|
file.puts post[:id]
end
rescue
puts "received 403 error at #{Time.new()}"
puts "this means the bot has been running too often. Configure it to run less often."
end
puts "replies so far: #{replies}"
@r.log_out
sleep @cfg.minutes_between_posts.minutes
else
puts "unable to parse this particular title.... moving to next"
sleep 3
next
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment