Skip to content

Instantly share code, notes, and snippets.

@stjordanis
Forked from neoeno/Gemfile
Created November 6, 2024 23:13
Show Gist options
  • Save stjordanis/3bbad3b5b57e23c8d040585a88ed0b67 to your computer and use it in GitHub Desktop.
Save stjordanis/3bbad3b5b57e23c8d040585a88ed0b67 to your computer and use it in GitHub Desktop.
Pokemon Go Slack Bot
# == A handy Professor Oak bot for your slack! ==
# Tells you when new pokemon spawn in your area
# E.g. http://i.imgur.com/yDvSV2W.png
# Uses http://pokevision.com/ to get data. Hope that's OK Pokevision!
# == Usage ==
# 1. Hit 'Download ZIP' above and unzip to your favourite directory
# 2. Fill out the HOME_POSITION with the location of e.g. your office
# 3. Fill out WEBHOOK_URL with a Slack incoming webhook URL
# (Heartily recommend uploading a picture of the prof as the icon when you set up the webhook)
# 4. Then run (presuming you have ruby & bundler):
# > bundle install
# > ruby bot.rb
HOME_POSITION = [0.0, 0.0] # lat, lng
WEBHOOK_URL = "https://hooks.slack.com/services/..."
SCAN_DISTANCE = 0.15 # 0.15 mile radius, change if you like walking
IGNORE = ["Drowzee", "Pidgey", "Zubat", "Rattata", "Spearow"].map(&:downcase) # Ignore the common pokemon in your area
# =============== CONFIG OVER NOTHING TO SEE HERE ===============
POKEDEX = {"1"=>"Bulbasaur","2"=>"Ivysaur","3"=>"Venusaur","4"=>"Charmander","5"=>"Charmeleon","6"=>"Charizard","7"=>"Squirtle","8"=>"Wartortle","9"=>"Blastoise","10"=>"Caterpie","11"=>"Metapod","12"=>"Butterfree","13"=>"Weedle","14"=>"Kakuna","15"=>"Beedrill","16"=>"Pidgey","17"=>"Pidgeotto","18"=>"Pidgeot","19"=>"Rattata","20"=>"Raticate","21"=>"Spearow","22"=>"Fearow","23"=>"Ekans","24"=>"Arbok","25"=>"Pikachu","26"=>"Raichu","27"=>"Sandshrew","28"=>"Sandslash","29"=>"Nidoran\u2640","30"=>"Nidorina","31"=>"Nidoqueen","32"=>"Nidoran\u2642","33"=>"Nidorino","34"=>"Nidoking","35"=>"Clefairy","36"=>"Clefable","37"=>"Vulpix","38"=>"Ninetales","39"=>"Jigglypuff","40"=>"Wigglytuff","41"=>"Zubat","42"=>"Golbat","43"=>"Oddish","44"=>"Gloom","45"=>"Vileplume","46"=>"Paras","47"=>"Parasect","48"=>"Venonat","49"=>"Venomoth","50"=>"Diglett","51"=>"Dugtrio","52"=>"Meowth","53"=>"Persian","54"=>"Psyduck","55"=>"Golduck","56"=>"Mankey","57"=>"Primeape","58"=>"Growlithe","59"=>"Arcanine","60"=>"Poliwag","61"=>"Poliwhirl","62"=>"Poliwrath","63"=>"Abra","64"=>"Kadabra","65"=>"Alakazam","66"=>"Machop","67"=>"Machoke","68"=>"Machamp","69"=>"Bellsprout","70"=>"Weepinbell","71"=>"Victreebel","72"=>"Tentacool","73"=>"Tentacruel","74"=>"Geodude","75"=>"Graveler","76"=>"Golem","77"=>"Ponyta","78"=>"Rapidash","79"=>"Slowpoke","80"=>"Slowbro","81"=>"Magnemite","82"=>"Magneton","83"=>"Farfetch'd","84"=>"Doduo","85"=>"Dodrio","86"=>"Seel","87"=>"Dewgong","88"=>"Grimer","89"=>"Muk","90"=>"Shellder","91"=>"Cloyster","92"=>"Gastly","93"=>"Haunter","94"=>"Gengar","95"=>"Onix","96"=>"Drowzee","97"=>"Hypno","98"=>"Krabby","99"=>"Kingler","100"=>"Voltorb","101"=>"Electrode","102"=>"Exeggcute","103"=>"Exeggutor","104"=>"Cubone","105"=>"Marowak","106"=>"Hitmonlee","107"=>"Hitmonchan","108"=>"Lickitung","109"=>"Koffing","110"=>"Weezing","111"=>"Rhyhorn","112"=>"Rhydon","113"=>"Chansey","114"=>"Tangela","115"=>"Kangaskhan","116"=>"Horsea","117"=>"Seadra","118"=>"Goldeen","119"=>"Seaking","120"=>"Staryu","121"=>"Starmie","122"=>"Mr. Mime","123"=>"Scyther","124"=>"Jynx","125"=>"Electabuzz","126"=>"Magmar","127"=>"Pinsir","128"=>"Tauros","129"=>"Magikarp","130"=>"Gyarados","131"=>"Lapras","132"=>"Ditto","133"=>"Eevee","134"=>"Vaporeon","135"=>"Jolteon","136"=>"Flareon","137"=>"Porygon","138"=>"Omanyte","139"=>"Omastar","140"=>"Kabuto","141"=>"Kabutops","142"=>"Aerodactyl","143"=>"Snorlax","144"=>"Articuno","145"=>"Zapdos","146"=>"Moltres","147"=>"Dratini","148"=>"Dragonair","149"=>"Dragonite","150"=>"Mewtwo","151"=>"Mew"}
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __FILE__)
require 'bundler/setup' # Set up gems listed in the Gemfile.
Bundler.require(:default)
def distance_from_here(pokemon)
Geocoder::Calculations.distance_between(HOME_POSITION, [pokemon["latitude"], pokemon["longitude"]])
end
@seen = []
def mark_as_seen(pokelist)
@seen = @seen | pokelist.map { |pokemon| pokemon["id"] }
end
def inflected_minutes(n)
n == 1 ? "#{n} minute" : "#{n} minutes"
end
def pokename(pokemon)
return POKEDEX[pokemon["pokemonId"].to_s]
end
def get_new_pokemon()
response = HTTParty.get('https://pokevision.com/map/data/' + HOME_POSITION.join('/'))
if response['pokemon'].nil?
puts "Unable to fetch Pokevision data, response was:"
puts response
return []
else
new_pokemon = response['pokemon']
.select { |pokemon| pokemon["is_alive"] }
.reject { |pokemon| distance_from_here(pokemon) > SCAN_DISTANCE }
.reject { |pokemon| IGNORE.include? pokename(pokemon).downcase }
.uniq { |pokemon| pokemon["uid"] }
.uniq { |pokemon| "#{pokemon["pokemonId"]},#{pokemon["latitude"]},#{pokemon["longitude"]}" } # sometimes get dupes at the same exact position with diff IDs...
.reject { |pokemon| @seen.include? pokemon["uid"] }
mark_as_seen(new_pokemon)
new_pokemon
end
end
def make_slack_message(pokemon)
attachment = Slack::Attachment.new
attachment.fallback = "Image showing pokemon position"
attachment.image_url = "http://maps.googleapis.com/maps/api/staticmap?center=&zoom=17&scale=false&size=600x300&maptype=terrain&format=png&visual_refresh=true&markers=icon:http://ugc.pokevision.com/images/pokemon/#{pokemon["pokemonId"]}.png%7Cshadow:false%7C#{pokemon["latitude"]},#{pokemon["longitude"]}"
attachment.title = "Where's that #{pokename(pokemon)}?"
attachment.title_link = "https://pokevision.com/#/@#{pokemon["latitude"]},#{pokemon["longitude"]}"
Slack::Message.new(pokemon_message(pokemon), attachment)
end
def pokemon_message(pokemon)
minutes_remaining = ((Time.at(pokemon["expiration_time"]) - Time.now) / 60).floor;
"A wild *#{pokename(pokemon)}* appears! Despawns in #{inflected_minutes(minutes_remaining)}."
end
poster = Slack::Poster.new(WEBHOOK_URL)
poster.username = "Professor Oak"
while true do
new_pokes = get_new_pokemon
new_pokes.each do |pokemon|
message = make_slack_message(pokemon)
puts message.text
poster.send_message(message)
end
sleep 30
end
source "https://rubygems.org"
gem "httparty"
gem "geocoder"
gem "slack-poster"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment