Repository: NARKOZ/hacker-scripts Branch: master Commit: b14a0a89bdf7 Files: 58 Total size: 67.1 KB Directory structure: gitextract_7n55pooc/ ├── CSharp/ │ ├── Hangover.cs │ └── SmackMyBitch.cs ├── R/ │ ├── hangover.R │ └── smack_my_bitch_up.R ├── README.md ├── README.zh-CN.md ├── clojure/ │ ├── coffee.clj │ ├── hangover.clj │ ├── kumar.clj │ └── smack.clj ├── coffee/ │ └── fucking.coffee ├── fucking-coffee.sh ├── fucking_coffee.rb ├── go/ │ ├── fucking-coffee.go │ ├── hangover.go │ └── smack_my_bitch_up.go ├── groovy/ │ └── fucking_coffee.groovy ├── hangover.rb ├── hangover.sh ├── java/ │ ├── FuckingCoffee.java │ ├── Hangover.java │ ├── KumarAsshole.java │ └── SmackMyBitch.java ├── kotlin/ │ ├── FuckingCoffee.kt │ ├── Hangover.kt │ ├── KumarAsshole.kt │ └── SmackMyBitch.kt ├── kumar-asshole.sh ├── kumar_asshole.rb ├── nodejs/ │ ├── fucking_coffee.js │ ├── fucking_coffee_yo_server.js │ ├── hangover.js │ ├── kumar_asshole.js │ └── smack_my_bitch_up.js ├── perl/ │ ├── fucking-coffee.pl │ ├── hangover.pl │ ├── kumar-asshole.pl │ └── smack-my-bitch-up.pl ├── php/ │ ├── composer.json │ ├── fucking_coffee.php │ ├── hangover.php │ └── smack_my_bitch_up.php ├── powershell/ │ ├── fucking_coffee.psm1 │ ├── hangover.psm1 │ └── smack_my_bitch_up.ps1 ├── python/ │ ├── fucking_coffee.py │ ├── hangover.py │ ├── kumar_asshole.py │ └── smack_my_bitch_up.py ├── python3/ │ ├── fucking_coffee.py │ ├── hackerutils.py │ ├── hangover.py │ ├── kumar_asshole.py │ ├── requirements.txt │ └── smack_my_bitch_up.py ├── scala/ │ └── fucking-coffee.scala ├── smack-my-bitch-up.sh └── smack_my_bitch_up.rb ================================================ FILE CONTENTS ================================================ ================================================ FILE: CSharp/Hangover.cs ================================================ namespace Hacker_Scripts { using System; using Twilio; using System.Linq; class Hangover { public static string TWILIO_ACCOUNT_SID = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID"); public static string AUTH_TOKEN = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN"); public static string YOUR_NUMBER = "9879789978"; public static string BOSS_NUMBER = "3213213233"; static void Main(string[] args) { var twilio = new TwilioRestClient(TWILIO_ACCOUNT_SID, AUTH_TOKEN); string[] randomMessages = { "Locked out", "Pipes broke", "Food poisoning", "Not feeling well" }; int randomIndex = new Random().Next(randomMessages.Count()); String messageToSend = (randomMessages[randomIndex]); var message = twilio.SendMessage(YOUR_NUMBER, BOSS_NUMBER, messageToSend); Console.WriteLine(message.Sid); } } } ================================================ FILE: CSharp/SmackMyBitch.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Twilio; namespace Hacker_Scripts { class SmackMyBitch { public static string TWILIO_ACCOUNT_SID = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID"); public static string AUTH_TOKEN = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN"); public static string YOUR_NUMBER = "9879789978"; public static string HER_NUMBER = "3213213233"; static void Main(string[] args) { var twilio = new TwilioRestClient(TWILIO_ACCOUNT_SID, AUTH_TOKEN); string[] randomMessages = { "Working hard", "Gotta ship this feature", "Someone fucked the system again" }; int randomIndex = new Random().Next(randomMessages.Count()); String messageToSend = (randomMessages[randomIndex]); var message = twilio.SendMessage(YOUR_NUMBER, HER_NUMBER, messageToSend); Console.WriteLine(message.Sid); } } } ================================================ FILE: R/hangover.R ================================================ library(httr) today = Sys.Date() # skip weekends if( weekdays(today) %in% c('Saturday','Sunday') ){ quit() } # exit if no sessions with my username are found output = system("who", intern = TRUE) if( !( grep('^my_user_name', output) ) ){ quit() } # returns 'None' if the key doesn't exist TWILIO_ACCOUNT_SID = Sys.getenv('TWILIO_ACCOUNT_SID') TWILIO_AUTH_TOKEN = Sys.getenv('TWILIO_AUTH_TOKEN') # Phone numbers my_number = '+xxx' number_of_boss= '+xxx' excuse = c( 'Locked out', 'Pipes broke', 'Food poisoning', 'Not feeling well' ) POST(paste("https://api.twilio.com/2010-04-01/Accounts/",TWILIO_ACCOUNT_SID,"/Messages.json",sep=""), body = list(From=my_number,To=number_of_boss,Body=paste("Gonna work from home. ", sample(excuse,1))), authenticate(TWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKEN) ) print( paste("Message sent at",Sys.time()) ) ================================================ FILE: R/smack_my_bitch_up.R ================================================ library(httr) today = Sys.Date() # skip weekends if( weekdays(today) %in% c('Saturday','Sunday') ){ quit() } # exit if no sessions with my username are found output = system("who", intern = TRUE) if( !( grep('^my_user_name', output) ) ){ quit() } # returns 'None' if the key doesn't exist TWILIO_ACCOUNT_SID = Sys.getenv('TWILIO_ACCOUNT_SID') TWILIO_AUTH_TOKEN = Sys.getenv('TWILIO_AUTH_TOKEN') # Phone numbers my_number = '+xxx' her_number = '+xxx' reasons = c( 'Working hard', 'Gotta ship this feature', 'Someone fucked the system again' ) POST(paste("https://api.twilio.com/2010-04-01/Accounts/",TWILIO_ACCOUNT_SID,"/Messages.json",sep=""), body = list(From=my_number,To=her_number,Body=paste("Late at work. ", sample(reasons,1))), authenticate(TWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKEN) ) print( paste("Message sent at",Sys.time()) ) ================================================ FILE: README.md ================================================ English | [简体中文](./README.zh-CN.md) # Hacker Scripts Based on a _[true story](https://www.jitbit.com/alexblog/249-now-thats-what-i-call-a-hacker/)_: > xxx: OK, so, our build engineer has left for another company. The dude was literally living inside the terminal. You know, that type of a guy who loves Vim, creates diagrams in Dot and writes wiki-posts in Markdown... If something - anything - requires more than 90 seconds of his time, he writes a script to automate that. > xxx: So we're sitting here, looking through his, uhm, "legacy" > xxx: You're gonna love this > xxx: [`smack-my-bitch-up.sh`](https://github.com/NARKOZ/hacker-scripts/blob/master/smack-my-bitch-up.sh) - sends a text message "late at work" to his wife (apparently). Automatically picks reasons from an array of strings, randomly. Runs inside a cron-job. The job fires if there are active SSH-sessions on the server after 9pm with his login. > xxx: [`kumar-asshole.sh`](https://github.com/NARKOZ/hacker-scripts/blob/master/kumar-asshole.sh) - scans the inbox for emails from "Kumar" (a DBA at our clients). Looks for keywords like "help", "trouble", "sorry" etc. If keywords are found - the script SSHes into the clients server and rolls back the staging database to the latest backup. Then sends a reply "no worries mate, be careful next time". > xxx: [`hangover.sh`](https://github.com/NARKOZ/hacker-scripts/blob/master/hangover.sh) - another cron-job that is set to specific dates. Sends automated emails like "not feeling well/gonna work from home" etc. Adds a random "reason" from another predefined array of strings. Fires if there are no interactive sessions on the server at 8:45am. > xxx: (and the oscar goes to) [`fucking-coffee.sh`](https://github.com/NARKOZ/hacker-scripts/blob/master/fucking-coffee.sh) - this one waits exactly 17 seconds (!), then opens a telnet session to our coffee-machine (we had no frikin idea the coffee machine is on the network, runs linux and has a TCP socket up and running) and sends something like `sys brew`. Turns out this thing starts brewing a mid-sized half-caf latte and waits another 24 (!) seconds before pouring it into a cup. The timing is exactly how long it takes to walk to the machine from the dudes desk. > xxx: holy sh*t I'm keeping those Original: http://bash.im/quote/436725 (in Russian) (Archive.org [link](https://web.archive.org/web/20210226092253/http://bash.im/quote/436725)) Pull requests with other implementations (Python, Perl, Shell, etc) are welcome. ## Usage You need these environment variables: ```sh # used in `smack-my-bitch-up` and `hangover` scripts TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx TWILIO_AUTH_TOKEN=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy # used in `kumar_asshole` script GMAIL_USERNAME=admin@example.org GMAIL_PASSWORD=password ``` For Ruby scripts you need to install gems: `gem install dotenv twilio-ruby gmail` ## Cron jobs ```sh # Runs `smack-my-bitch-up.sh` monday to friday at 9:20 pm. 20 21 * * 1-5 /path/to/scripts/smack-my-bitch-up.sh >> /path/to/smack-my-bitch-up.log 2>&1 # Runs `hangover.sh` monday to friday at 8:45 am. 45 8 * * 1-5 /path/to/scripts/hangover.sh >> /path/to/hangover.log 2>&1 # Runs `kumar-asshole.sh` every 10 minutes. */10 * * * * /path/to/scripts/kumar-asshole.sh # Runs `fucking-coffee.sh` hourly from 9am to 6pm on weekdays. 0 9-18 * * 1-5 /path/to/scripts/fucking-coffee.sh ``` --- Code is released under WTFPL. ================================================ FILE: README.zh-CN.md ================================================ # Hacker Scripts 根据 *[真实故事](https://www.jitbit.com/alexblog/249-now-thats-what-i-call-a-hacker/)* 改编: > xxx: 是这样的,我们的构建工程师离职去了另外一家公司,这货基本算是生活在终端里。 你知道么,这人热爱Vim,用Dot作图,甚至用MarkDown来写维基帖子...,如果有什么事情要花上他超过90秒,他一定会整个脚本来让这件事变得“自动化”。 > xxx: 我们现在坐在他的工位上,看着他留下来的这些,呃,“遗产”? > xxx: 我觉得你们会喜欢这些的 > xxx: [`smack-my-bitch-up.sh(拍老婆马屁脚本)`](https://github.com/NARKOZ/hacker-scripts/blob/master/smack-my-bitch-up.sh) - 它会给他的老婆(很明显是他老婆)发送一条“今晚要加班了”的短信,再自动从文本库中随机地选择一条理由。这个脚本被设置为定时触发,而且只有在工作日晚9点以后,服务器上还有他登陆的SSH进程在运行时才会执行。 > xxx: [`kumar-asshole.sh(库马尔个傻*)`](https://github.com/NARKOZ/hacker-scripts/blob/master/kumar-asshole.sh) - 这个脚本会自动扫描邮箱,如果发现其中有库马尔(库马尔是我们客户公司的一位数据库管理员)发来的邮件,就会在其中寻找关键字如“求助”,“遇到麻烦了”,“抱歉”等等,如果发现了这些关键字,这个脚本会通过SSH连接上客户公司的服务器,把中间数据库(staging database)回滚到最新一次的可用备份。然后它会给邮件发送回复,“没事了哥们,下次小心点哈”。 > xxx: [`hangover.sh(宿醉)`](https://github.com/NARKOZ/hacker-scripts/blob/master/hangover.sh) - 同样是个定时执行的任务,被设置为在特定日期触发,它会自动发送诸如“今天不太舒服”或“今天我在家上班”之类的邮件,同样会从文本库里随机选取一条理由。这个任务会在工作日清晨8点45分以后服务器上仍然没有可交互的SSH进程时真正执行。 > xxx: (最牛的就是接下来这个) [`fucking-coffee.sh(**的咖啡)`](https://github.com/NARKOZ/hacker-scripts/blob/master/fucking-coffee.sh) - 这个脚本在启动之后,会先等待恰好17秒(!),然后启动一个登录进程连接到我们的咖啡机(淦,我们之前完全不知道我们的咖啡机是联网的,上面还运行着Linux系统,甚至还跑着TCP socket连接!),然后它会发送类似“系统!开始煮咖啡!”之类的消息,结果这条消息会让咖啡机开始工作,煮一杯 中杯大小、半咖啡因的拿铁,再等待恰好24秒(!)后,才倒进咖啡杯里。这些时间加起来刚好就是这位程序员从自己的工位走到机器前要的时间。 > xxx: 天了噜我要把这些保留下来。 原文: http://bash.im/quote/436725 (俄语) 欢迎使用其它语言来实现 (Python, Perl, Shell等等)并提交PR。 ## 用法 你需要以下这些环境变量: ```bash # used in `smack-my-bitch-up` and `hangover` scripts TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx TWILIO_AUTH_TOKEN=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy # used in `kumar_asshole` script GMAIL_USERNAME=admin@example.org GMAIL_PASSWORD=password ``` 为了执行Ruby脚本,你需要安装gems: `gem install dotenv twilio-ruby gmail` ## 定时任务 ```bash # Runs `smack-my-bitch-up.sh` monday to friday at 9:20 pm. 20 21 * * 1-5 /path/to/scripts/smack-my-bitch-up.sh >> /path/to/smack-my-bitch-up.log 2>&1 # Runs `hangover.sh` monday to friday at 8:45 am. 45 8 * * 1-5 /path/to/scripts/hangover.sh >> /path/to/hangover.log 2>&1 # Runs `kumar-asshole.sh` every 10 minutes. */10 * * * * /path/to/scripts/kumar-asshole.sh # Runs `fucking-coffee.sh` hourly from 9am to 6pm on weekdays. 0 9-18 * * 1-5 /path/to/scripts/fucking-coffee.sh ``` ------ 代码的使用遵循WTFPL(Do What The Fuck You Want To Public License)协议。 ================================================ FILE: clojure/coffee.clj ================================================ (ns hacker-scripts.coffee (:require [environ.core :refer [env]]) (:import (java.net Socket) (java.io BufferedReader PrintWriter InputStreamReader))) (def my-username "my-username") (def my-password "my-password") (def coffee-machine-ip "10.10.42.42") (def password-prompt "Password: ") (def connection-port 23) (def sec-delay-before-brew 17) (def sec-delay-before-pour 24) (defn logged-in? [] (= (:USER env) my-username)) (defn auth [in-stream out-stream] (if (= (.readLine in-stream) password-prompt) (.println out-stream my-password) (throw (RuntimeException. "Failed to authenticate with coffee machine")))) (defn command-brew-pour [out-stream] (do (Thread/sleep (* 1000 sec-delay-before-brew)) (.println out-stream "sys brew") (Thread/sleep (* 1000 sec-delay-before-pour)) (.println out-stream "sys pour"))) (defn coffee [] (if (logged-in?) (with-open [socket (Socket. coffee-machine-ip connection-port) out-stream (PrintWriter. (.getOutputStream socket) true) in-stream (BufferedReader. (InputStreamReader. (.getInputStream socket)))] (do (auth in-stream out-stream) (command-brew-pour out-stream))))) ================================================ FILE: clojure/hangover.clj ================================================ (ns hacker-scripts.hangover (:import (com.twilio Twilio) (com.twilio.rest.api.v2010.account Message) (com.twilio.type PhoneNumber))) (def acc-sid "my twilio account SID") (def acc-tkn "my twilio secret token") (def my-num (PhoneNumber. "+10001112222")) (def boss-num (PhoneNumber. "+19998887777")) (def reasons ["Receiving delivery" "Waiting for repairman" "Nasty cold"]) (defn twilio-init [] (Twilio/init acc-sid acc-tkn)) (defn send-sms [to-num from-num message] (.. Message (creator to-num from-num message) create)) (def send-sms-boss (partial send-sms boss-num my-num)) (defn hangover [] (twilio-init) (let [message (rand-nth reasons)] (send-sms-boss message))) ================================================ FILE: clojure/kumar.clj ================================================ (ns hacker-scripts.kumar (:import (java.util Properties) (javax.mail Session Authenticator PasswordAuthentication Message$RecipientType Transport Folder Flags Flags$Flag) (javax.mail.internet MimeMessage InternetAddress) (javax.mail.search FlagTerm FromTerm AndTerm OrTerm SubjectTerm BodyTerm SearchTerm))) (def host "smtp.gmail.com") (def my-email "my-email@gmail.com") (def my-password "my-gmail-password") (def kumar-email "kumar@gmail.com") (def seen-flag (Flags. (Flags$Flag/SEEN))) (def unread-term (FlagTerm. seen-flag false)) (defn get-session [] (let [authenticator (proxy [Authenticator] [] (getPasswordAuthentication [] (PasswordAuthentication. my-email my-password))) props (Properties.)] (.put props "mail.smtp.host" "smtp.gmail.com") (.put props "mail.smtp.port" "587") (.put props "mail.smtp.auth" "true") (.put props "mail.smtp.starttls.enable" "true") (.. Session (getInstance props authenticator)))) (defn get-inbox [session] (let [store (.getStore session "imaps") inbox (do (.connect store host my-email my-password) (.getFolder store "inbox"))] (.open inbox Folder/READ_WRITE) inbox)) (defn get-no-worries-message [session] (let [message (MimeMessage. session)] (.setFrom message (InternetAddress. my-email)) (.addRecipient message Message$RecipientType/TO (InternetAddress. kumar-email)) (.setSubject message "Database fixes") (.setText message "No worries mate, be careful next time") message)) (defn search-term [pattern] (OrTerm. (into-array SearchTerm [(SubjectTerm. pattern) (BodyTerm. pattern)]))) (defn any-of-search-term [& patterns] (OrTerm. (into-array (map search-term patterns)))) (defn from-term [addr] (FromTerm. (InternetAddress. addr))) (defn get-unread-sos-from-kumar [inbox] (let [flag (AndTerm. (into-array SearchTerm [unread-term (from-term kumar-email) (any-of-search-term "help" "sorry" "trouble")]))] (.search inbox flag))) (defn mark-as-read [inbox messages] (.setFlags inbox messages seen-flag true)) (defn kumar-asshole [] (let [session (get-session) inbox (get-inbox session) unread-sos-from-kumar (get-unread-sos-from-kumar inbox)] (when (seq unread-sos-from-kumar) (mark-as-read inbox unread-sos-from-kumar) (Transport/send (get-no-worries-message session))))) ================================================ FILE: clojure/smack.clj ================================================ (ns hacker-scripts.smack (:import (com.twilio Twilio) (com.twilio.rest.api.v2010.account Message) (com.twilio.type PhoneNumber))) (def acc-sid "my twilio account SID") (def acc-tkn "my twilio secret token") (def my-num (PhoneNumber. "+10001112222")) (def her-num (PhoneNumber. "+19998887777")) (def reasons ["Working hard" "Gotta ship this feature" "Someone fucked the system again"]) (defn twilio-init [] (Twilio/init acc-sid acc-tkn)) (defn send-sms [to-num from-num message] (.. Message (creator to-num from-num message) create)) (def send-sms-girlfriend (partial send-sms her-num my-num)) (defn smack [] (twilio-init) (let [message (rand-nth reasons)] (send-sms-girlfriend message))) ================================================ FILE: coffee/fucking.coffee ================================================ #!/usr/bin/env coffee username = 'name' host = 'localhost' port = '3000' pass = '5555' sh = require('child_process').execSync # weekend process.exit 0 if new Date().getDay() in [6, 0] # no sessions process.exit 0 unless new RegExp(username).test sh('who -q').toString() conn = require('net').createConnection port, host setTimeout -> conn.write "#{pass}\nsys brew\n" setTimeout -> conn.end 'sys pour' process.exit 0 , 2 * 1000 , 1 * 1000 # alert sh 'say come here and take your fucking coffee' ================================================ FILE: fucking-coffee.sh ================================================ #!/bin/sh # # Requires fucking_coffee script in your bin # exec fucking_coffee ================================================ FILE: fucking_coffee.rb ================================================ #!/usr/bin/env ruby # Exit early if no sessions with my username are found exit unless `who -q`.include? ENV['USER'] require 'net/telnet' coffee_machine_ip = '10.10.42.42' password = '1234' password_prompt = 'Password: ' delay_before_brew = 17 delay = 24 sleep delay_before_brew con = Net::Telnet.new('Host' => coffee_machine_ip) con.cmd('String' => password, 'Match' => /#{password_prompt}/) con.cmd('sys brew') sleep delay con.cmd('sys pour') con.close ================================================ FILE: go/fucking-coffee.go ================================================ package main import ( "fmt" "log" "os" "regexp" "time" "github.com/codeskyblue/go-sh" "github.com/google/goexpect" ) func main() { // exit early if no sessions with my username are found currentUser, _ := sh.Command("who").Command("grep", "my_username").Output() if currentUser == nil { os.Exit(1) } // info about the coffee machine coffeeMachineIP := "10.10.42.42" password := "1234" passwordPrompt := "Password: " delayBeforeBrew := 17 * time.Second delay := 24 * time.Second // timeout for the telnet prompts timeout := 10 * time.Minute // sleep 17 seconds before brewing coffee time.Sleep(delayBeforeBrew) // spawn a new telnet session with the coffee machine t, _, err := expect.Spawn(fmt.Sprintf("telnet %s", coffeeMachineIP), -1) if err != nil { log.Fatal(err) } defer t.Close() t.Expect(regexp.MustCompile(passwordPrompt), timeout) t.Send(password + "\n") t.Expect(regexp.MustCompile("telnet>"), timeout) t.Send("sys brew\n") time.Sleep(delay) t.Expect(regexp.MustCompile("telnet>"), timeout) t.Send("sys pour\n") t.Expect(regexp.MustCompile("telnet>"), timeout) t.Send("exit\n") } ================================================ FILE: go/hangover.go ================================================ package main import ( "fmt" "log" "math/rand" "os" "github.com/codeskyblue/go-sh" "github.com/subosito/twilio" ) const my_number string = "+xxxxx" const boss_number string = "+yyyyy" func main() { //exit if sessions with my username are found _, err := sh.Command("who").Command("grep", "my_username").Output() if err != nil { os.Exit(1) } //Grab Twilio ID and token from environment variables Account_Sid := os.Getenv("TWILIO_ACCOUNT_SID") Auth_Token := os.Getenv("TWILIO_AUTH_TOKEN") //create the reasons slice and append reasons to it reasons := make([]string, 0) reasons = append(reasons, "Locked out", "Pipes broke", "Food poisoning", "Not feeling well") // Initialize Twilio client and send message client := twilio.NewClient(Account_Sid, Auth_Token, nil) message := fmt.Sprint("Gonna work from home...", reasons[rand.Intn(len(reasons))]) params := twilio.MessageParams{ Body: message, } s, resp, err := client.Messages.Send(my_number, boss_number, params) if err == nil { log.Fatal(s, resp, err) } } ================================================ FILE: go/smack_my_bitch_up.go ================================================ package main import ( "fmt" "math/rand" "os" "os/exec" "strings" "time" ) func main() { output1, err := exec.Command("who").Output() output2 := os.Getenv("USER") users := string(output1[:]) current_user := string(output2[:]) if !strings.Contains(users, current_user) { return } reasons := []string{"Working hard", "Gotta ship this feature", "Someone fucked the system again"} rand.Seed(time.Now().UTC().UnixNano()) message := "Late at work. " + reasons[rand.Intn(len(reasons))] TWILIO_ACCOUNT_SID := string(os.Getenv("TWILIO_ACCOUNT_SID")) TWILIO_AUTH_TOKEN := string(os.Getenv("TWILIO_AUTH_TOKEN")) MY_NUMBER := string(os.Getenv("MY_NUMBER")) HER_NUMBER := string(os.Getenv("HER_NUMBER")) response, err := exec.Command("curl", "-fSs", "-u", TWILIO_ACCOUNT_SID+":"+TWILIO_AUTH_TOKEN, "-d", "From="+MY_NUMBER, "-d", "To="+HER_NUMBER, "-d", "Body="+message, "https://api.twilio.com/2010-04-01/Accounts/"+TWILIO_ACCOUNT_SID+"/Messages").Output() if err != nil { fmt.Printf("Failed to send SMS: %s", err) return } fmt.Printf("Message Sent Successfully with response: %s ", response) } ================================================ FILE: groovy/fucking_coffee.groovy ================================================ @Grab(group='org.hidetake', module='groovy-ssh', version='1.1.8') @GrabExclude('org.codehaus.groovy:groovy-all') import org.hidetake.groovy.ssh.Ssh final def ssh = Ssh.newService() final def HOST = '10.10.42.42' final def USER = 'my_username' final def PASSWORD = '1234' final def DELAY = 24 ssh.remotes { webServer { host = HOST user = USER password = PASSWORD } } ssh.run { session(ssh.remotes.webServer) { execute 'sys brew' execute "sleep ${DELAY}s" execute 'sys pour' } } ================================================ FILE: hangover.rb ================================================ #!/usr/bin/env ruby # Exit early if sessions with my username are found exit if `who -q`.include? ENV['USER'] require 'dotenv' require 'twilio-ruby' Dotenv.load TWILIO_ACCOUNT_SID = ENV['TWILIO_ACCOUNT_SID'] TWILIO_AUTH_TOKEN = ENV['TWILIO_AUTH_TOKEN'] @twilio = Twilio::REST::Client.new TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN # Phone numbers my_number = '+xxx' number_of_boss = '+xxx' excuse = [ 'Locked out', 'Pipes broke', 'Food poisoning', 'Not feeling well' ].sample # Send a text message @twilio.messages.create( from: my_number, to: number_of_boss, body: "Gonna work from home. #{excuse}" ) # Log this puts "Message sent at: #{Time.now} | Excuse: #{excuse}" ================================================ FILE: hangover.sh ================================================ #!/bin/sh -e # Exit early if any session with my username is found if who | grep -wq $USER; then exit fi # Phone numbers MY_NUMBER='+xxx' NUMBER_OF_BOSS='+xxx' EXCUSES=( 'Locked out' 'Pipes broke' 'Food poisoning' 'Not feeling well' ) rand=$[ $RANDOM % ${#EXCUSES[@]} ] RANDOM_EXCUSE=${EXCUSES[$rand]} MESSAGE="Gonna work from home. "$RANDOM_EXCUSE # Send a text message RESPONSE=`curl -fSs -u "$TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN" \ -d "From=$MY_NUMBER" -d "To=$NUMBER_OF_BOSS" -d "Body=$MESSAGE" \ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Messages"` # Log errors if [ $? -gt 0 ]; then echo "Failed to send SMS: $RESPONSE" exit 1 fi ================================================ FILE: java/FuckingCoffee.java ================================================ import java.net.*; import java.io.*; public class FuckingCoffee{ private static final String MY_USERNAME = "my_username"; private static final String PASSWORD_PROMPT = "Password: "; private static final String PASSWORD = "1234"; private static final String COFFEE_MACHINE_IP = "10.10.42.42"; private static int DELAY_BEFORE_BREW = 17; private static int DELAY = 24; public static void main(String[] args)throws Exception{ for(int i = 1; i< args.length ; i++){ if(!args[i].contains(MY_USERNAME)){ return; } } Socket telnet = new Socket(COFFEE_MACHINE_IP, 23); PrintWriter out = new PrintWriter(telnet.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(telnet.getInputStream())); Thread.sleep(DELAY_BEFORE_BREW*1000); if(!in.readLine().equals(PASSWORD_PROMPT)){ return ; } out.println(PASSWORD); out.println("sys brew"); Thread.sleep(DELAY*1000); out.println("sys pour"); out.close(); in.close(); telnet.close(); } } ================================================ FILE: java/Hangover.java ================================================ import com.twilio.sdk.TwilioRestClient; import com.twilio.sdk.TwilioRestException; import com.twilio.sdk.resource.factory.MessageFactory; import com.twilio.sdk.resource.instance.Message; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import java.util.ArrayList; import java.util.List; import java.util.Random; public class Hangover { public static final String ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID"); public static final String AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN"); public static final String YOUR_NUMBER = "1231231231"; public static final String BOSS_NUMBER = "3213213213"; public static void main(String[] args) throws TwilioRestException { TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN); String[] randomMessages = { "Locked out", "Pipes broke", "Food poisoning", "Not feeling well" }; int randomIndex = new Random().nextInt(randomMessages.length); String finalMessage = (randomMessages[randomIndex]); List params = new ArrayList(); params.add(new BasicNameValuePair("Body", "Gonna work from home. " + finalMessage)); params.add(new BasicNameValuePair("From", YOUR_NUMBER)); params.add(new BasicNameValuePair("To", BOSS_NUMBER)); MessageFactory messageFactory = client.getAccount().getMessageFactory(); Message message = messageFactory.create(params); System.out.println(message.getSid()); } } ================================================ FILE: java/KumarAsshole.java ================================================ import java.io.File; import java.io.FileInputStream; import java.util.*; import java.util.regex.*; import javax.mail.*; import javax.mail.internet.*; import javax.mail.search.FlagTerm; //Dependencies- Java mail API public class KumarAsshole { public static void main(String[] args) { KumarAsshole asshole = new KumarAsshole(); asshole.read(); } public void read() { Properties props = new Properties(); //modify below properties to your details String host = "smtp.gmail.com"; String username = "yourmailaddress@example.com goes here"; String password = "your password goes here "; String Kumar_mail = "the mail address to be replied to !"; try { Session session = Session.getDefaultInstance(props, null); Store store = session.getStore("imaps"); store.connect(host, username, password); Folder inbox = store.getFolder("inbox"); inbox.open(Folder.READ_ONLY); Message messages[] = inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false)); for (int i = 0; i < messages.length; i++) { if (messages[i].getFrom()[0].toString().contains(Kumar_mail)) { String bodytext = null; Object content = messages[i].getContent(); if (content instanceof String) { bodytext = (String) content; } else if (content instanceof Multipart) { Multipart mp = (Multipart) content; BodyPart bp = mp.getBodyPart(mp.getCount() - 1); bodytext = (String) bp.getContent(); } Pattern pattern = Pattern.compile("sorry|help|wrong", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(bodytext); // check all occurance if (matcher.find()) { Properties props1 = new Properties(); Address[] tomail; MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress(username)); tomail = messages[i].getFrom(); String t1 = tomail[0].toString(); msg.addRecipient(Message.RecipientType.TO, new InternetAddress(t1)); msg.setSubject("Database fixes"); msg.setText("No problem. I've fixed it. \n\n Please be careful next time."); Transport t = null; t = session.getTransport("smtps"); t.connect(host, username, password); t.sendMessage(msg, msg.getAllRecipients()); } } } inbox.close(true); store.close(); } catch(Exception e) { e.printStackTrace(); } } } ================================================ FILE: java/SmackMyBitch.java ================================================ import com.twilio.sdk.TwilioRestClient; import com.twilio.sdk.TwilioRestException; import com.twilio.sdk.resource.factory.MessageFactory; import com.twilio.sdk.resource.instance.Message; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import java.util.ArrayList; import java.util.List; import java.util.Random; //Pre-requisite apache http and twilio java libraries public class SmackMyBitch { public static final String ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID"); public static final String AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN"); public static final String YOUR_NUMBER = "1231231231"; public static final String HER_NUMBER = "3213213213"; public static void main(String[] args) throws TwilioRestException { TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN); String[] randomMessages = { "Working hard", "Gotta ship this feature", "Someone fucked the system again", }; int randomIndex = new Random().nextInt(randomMessages.length); String finalMessage = (randomMessages[randomIndex]); List params = new ArrayList(); params.add(new BasicNameValuePair("Body", "Late at work. " + finalMessage)); params.add(new BasicNameValuePair("From", YOUR_NUMBER)); params.add(new BasicNameValuePair("To", HER_NUMBER)); MessageFactory messageFactory = client.getAccount().getMessageFactory(); Message message = messageFactory.create(params); System.out.println(message.getSid()); } } ================================================ FILE: kotlin/FuckingCoffee.kt ================================================ import java.io.BufferedReader import java.io.InputStreamReader import java.io.PrintWriter import java.net.Socket private const val MY_USERNAME = "my_username" private const val PASSWORD_PROMPT = "Password: " private const val PASSWORD = "1234" private const val COFFEE_MACHINE_IP = "10.10.42.42" private const val DELAY_BEFORE_BREW = 17 private const val DELAY = 24 fun main(args: Array) { for (i in 1 until args.size) { if (!args[i].contains(MY_USERNAME)) { return } } val telnet = Socket(COFFEE_MACHINE_IP, 23) val out = PrintWriter(telnet.getOutputStream(), true) val reader = BufferedReader(InputStreamReader(telnet.getInputStream())) Thread.sleep((DELAY_BEFORE_BREW * 1000).toLong()) if (reader.readLine() != PASSWORD_PROMPT) { return } out.println(PASSWORD) out.println("sys brew") Thread.sleep((DELAY * 1000).toLong()) out.println("sys pour") out.close() reader.close() telnet.close() } ================================================ FILE: kotlin/Hangover.kt ================================================ import com.twilio.sdk.TwilioRestClient import com.twilio.sdk.TwilioRestException import com.twilio.sdk.resource.factory.MessageFactory import com.twilio.sdk.resource.instance.Message import org.apache.http.NameValuePair import org.apache.http.message.BasicNameValuePair import java.util.ArrayList import java.util.Random private val ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID") private val AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN") private const val YOUR_NUMBER = "1231231231" private const val BOSS_NUMBER = "3213213213" private val randomMessages = arrayOf( "Locked out", "Pipes broke", "Food poisoning", "Not feeling well" ) fun main() { val client = TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN) val finalMessage = randomMessages.random() val params = ArrayList().apply { add(BasicNameValuePair("Body", "Gonna work from home. $finalMessage")) add(BasicNameValuePair("From", YOUR_NUMBER)) add(BasicNameValuePair("To", BOSS_NUMBER)) } val messageFactory = client.getAccount().getMessageFactory() val message = messageFactory.create(params) System.out.println(message.getSid()) } ================================================ FILE: kotlin/KumarAsshole.kt ================================================ import java.io.File import java.io.FileInputStream import java.util.* import java.util.regex.* import javax.mail.* import javax.mail.internet.* import javax.mail.search.FlagTerm //modify below properties to your details private const val host = "smtp.gmail.com" private const val username = "yourmailaddress@example.com goes here" private const val password = "your password goes here " private const val Kumar_mail = "the mail address to be replied to !" //Dependencies- Java mail API fun main() { val asshole = KumarAsshole() asshole.read() } object KumarAsshole { fun read() { val props = Properties() try { val session = Session.getDefaultInstance(props, null) val store = session.getStore("imaps") store.connect(host, username, password) val inbox = store.getFolder("inbox") inbox.open(Folder.READ_ONLY) val messages = inbox.search(FlagTerm(Flags(Flags.Flag.SEEN), false)) for (i in messages.indices) { if (messages[i].getFrom()[0].toString().contains(Kumar_mail)) { var bodytext: String? = null val content = messages[i].getContent() if (content is String) { bodytext = content } else if (content is Multipart) { val mp = content as Multipart val bp = mp.getBodyPart(mp.getCount() - 1) bodytext = bp.getContent() } val pattern = Pattern.compile("sorry|help|wrong", Pattern.CASE_INSENSITIVE) val matcher = pattern.matcher(bodytext!!) // check all occurance if (matcher.find()) { val props1 = Properties() val tomail: Array
val msg = MimeMessage(session) msg.setFrom(InternetAddress(username)) tomail = messages[i].getFrom() val t1 = tomail[0].toString() msg.addRecipient(Message.RecipientType.TO, InternetAddress(t1)) msg.setSubject("Database fixes") msg.setText("No problem. I've fixed it. \n\n Please be careful next time.") var t: Transport? = null t = session.getTransport("smtps") t!!.connect(host, username, password) t!!.sendMessage(msg, msg.getAllRecipients()) } } } inbox.close(true) store.close() } catch (e: Exception) { e.printStackTrace() } } } ================================================ FILE: kotlin/SmackMyBitch.kt ================================================ import com.twilio.sdk.TwilioRestClient import com.twilio.sdk.TwilioRestException import com.twilio.sdk.resource.factory.MessageFactory import com.twilio.sdk.resource.instance.Message import org.apache.http.NameValuePair import org.apache.http.message.BasicNameValuePair import java.util.ArrayList import java.util.Random //Pre-requisite apache http and twilio java libraries private const val ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID") private const val AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN") private const val YOUR_NUMBER = "1231231231" private const val HER_NUMBER = "3213213213" private val randomMessages = arrayOf( "Working hard", "Gotta ship this feature", "Someone fucked the system again" ) @Throws(TwilioRestException::class) fun main() { val client = TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN) val finalMessage = randomMessages.random() val params = mutableListOf().apply { add(BasicNameValuePair("Body", "Late at work. $finalMessage")) add(BasicNameValuePair("From", YOUR_NUMBER)) add(BasicNameValuePair("To", HER_NUMBER)) } val messageFactory = client.getAccount().getMessageFactory() val message = messageFactory.create(params) System.out.println(message.getSid()) } ================================================ FILE: kumar-asshole.sh ================================================ #!/bin/sh # # Requires kumar_asshole script in your bin # exec kumar_asshole ================================================ FILE: kumar_asshole.rb ================================================ #!/usr/bin/env ruby require 'dotenv' require 'gmail' Dotenv.load GMAIL_USERNAME = ENV['GMAIL_USERNAME'] GMAIL_PASSWORD = ENV['GMAIL_PASSWORD'] GMAIL = Gmail.connect(GMAIL_USERNAME, GMAIL_PASSWORD) KUMARS_EMAIL = 'kumar.a@example.com' DB_NAME_REGEX = /\S+_staging/ KEYWORDS_REGEX = /sorry|help|wrong/i def create_reply(subject) GMAIL.compose do to KUMARS_EMAIL subject "RE: #{subject}" body "No problem. I've fixed it. \n\n Please be careful next time." end end GMAIL.inbox.find(:unread, from: KUMARS_EMAIL).each do |email| if email.body.raw_source[KEYWORDS_REGEX] && (db_name = email.body.raw_source[DB_NAME_REGEX]) backup_file = "/home/backups/databases/#{db_name}-" + (Date.today - 1).strftime('%Y%m%d') + '.gz' abort 'ERROR: Backup file not found' unless File.exist?(backup_file) # Restore DB `gunzip -c #{backup_file} | psql #{db_name}` # Mark as read, add label and reply email.read! email.label('Database fixes') reply = create_reply(email.subject) GMAIL.deliver(reply) end end ================================================ FILE: nodejs/fucking_coffee.js ================================================ #!/usr/bin/env node /* Before running: npm install telnet-client */ var exec = require('child_process').exec; var telnet = require('telnet-client'); var me = 'my_username'; exec("who", function(error, stdout, stderr) { // Exit if no sessions with my username are found if(stdout.indexOf(me) == -1) process.exit(/*1*/); var coffee_machine_ip = 'xxx.xxx.xxx.xxx'; var password = 'xxxx'; var con = new telnet(); con.on('ready', function(prompt) { con.exec('Password: ' + password, function(error, res) { // Brew Coffee! con.exec('sys brew', function(error, res) { // Wait for 24s setTimeout(function() { // Pour Coffee! con.exec('sys pour', function(error, res) { con.end(); }); }, 24000); }); }); }); con.connect({host: coffee_machine_ip}); }); ================================================ FILE: nodejs/fucking_coffee_yo_server.js ================================================ #!/usr/bin/env node /* Before running: Setup Yo Callback URL and Yo username for coffee machine: http://docs.justyo.co/docs/receiving-a-yo-with-the-api */ var exec = require('child_process').exec; var telnet = require('telnet-client'); var ME = 'my_username'; var AUTHORIZED_YO_NAMES = [ME]; var COFFEE_MACHINE_YO_NAME = 'coffeemachine'; // These should be same as what you set up in the Yo API var CALLBACK_URL = 'http://xxx.com'; var CALLBACK_ENDPOINT = '/coffeemachine'; var PORT = '3000'; exec("who -q", function(error, stdout, stderr) { var express = require('express'); var coffeeApp = express(); // Exit if no sessions with my username are found if(stdout.indexOf(ME) == -1) process.exit(1); // Got a Yo! coffeeApp.get(CALLBACK_ENDPOINT, function (req, res) { if(req.query.username === undefined) { // Not a Yo, don't make coffee. res.sendStatus(401); } else if(AUTHORIZED_YO_NAMES.indexOf(req.query.username) == -1) { // If authorized users didn't Yo, don't make coffee. res.sendStatus(401); console.log(req.query.username + ' YO\'d.') } else { res.sendStatus(200); var coffee_machine_ip = 'xxx.xxx.xxx.xxx'; var password = 'xxxx'; var con = new telnet(); con.on('ready', function(prompt) { con.exec('Password: ' + password, function(error, res) { // Brew Coffee! con.exec('sys brew', function(error, res) { // Wait for 24s setTimeout(function() { // Pour Coffee! con.exec('sys pour', function(error, res) { con.end(); }); }, 24000); }); }); }); con.connect({host: coffee_machine_ip}); } }); // Not Callback endpoint coffeeApp.get('/*', function (req, res) { res.sendStatus(404); }); var coffeeServer = coffeeApp.listen(PORT, CALLBACK_URL, function() { console.log('Coffee Server listening at %s:%s', CALLBACK_URL, PORT); console.log('\nYo Callback URL: %s:%s/%s', CALLBACK_URL, PORT, CALLBACK_ENDPOINT); }); }); ================================================ FILE: nodejs/hangover.js ================================================ #!/usr/bin/env node /* Before running: npm install twilio */ var exec = require('child_process').exec; var me = 'my_username'; exec("who -q", function(error, stdout, stderr) { // Exit if sessions with my username are found if(stdout.indexOf(me) > -1) process.exit(1); var TWILIO_ACCOUNT_SID = process.env['TWILIO_ACCOUNT_SID']; var TWILIO_AUTH_TOKEN = process.env['TWILIO_AUTH_TOKEN']; // Phone numbers var MY_NUMBER = '+xxx'; var BOSS_NUMBER = '+xxx'; // Excuses var excuses = [ 'Locked out', 'Pipes broke', 'Food poisoning', 'Not feeling well' ]; // Generate BS message var excuse = excuses[Math.floor(Math.random() * excuses.length)]; var textMessage = 'Gonna work from home. ' + excuse; var client = require('twilio')(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN); // Shoot text client.messages.create({ body: textMessage, to: BOSS_NUMBER, from: MY_NUMBER }, function(error, message) { if(error) console.log('Failed to send SMS: ' + error.message); else { var currentdate = new Date(); console.log('Message sent at: '+ (currentdate.getMonth() + 1) + '/' + currentdate.getDate() + '/' + currentdate.getFullYear() + ' ' + currentdate.getHours() + ':' + currentdate.getMinutes() + ':' + currentdate.getSeconds() + '| Excuse: ' + excuse); } }); }); ================================================ FILE: nodejs/kumar_asshole.js ================================================ #!/usr/bin/env node /* Before running: npm install nodemailer npm install imap I realize this is long. IMAP can only fetch emails and nodemailer can only send. Could try implementing with Gmail Node API later. */ var GMAIL_USERNAME = process.env['GMAIL_USERNAME']; var GMAIL_PASSWORD = process.env['GMAIL_PASSWORD']; var KUMAR_EMAIL = 'kumar.asshole@example.com'; var EMAIL = 'No worries mate, be careful next time'; // Scan for unread email from Kumar var Imap = require('imap'); var imap = new Imap({ user: GMAIL_USERNAME, password: GMAIL_PASSWORD, host: 'imap.gmail.com', port: 993, tls: true, tlsOptions: { rejectUnauthorized: false } }); function openInbox(cb) { imap.openBox('INBOX', false, cb); } imap.once('ready', function() { openInbox(function(err, box) { if (err) process.exit(1); imap.search(['UNSEEN', ['FROM', KUMAR_EMAIL]], function(err, results) { if (err) process.exit(1); // RegEx search for keywords; ignore case var kumarPattern = new RegExp(/sorry|help|wrong/i); // IMAP dumps all headers, so need to parse and get email body var MailParser = require("mailparser").MailParser; var f = imap.fetch(results, {bodies: ''}); f.on('message', function(msg, seqno) { msg.on('body', function(stream, info) { var kumarEmail = ""; stream.on('data', function(chunk) { kumarEmail += chunk.toString('utf8'); }); stream.once('end', function() { var mailparser = new MailParser(); mailparser.on("end", function(mail_object){ // If the RegEx matches if(mail_object.text.match(kumarPattern)) { // Shoot email to Kumar! var nodemailer = require('nodemailer'); // create reusable transporter object using SMTP transport var transporter = nodemailer.createTransport({ service: 'Gmail', auth: { user: GMAIL_USERNAME, pass: GMAIL_PASSWORD } }); // setup e-mail data var mailOptions = { from: GMAIL_USERNAME, to: KUMAR_EMAIL, subject: 'Database Fixes', text: EMAIL }; // send mail with defined transport object transporter.sendMail(mailOptions, function(error, info) { if(error) process.exit(1) }); } }); mailparser.write(kumarEmail); mailparser.end(); }); }); msg.once('end', function() { // Fetched all unread from kumar }); }); f.once('error', function(err) { process.exit(1); }); f.once('end', function() { imap.end(); }); }); }); }); imap.connect(); ================================================ FILE: nodejs/smack_my_bitch_up.js ================================================ #!/usr/bin/env node /* Before running: npm install twilio */ var exec = require('child_process').exec; var me = 'my_username'; exec("who -q", function(error, stdout, stderr) { // Exit if no sessions with my username are found if(stdout.indexOf(me) == -1) process.exit(1); var TWILIO_ACCOUNT_SID = process.env['TWILIO_ACCOUNT_SID']; var TWILIO_AUTH_TOKEN = process.env['TWILIO_AUTH_TOKEN']; // Phone numbers var MY_NUMBER = '+xxx'; var HER_NUMBER = '+xxx'; // Reasons var reasons = [ 'Working hard', 'Gotta ship this feature', 'Someone fucked the system again' ]; // Generate BS message var reason = reasons[Math.floor(Math.random() * reasons.length)]; var textMessage = 'Late at work. ' + reason; var client = require('twilio')(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN); // Shoot text client.messages.create({ body: textMessage, to: HER_NUMBER, from: MY_NUMBER }, function(error, message) { if(error) console.log('Failed to send SMS: ' + error.message); else { var currentdate = new Date(); console.log('Message sent at: '+ (currentdate.getMonth() + 1) + '/' + currentdate.getDate() + '/' + currentdate.getFullYear() + ' ' + currentdate.getHours() + ':' + currentdate.getMinutes() + ':' + currentdate.getSeconds() + '| Excuse: ' + reason); } }); }); ================================================ FILE: perl/fucking-coffee.pl ================================================ #!/usr/bin/perl use strict; use warnings; use DateTime; use YAML; use Net::Telnet; # Config my $conf = Load( <<'...' ); --- coffee_machine_ip: 10.10.42.42 password: 1234 password_prompt: Password: delay_before_brew: 17 delay: 24 ... # Skip on weekends my $date = DateTime->now; if ( $date->day_of_week >= 6 ) { exit; } # Exit early if no sessions with my username are found open( my $cmd_who, '-|', 'who' ) || die "Cannot pipe who command ". $!; my @sessions = grep { m/$ENV{'USER'}/ } <$cmd_who>; close $cmd_who; exit if ( scalar( @sessions ) == 0 ); sleep $conf->{'delay_before_brew'}; my $con = Net::Telnet->new( 'Host' => $conf->{'coffee_machine_ip'}, ); $con->watifor( $conf->{'password_prompt'} ); $con->cmd( $conf->{'password'} ); $con->cmd( 'sys brew' ); sleep $conf->{'delay'}; $con->cmd( 'sys pour' ); $con->close; ================================================ FILE: perl/hangover.pl ================================================ #!/usr/bin/perl use strict; use warnings; use DateTime; use SMS::Send; use YAML; # Config my $conf = Load( <<'...' ); --- phone_numbers: my_number: +15005550006 boss_number: +xxx reasons: - Locked out - Pipes broke - Food poisoning - Not feeling well ... my $date = DateTime->now; # Skip on weekends if ( $date->day_of_week >= 6 ) { exit; } # Exit early if no sessions with my username are found open( my $cmd_who, '-|', 'who' ) || die "Cannot pipe who command ". $!; my @sessions = grep { m/$ENV{'USER'}/ } <$cmd_who>; close $cmd_who; exit if ( scalar( @sessions ) == 0 ); # Load Twilio API config open( my $env, '<', '../.env' ) || die "Cannot find .env file in project root."; LINE: while ( my $line = <$env> ) { next LINE unless ( $line =~ m/^(TWILIO[^=]+)=(.*)(?:[\n\r]*)/ ); $conf->{'env'}->{ $1 } = $2; } close $env; # Randomize excuse my $reason_number = int( rand( scalar( @{ $conf->{'reasons'} } ) ) ); my $sms_text = "Gonna work from home. ". $conf->{'reasons'}[ $reason_number ]; # Create an object. There are three required values: my $sender = SMS::Send->new('Twilio', _accountsid => $conf->{'env'}->{'TWILIO_ACCOUNT_SID'}, _authtoken => $conf->{'env'}->{'TWILIO_AUTH_TOKEN'}, _from => $conf->{'phone_numbers'}->{'my_number'}, ); # Send a message to me my $sent = $sender->send_sms( text => $sms_text, to => $conf->{'phone_numbers'}->{'boss_number'}, ); # Did it send? if ( $sent ) { print "Sent message.\n"; } else { print "Message failed.\n"; } ================================================ FILE: perl/kumar-asshole.pl ================================================ #!/usr/bin/perl use strict; use warnings; use YAML; use DateTime; use Mail::Webmail::Gmail; # Config my $conf = Load( <<'...' ); --- kumar_mail: kumar.a@example.com database_regex: \S+_staging keywords_regex: sorry|help|wrong backup_path: /home/backups/databases/ ... $conf->{'database_regex'} = qr/ ( $conf->{'database_regex'} ) /x; $conf->{'keywords_regex'} = qr/ ( $conf->{'keywords_regex'} ) /x; my $date = DateTime->now->subtract( 'days' => 1 ); # Load GMail API config open( my $env, '<', '../.env' ) || die "Cannot find .env file in project root."; LINE: while ( my $line = <$env> ) { next LINE unless ( $line =~ m/^(GMAIL[^=]+)=(.*)(?:[\n\r]*)/ ); $conf->{'env'}->{ $1 } = $2; } close $env; my $gmail = Mail::Webmail::Gmail->new( username => $conf->{'env'}->{'GMAIL_USERNAME'}, password => $conf->{'env'}->{'GMAIL_PASSWORD'}, encrypt_session => 1, ); my $messages = $gmail->get_messages( label => $Mail::Webmail::Gmail::FOLDERS{ 'INBOX' } ); die "Cannot fetch emails: ". $gmail->error_msg(); MESSAGE: foreach my $message ( @{ $messages } ) { unless ( ( $message->{ 'new' } ) && ( $message->{'sender_email'} eq $conf->{'kumars_email'} ) && ( $message->{'body'} =~ m/$conf->{'keywords_regex'}/ ) && ( $message->{'body'} =~ m/$conf->{'database_regex'}/ ) ) { print "Skipping mail from=[". $message->{'sender_email'}."] subject=[". $message->{'subject'} ."]\n"; next MESSAGE; } exit 1; my $database = $1; my $backup_file = $conf->{'backup_path'} . $database .'-'. $date->ymd() .'.gz'; unless ( -f $backup_file ) { die 'Cannot find backup file=['. $backup_file ."]\n"; } print 'Restoring database=['. $database .'] from day=['. $date->ymd() .'] from file=['. $backup_file ."]\n"; # Restore DB system( 'gunzip -c '. $backup_file .' | psql '. $database ); die "Error while restoring the database=[". $database ."] from file=[". $backup_file ."]" if ( $? >> 8 ); # Mark as read, add label, reply $gmail->edit_labels( 'label' => 'Database fixes', 'action' => 'add', 'msgid' => $message->{'id'} ); $gmail->send_message( 'to' => $conf->{'kumars_email'}, 'subject' => 'RE: '. $message->{'subject'}, 'msgbody' => "No problem. I've fixed it. \n\n Please be careful next time.", ); $gmail->edit_labels( 'label' => 'unread', 'action' => 'remove', 'msgid' => $message->{'id'} ); } ================================================ FILE: perl/smack-my-bitch-up.pl ================================================ #!/usr/bin/perl use strict; use warnings; use DateTime; use SMS::Send; use YAML; # Config my $conf = Load( <<'...' ); --- phone_numbers: my_number: +15005550006 her_number: +xxx reasons: - Working hard - Gotta ship this feature - Someone fucked the system again ... my $date = DateTime->now; # Skip on weekends if ( $date->day_of_week >= 6 ) { exit; } # Exit early if no sessions with my username are found open( my $cmd_who, '-|', 'who' ) || die "Cannot pipe who command ". $!; my @sessions = grep { m/$ENV{'USER'}/ } <$cmd_who>; close $cmd_who; exit if ( scalar( @sessions ) == 0 ); # Load Twilio API config open( my $env, '<', '../.env' ) || die "Cannot find .env file in project root."; LINE: while ( my $line = <$env> ) { next LINE unless ( $line =~ m/^(TWILIO[^=]+)=(.*)(?:[\n\r]*)/ ); $conf->{'env'}->{ $1 } = $2; } close $env; # Randomize excuse my $reason_number = int( rand( scalar( @{ $conf->{'reasons'} } ) ) ); my $sms_text = "Late at work. ". $conf->{'reasons'}[ $reason_number ]; # Create an object. There are three required values: my $sender = SMS::Send->new('Twilio', _accountsid => $conf->{'env'}->{'TWILIO_ACCOUNT_SID'}, _authtoken => $conf->{'env'}->{'TWILIO_AUTH_TOKEN'}, _from => $conf->{'phone_numbers'}->{'my_number'}, ); # Send a message to me my $sent = $sender->send_sms( text => $sms_text, to => $conf->{'phone_numbers'}->{'her_number'}, ); # Did it send? if ( $sent ) { print "Sent message.\n"; } else { print "Message failed.\n"; } ================================================ FILE: php/composer.json ================================================ { "require": { "bestnetwork/telnet": "^1.0", "vlucas/phpdotenv": "^2.0", "twilio/sdk": "^4.6" } } ================================================ FILE: php/fucking_coffee.php ================================================ #!/usr/bin/env php execute('1234', 'Password: '); $con->execute('sys brew'); sleep(24); $con->execute('sys pour'); ================================================ FILE: php/hangover.php ================================================ #!/usr/bin/env php load(); (strpos(exec('who'), getenv('USER')) === false) or exit('session found'); $my_number = '+xxx'; $number_of_boss = '+xxx'; $excuse = ['Locked out', 'Pipes broke', 'Food poisoning', 'Not feeling well']; $excuse = $excuse[array_rand($excuse)]; $twilio = new Services_Twilio(getenv('TWILIO_ACCOUNT_SID'), getenv('TWILIO_AUTH_TOKEN')); $twilio->account->messages->sendMessage( $my_number, $number_of_boss, "Gonna work from home. {$excuse}" ); echo "Message sent at: #".date('Y-m-d')." | Excuse: {$excuse}"; ================================================ FILE: php/smack_my_bitch_up.php ================================================ #!/usr/bin/env php load(); (strpos(exec('who'), getenv('USER')) !== false) or exit('no session'); // Phone numbers $my_number = '+xxx'; $her_number = '+xxx'; $reasons = [ 'Working hard', 'Gotta ship this feature', 'Someone fucked up the system again' ]; $rand = rand(0,count($reasons)-1); $random_reason = $reasons[$rand]; $message = 'Late at work. '.$random_reason; // Send a text message $twilio = new Services_Twilio(getenv('TWILIO_ACCOUNT_SID'), getenv('TWILIO_AUTH_TOKEN')); $twilio->account->messages->sendMessage( $my_number, $her_number, $message ); echo 'Message sent at: #'.date('Y-m-d').' | Reason: '.$random_reason; ================================================ FILE: powershell/fucking_coffee.psm1 ================================================ <# .SYNOPSIS Simple script to connect to a coffee part using TelNet then issue specific commands that brew and pour a cup of coffee for the user. .DESCRIPTION This script was converted using the ruby version of the fucking_coffee script. In this script, I left the use of environment variables since its only use was to determine if the user was still logged in to the system. Per issue #42 (https://github.com/NARKOZ/hacker-scripts/issues/42) I left the password string hard coded until a decision is made by NARKOZ, the project owner, as to how the information should be stored. .OUTPUT None .NOTES Author: Tyler Hughes Twitter: @thughesIT Blog: http://tylerhughes.info/ Changelog: 1.0 Initial Release #> Function Fucking-Coffee { # Exit early if no sessions with my username are found if ($env:Username.Count > 0) { return } $coffee_machine_ip = '10.10.42.42' $password = '1234' Start-Sleep -s 17 $socket = New-Object System.Net.Sockets.TcpClient($coffee_machine_ip) if ($socket) { $stream = $connection.GetStream() $Writer = New-Object System.IO.StreamWriter($Stream) $Buffer = New-Object System.Byte[] 1024 $Encoding = New-Object System.Text.AsciiEncoding # Start issuing the commands Send-TelNetCommands($Writer, $password, 1) Send-TelNetCommands($Writer, "sys brew", 24) Send-TelNetCommands($Writer, "sys pour", 4) $socket.Close() } } Function Send-TelNetCommands { Param ( [Parameter(ValueFromPipeline=$false)] [System.IO.StreamWriter]$writer, [String]$command, [int]$WaitTime ) $writer.WriteLine($command) $writer.Flush() Start-Sleep -Milliseconds $WaitTime } ================================================ FILE: powershell/hangover.psm1 ================================================ <# .SYNOPSIS Simple script to SMS a supervisor informing them you will be working from home on the day this script is used. .DESCRIPTION This script was converted using the ruby version of the hangover script. However, the ruby version used environment variables to hold the user's account information. Due to issue #42 (https://github.com/NARKOZ/hacker-scripts/issues/42) I opted to hard code the strings at this time until a decision is made by NARKOZ, the project owner, as the how the information should be stored. This script also uses Twilio to send the SMS messages. The from number MUST be a valid Twilio phone number. The to number can be any outgoing number. .OUTPUT This script will output an error message to the PowerShell window if it fails to send the message. .NOTES Author: Tyler Hughes Twitter: @thughesIT Blog: http://tylerhughes.info/ Changelog: 1.0 Initial Release #> Function Hangover { # Phone numbers (Must include country code and area code) $from = '+XXXXXXXXXXX' $to = '+XXXXXXXXXXX' # Twilio API Information $twilio_base_url = 'https://api.twilio.com/2010-04-01' $twilio_account_sid = 'XXXXXXXXXXXXXXXXXXX' $twilio_auth_token = 'XXXXXXXXXXXXXXXXXX' $password = ConvertTo-SecureString -AsPlainText $twilio_auth_token -Force $credentials = New-Object System.Management.Automation.PSCredential($twilio_account_sid, $password) # Get the message to send $excuses = 'Locked out', 'Pipes broke', 'Food poisoning', 'Not feeling well' $excuse = $excuses | Get-Random $message = "$excuse. Going to work from home today." $body = @{ From = $from; To = $to; Body = $message; } # Send the message and log any errors $uri = "$twilio_base_url/Accounts/" + $credentials.UserName + "/SMS/Messages" try { $response = Invoke-RestMethod -Method Post -Uri $uri -Body $body -Credential $credentials } catch { $time = Get-Date -format u Write-Host $time " - Failed to send message: " $message } } ================================================ FILE: powershell/smack_my_bitch_up.ps1 ================================================ $DAYOFWEEK = (Get-Date).DayOfWeek.value__; # Skip on weekends if ($DAYOFWEEK -eq 6 -or $DAYOFWEEK -eq 7) { return } # Exit early if no sessions with my username are found if (-not (QWINSTA | FINDSTR $env:USERNAME)) { return } # Phone numbers $MY_NUMBER='+xxx' $HER_NUMBER='+xxx' $REASONS = 'Working hard', 'Gotta ship this feature', 'Someone fucked the system again' $reason = $REASONS | Get-Random $message = "Late at work. $reason." $API_URL = "https://api.twilio.com/2010-04-01/Accounts/$env:TWILIO_ACCOUNT_SID/Messages" $BASE64AUTHINFO = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $env:TWILIO_ACCOUNT_SID,$env:TWILIO_AUTH_TOKEN))) $body = @{ From = $MY_NUMBER; To = $HER_NUMBER; Body = $message; } #Send a text message and Log errors try{ Invoke-RestMethod -Method Post -Headers @{Authorization=("Basic {0}" -f $BASE64AUTHINFO)} $API_URL -Body $body > $null } catch{ Write-Host "Failed to send SMS: $_" } ================================================ FILE: python/fucking_coffee.py ================================================ #!/usr/bin/env python import sys import subprocess import telnetlib import time # exit if no sessions with my username are found output = subprocess.check_output('who') if 'my_username' not in output: sys.exit() time.sleep(17) coffee_machine_ip = '10.10.42.42' password = '1234' password_prompt = 'Password: ' con = telnetlib.Telnet(coffee_machine_ip) con.read_until(password_prompt) con.write(password + "\n") # Make some coffee! con.write("sys brew\n") time.sleep(24) # love the smell! con.write("sys pour\n") con.close() ================================================ FILE: python/hangover.py ================================================ #!/usr/bin/env python import os import random from twilio.rest import TwilioRestClient from time import strftime import subprocess # exit if sessions with my username are found output = subprocess.check_output('who') if 'my_username' in output: sys.exit() # returns 'None' if the key doesn't exist TWILIO_ACCOUNT_SID = os.environ.get('TWILIO_ACCOUNT_SID') TWILIO_AUTH_TOKEN = os.environ.get('TWILIO_AUTH_TOKEN') # Phone numbers my_number = '+xxx' number_of_boss = '+xxx' excuses = [ 'Locked out', 'Pipes broke', 'Food poisoning', 'Not feeling well' ] client = TwilioRestClient(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN) client.messages.create( to=number_of_boss, from_=my_number, body="Gonna work from home. " + random.choice(excuses) ) print "Message sent at " + strftime("%a, %d %b %Y %H:%M:%S") ================================================ FILE: python/kumar_asshole.py ================================================ #!/usr/bin/env python import gmail import sys import re GMAIL_USERNAME = ENV['GMAIL_USERNAME'] GMAIL_PASSWORD = ENV['GMAIL_PASSWORD'] g = gmail.login(GMAIL_USERNAME, GMAIL_PASSWORD) if not g.logged_in: sys.exit() msgs = g.inbox().mail(sender="kumar.a@example.com", unread=True, prefetch=True) pattern = re.compile("\bsorry\b | \bhelp\b | \bwrong\b ", flags=re.I) for msg in msgs: if pattern.match(msg.body): msg.label("Database fixes") msg.reply("No problem. I've fixed it. \n\n Please be careful next time.") ================================================ FILE: python/smack_my_bitch_up.py ================================================ #!/usr/bin/env python import os import random from twilio.rest import TwilioRestClient import subprocess import sys from time import strftime # exit if no sessions with my username are found output = subprocess.check_output('who') if 'my_username' not in output: sys.exit() # returns 'None' if the key doesn't exist TWILIO_ACCOUNT_SID = os.environ.get('TWILIO_ACCOUNT_SID') TWILIO_AUTH_TOKEN = os.environ.get('TWILIO_AUTH_TOKEN') # Phone numbers my_number = '+xxx' her_number = '+xxx' reasons = [ 'Working hard', 'Gotta ship this feature', 'Someone fucked the system again' ] client = TwilioRestClient(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN) client.messages.create( to=her_number, from_=my_number, body="Late at work. " + random.choice(reasons) ) print "Message sent at " + strftime("%a, %d %b %Y %H:%M:%S") ================================================ FILE: python3/fucking_coffee.py ================================================ #!/usr/bin/env python3 # -*- coding: utf-8 -*- import telnetlib import time from hackerutils import sh COFFEE_MACHINE_ADDR = '10.10.42.42' COFFEE_MACHINE_PASS = '1234' COFFEE_MACHINE_PROM = 'Password: ' def main(): # Exit early if no sessions with my_username are found. if not any(s.startswith(b'my_username ') for s in sh('who').split(b'\n')): return time.sleep(17) conn = telnetlib.Telnet(host=COFFEE_MACHINE_ADDR) conn.open() conn.expect([COFFEE_MACHINE_PROM]) conn.write(COFFEE_MACHINE_PASS) conn.write('sys brew') time.sleep(24) conn.write('sys pour') conn.close() if __name__ == '__main__': main() ================================================ FILE: python3/hackerutils.py ================================================ #!/usr/bin/env python3 # -*- coding: utf-8 -*- import pathlib import subprocess from dotenv import Dotenv def get_dotenv(filename='.env'): return Dotenv(str(pathlib.Path(__file__).parent / filename)) def sh(*args): proc = subprocess.Popen(args, stdout=subprocess.PIPE) stdout, _ = proc.communicate() return stdout def get_log_path(name): path = pathlib.Path(__file__).parent / 'logs' / name path.parent.mkdir(parents=True, exist_ok=True) return path ================================================ FILE: python3/hangover.py ================================================ #!/usr/bin/env python3 # -*- coding: utf-8 -*- import random from twilio import TwilioRestException from twilio.rest import TwilioRestClient from hackerutils import get_dotenv, get_log_path, sh dotenv = get_dotenv() TWILIO_ACCOUNT_SID = dotenv['TWILIO_ACCOUNT_SID'] TWILIO_AUTH_TOKEN = dotenv['TWILIO_AUTH_TOKEN'] LOG_FILE_PATH = get_log_path('hangover.txt') def main(): # Exit early if any session with my_username is found. if any(s.startswith(b'my_username ') for s in sh('who').split(b'\n')): return client = TwilioRestClient(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN) # Phone numbers. my_number = '+xxx' number_of_boss = '+xxx' excuses = [ 'Locked out', 'Pipes broke', 'Food poisoning', 'Not feeling well', ] try: # Send a text message. client.messages.create( to=number_of_boss, from_=my_number, body='Gonna work from home. ' + random.choice(excuses), ) except TwilioRestException as e: # Log errors. with LOG_FILE_PATH.open('a') as f: f.write('Failed to send SMS: {}'.format(e)) raise if __name__ == '__main__': main() ================================================ FILE: python3/kumar_asshole.py ================================================ #!/usr/bin/env python3 # -*- coding: utf-8 -*- import re import gmail import yagmail from hackerutils import get_dotenv dotenv = get_dotenv() GMAIL_USERNAME = dotenv['GMAIL_USERNAME'] GMAIL_PASSWORD = dotenv['GMAIL_PASSWORD'] KUMAR_EMAIL = 'kumar.a@example.com' KEYWORDS_REGEX = re.compile(r'sorry|help|wrong', re.IGNORECASE) REPLY_BODY = "No problem. I've fixed it. \n\nPlease be careful next time." yagmail.register(GMAIL_USERNAME, GMAIL_PASSWORD) def send_reply(subject): yag = yagmail.SMTP(GMAIL_USERNAME) yag.send( to=KUMAR_EMAIL, subject='RE: {}'.format(subject), contents=REPLY_BODY, ) def main(): g = gmail.login(GMAIL_USERNAME, GMAIL_PASSWORD) for mail in g.inbox().mail(unread=True, sender=KUMAR_EMAIL, prefetch=True): if KEYWORDS_REGEX.search(mail.body): # Restore DB and send a reply. mail.add_label('Database fixes') send_reply(mail.subject) if __name__ == '__main__': main() ================================================ FILE: python3/requirements.txt ================================================ dotenv twilio yagmail git+https://github.com/charlierguo/gmail ================================================ FILE: python3/smack_my_bitch_up.py ================================================ #!/usr/bin/env python3 # -*- coding: utf-8 -*- import random from twilio import TwilioRestException from twilio.rest import TwilioRestClient from hackerutils import get_dotenv, get_log_path, sh dotenv = get_dotenv() TWILIO_ACCOUNT_SID = dotenv['TWILIO_ACCOUNT_SID'] TWILIO_AUTH_TOKEN = dotenv['TWILIO_AUTH_TOKEN'] LOG_FILE_PATH = get_log_path('smack_my_bitch_up.txt') def main(): # Exit early if no sessions with my_username are found. if not any(s.startswith(b'my_username ') for s in sh('who').split(b'\n')): return client = TwilioRestClient(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN) # Phone numbers. my_number = '+xxx' her_number = '+xxx' reasons = [ 'Working hard', 'Gotta ship this feature', 'Someone fucked the system again', ] try: # Send a text message. client.messages.create( to=her_number, from_=my_number, body='Late at work. ' + random.choice(reasons), ) except TwilioRestException as e: # Log errors. with LOG_FILE_PATH.open('a') as f: f.write('Failed to send SMS: {}'.format(e)) raise if __name__ == '__main__': main() ================================================ FILE: scala/fucking-coffee.scala ================================================ /******************************************* * * Get Ammonite (http://lihaoyi.github.io/Ammonite/#Ammonite-Shell): * $ mkdir ~/.ammonite; curl -L -o ~/.ammonite/predef.scala http://git.io/vR04f * $ curl -L -o amm http://git.io/vR08A; chmod +x amm * * Run script * $ ./amm fucking-coffee.scala * *******************************************/ import java.net._ import java.io._ import ammonite.ops._ import ammonite.ops.ImplicitWd._ val coffeeMachineIP = "10.10.42.42" val password = "1234" val passwordPrompt = "Password: " val delayBeforeBrew = 17 val delay = 24 if ((%%who "-q").out.string.contains(sys.props("user.name"))) { val telnet = new Socket(coffeeMachineIP, 23) val out = new PrintWriter(telnet.getOutputStream, true) val in = new BufferedReader(new InputStreamReader(telnet.getInputStream)) println(s"Wait for $delayBeforeBrew seconds") Thread.sleep(delayBeforeBrew * 1000); if(in.readLine == passwordPrompt){ out.println(password) out.println("sys brew") Thread.sleep(delay * 1000) out.println("sys pour") } out.close() in.close() telnet.close() } ================================================ FILE: smack-my-bitch-up.sh ================================================ #!/bin/sh -e # Exit early if no sessions with my username are found if ! who | grep -wq $USER; then exit fi # Phone numbers MY_NUMBER='+xxx' HER_NUMBER='+xxx' REASONS=( 'Working hard' 'Gotta ship this feature' 'Someone fucked the system again' ) rand=$[ $RANDOM % ${#REASONS[@]} ] RANDOM_REASON=${REASONS[$rand]} MESSAGE="Late at work. "$RANDOM_REASON # Send a text message RESPONSE=`curl -fSs -u "$TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN" \ -d "From=$MY_NUMBER" -d "To=$HER_NUMBER" -d "Body=$MESSAGE" \ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Messages"` # Log errors if [ $? -gt 0 ]; then echo "Failed to send SMS: $RESPONSE" exit 1 fi ================================================ FILE: smack_my_bitch_up.rb ================================================ #!/usr/bin/env ruby # Exit early if no sessions with my username are found exit unless `who -q`.include? ENV['USER'] require 'dotenv' require 'twilio-ruby' Dotenv.load TWILIO_ACCOUNT_SID = ENV['TWILIO_ACCOUNT_SID'] TWILIO_AUTH_TOKEN = ENV['TWILIO_AUTH_TOKEN'] @twilio = Twilio::REST::Client.new TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN # Phone numbers my_number = '+xxx' her_number = '+xxx' reason = [ 'Working hard', 'Gotta ship this feature', 'Someone fucked the system again' ].sample # Send a text message @twilio.messages.create( from: my_number, to: her_number, body: "Late at work. #{reason}" ) # Log this puts "Message sent at: #{Time.now} | Reason: #{reason}"