Created
September 21, 2016 07:25
-
-
Save jvanbaarsen/d60eb18fd27cbfb74ae0030759aedbad to your computer and use it in GitHub Desktop.
Auto office joiner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# encoding: utf-8 | |
require 'net/http' | |
require 'socket' | |
LAST_SEEN_TIME_OUT = 60 * 60 * 2 # 2 hours | |
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN" | |
CHANNEL_ID = "YOUR_CHANNEL_ID" | |
CHANNEL_NAME="YOUR_CHANNEL_NAME" | |
TOKEN_OWNER = "SLACK_ID_OF_USER_THAT_OWNS_THE_TOKEN" | |
def current_ips | |
ips = [] | |
raw_data = `nmap -sn #{ip_address}/24 | grep "scan report for" | awk '{print $5}'` | |
raw_data.each_line do |line| | |
ips << line.chomp | |
end | |
ips | |
end | |
def ip_address | |
ip = Socket.ip_address_list.detect{|intf| intf.ipv4_private?} | |
return if ip.nil? | |
ip.ip_address | |
end | |
def find_mac_for_ip(ip) | |
`arp -a | grep "(#{ip})" | awk '{print $4}'`.chomp.downcase | |
end | |
def known_devices | |
{ | |
"e1:e5:c0:97:3d:0c" => "Jeroen", | |
"5d:2c:b1:62:d9:45" => "Bob", | |
"8f:70:a9:32:01:49" => "Michiel", | |
} | |
end | |
def users | |
{ | |
"jeroen" => "xxx", | |
"bob" => "yyy", | |
"michiel" => "zzz", | |
} | |
end | |
def still_in_office?(last_seen) | |
return false if last_seen.nil? | |
# Is last seen within 4 hours | |
last_seen.to_i + (LAST_SEEN_TIME_OUT) > Time.now.to_i | |
end | |
def device_to_name(device_mac) | |
known_devices[device_mac] || "Unknown device: #{device_mac}" | |
end | |
def join_channel(user_token) | |
if user_token == TOKEN_OWNER | |
Net::HTTP.get(URI("https://slack.com/api/channels.join?token=#{ACCESS_TOKEN}&name=#{CHANNEL_NAME}")) | |
else | |
Net::HTTP.get(URI("https://slack.com/api/channels.invite?token=#{ACCESS_TOKEN}&channel=#{CHANNEL_ID}&user=#{user_token}")) | |
end | |
end | |
def leave_channel(user_token) | |
if user_token == TOKEN_OWNER | |
Net::HTTP.get(URI("https://slack.com/api/channels.leave?token=#{ACCESS_TOKEN}&channel=#{CHANNEL_ID}")) | |
else | |
Net::HTTP.get(URI("https://slack.com/api/channels.kick?token=#{ACCESS_TOKEN}&channel=#{CHANNEL_ID}&user=#{user_token}")) | |
end | |
end | |
@first_run ||= true | |
loop do | |
puts "=" * 20 | |
@last_devices ||= {} | |
current_ips.each do |ip| | |
@last_devices[find_mac_for_ip(ip)] = Time.now | |
end | |
begin | |
if @first_run | |
p "Running on IP: #{ip_address}" | |
offline_devices = known_devices.reject { |device| @last_devices.include?(device) } | |
offline_devices.each do |device, name| | |
user_token = users[name.downcase] | |
leave_channel(user_token) | |
puts "#{name} was not in the office when the script started" | |
end | |
@first_run = false | |
end | |
@last_devices.each do |device, time| | |
unless known_devices.include?(device) | |
puts "Unknown device: #{device}" | |
next | |
end | |
user_token = users[device_to_name(device).downcase] | |
if user_token.nil? | |
puts "Unknown user: #{device_to_name(device).downcase} with device #{device}" | |
next | |
end | |
if still_in_office?(@last_devices[device]) | |
join_channel(user_token) | |
puts "#{device_to_name(device)} is in the office" | |
else | |
@last_devices.delete(device) | |
leave_channel(user_token) | |
puts "#{device_to_name(device)} is not in the office" | |
end | |
end | |
rescue SocketError | |
puts "No network connection, retrying in 10 seconds" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment