#!/usr/local/bin/php -q jab = &$jab; $this->first_roster_update = true; echo "Created!\n"; } // called when a connection to the Jabber server is established function handleConnected() { echo "Connected!\n"; // now that we're connected, tell the Jabber class to login echo "Authenticating ...\n"; $this->jab->login(JABBER_USERNAME,JABBER_PASSWORD); } // called after a login to indicate the the login was successful function handleAuthenticated() { echo "Authenticated!\n"; echo "Fetching service list and roster ...\n"; // browser for transport gateways $this->jab->browse(); // retrieve this user's roster $this->jab->get_roster(); // set this user's presence $this->jab->set_presence("",JABBER_PRESENCE); } // called after a login to indicate that the login was NOT successful function handleAuthFailure($code,$error) { echo "Authentication failure: $error ($code)\n"; // set terminated to TRUE in the Jabber class to tell it to exit $this->jab->terminated = true; } // called periodically by the Jabber class to allow us to do our own processing function handleHeartbeat() { echo "."; //change to whatever you want, this gets called every CBK_FREQ seconds } // called when an error is received from the Jabber server function handleError($code,$error,$xmlns) { echo "Error: $error ($code)".($xmlns?" in $xmlns":"")."\n"; } // called when a message is received from a remote contact function handleMessage($from,$to,$body,$subject,$thread,$id,$extended) { echo "Incoming message!\n"; echo "From: $from\t\tTo: $to\n"; echo "Subject: $subject\tThread; $thread\n"; echo "Body: $body\n"; echo "ID: $id\n"; var_dump($extended); echo "\n"; $this->last_message = $body; //these next two bits are remote control constructs that can either kill the bot, or tell it to send //a message to someone // I created this kill string so I could turn off the bot remotely using another jabber client (gmail chat, etc...) //if I send the KILL_STRING directly to this bot, it will end and go offline if ($body == KILL_STRING) { $this->jab->terminated = true; return; } //another remote control construct here, useful for telling the bot to send a message to a //sepcified recipient by doing it from a remote jabber client //example: send:twitter@twitter.com:follow user (notice colons between sections) if(substr($body, 0, 5) == "send:") { list($send, $to, $msg) = explode(":", $body, 3); $this->jab->message($to,"chat",NULL,$msg); return; } //this is really where you start handling messages from Twitter //if you really wanted to add "security" to make sure the messages are coming from twitter, you //could either wrap all of these in an if($from == "twitter@twitter.com") or change the logic in the //is*Message() handler functions below //check to see if this tweet is a reply to this bot if (strpos($body,"@" . BOTNAME . "")) { $user = $this->getUserFromReply($body); $msg = $this->getMsgFromReply($body); //add any extra functionality for reply message handling here } //check to see if this is a direct message from twitter if($this->isDirectMessage($body)) { $user = $this->getUserFromDirectMessage($body); $msg = $this->getMsgFromDirectMessage($body); //add any extra functionality for direct message handling here } // end if isDirectMessage() //check if this is a tracked message from twitter if($this->isTrackedMessage($body)) { $user = $this->getUserFromTrackedMessage($body); $msg = $this->GetMsgFromTrackedMessage($body); //add any extra functionality for tracked message handling here } //it is important to note that I do not have any sort of handler for just normal tweets at this point //as only direct messages, replies, or tracked messages will create a valid $user and $msg variable. //if you want to add a "normal" tweet handler, you should insert it here before the next if statement //which will return if one of them is not set. //if the message or user is empty, return... if ($msg == "" || $user == "") { //abort! return; } // BEGIN COMMAND HANDLING //this is really where you start handling your defined commands for your twitter bot. //add/modify your commands to the if structure below in a similar manner $msg = strtolower($msg); if (substr($msg, 0, strlen("command1")) == "command1") { //change "command1" twice $this->handleCommand1($user, trim(substr($msg, strlen("command1")))); //change "command1" } else if (substr($msg, 0, strlen("command2")) == "command2") { //change "command2" twice $this->handleCommand2($user, trim(substr($msg, strlen("command2")))); //change "command2" } else { // default action - this means that no good command was received by your bot //you could either send a help message, or do nothing echo "no good command!"; } $this->last_msg_id = $id; $this->last_msg_from = $from; } //end function handleMessage //this function will send a message to the twitter bot function tweet($msg) { $this->jab->message("twitter@twitter.com","chat",NULL,"$msg"); } //the following functions are helper functions to determine the type of tweet and //extract user and message info function getUserFromReply($body) { list($user, $note) = explode(":", $body, 2); $user = str_replace('(', '', $user); $user = str_replace(')', '', $user); return $user; } function getMsgFromReply($body) { list($user, $cmd) = explode(":", $body, 2); $cmd = trim(str_replace(',', '', $cmd)); $cmd = trim(str_replace(':', '', $cmd)); $cmd = trim(str_replace('@' . BOTNAME . '', '', $cmd)); // replace bot name with correct name echo $cmd; return $cmd; } function isDirectMessage($body) { if(substr($body, 0, 12) == "Direct from ") { return 1; } else { return 0; } } function getUserFromDirectMessage($body) { list($user, $msg) = explode(":", $body, 2); $user = trim(str_replace("Direct from ", "", $user)); return $user; } // end function function getMsgFromDirectMessage($body) { list($user, $msg) = explode(":", $body, 2); $msg = trim($msg); $i = strpos($msg, "\n\nReply with 'd ", $msg); $msg = substr($msg, 0, $i); return $msg; } // end function function isTrackedMessage($body) { list($user, $msg) = explode(":", $body, 2); //echo "user: $user msg: $msg\n"; if (!(strpos($user, "(") === FALSE) && !(strpos($user, ")") === FALSE)) { //echo "returned 1\n"; return 1; } else { //echo "returned 0;\n"; return 0; } //echo "not good!!\n"; } function getUserFromTrackedMessage($body) { list($user, $note) = explode(":", $body, 2); $user = str_replace('(', '', $user); $user = str_replace(')', '', $user); return $user; } function getMsgFromTrackedMessage($body) { list($user, $cmd) = explode(":", $body, 2); $cmd = trim(str_replace(',', '', $cmd)); $cmd = trim(str_replace(':', '', $cmd)); $cmd = trim(str_replace('@madstatter', '', $cmd)); //echo $cmd; return $cmd; } //below are the bot command handlers function handleCommand1($user, $args) { //handle command here $this->tweet("@$user you said command1 with args $args"); } function handleCommand2($user, $args) { //handle command here $this->tweet("@$user you said command2 with args $args"); } //the rest of these commands are handlers for various jabber events, you shouldn't need to edit them for normal functionality, but you are free to change them if you want function _contact_info($contact) { return sprintf("Contact %s (JID %s) has status %s and message %s\n",$contact['name'],$contact['jid'],$contact['show'],$contact['status']); } function handleRosterUpdate($jid) { if ($this->first_roster_update) { // the first roster update indicates that the entire roster has been // downloaded for the first time echo "Roster downloaded:\n"; foreach ($this->jab->roster as $k=>$contact) { echo $this->_contact_info($contact); } $this->first_roster_update = false; } else { // subsequent roster updates indicate changes for individual roster items $contact = $this->jab->roster[$jid]; echo "Contact updated: " . $this->_contact_info($contact); } } function handleDebug($msg,$level) { echo "DBG: $msg\n"; } } // include the Jabber class require_once("class_Jabber.php"); // create an instance of the Jabber class $display_debug_info = false; $jab = new Jabber($display_debug_info); // create an instance of our event handler class $bot = new TwitterBot($jab); // set handlers for the events we wish to be notified about $jab->set_handler("connected",$bot,"handleConnected"); $jab->set_handler("authenticated",$bot,"handleAuthenticated"); $jab->set_handler("authfailure",$bot,"handleAuthFailure"); $jab->set_handler("heartbeat",$bot,"handleHeartbeat"); $jab->set_handler("error",$bot,"handleError"); $jab->set_handler("message_normal",$bot,"handleMessage"); $jab->set_handler("message_chat",$bot,"handleMessage"); $jab->set_handler("debug_log",$bot,"handleDebug"); $jab->set_handler("rosterupdate",$bot,"handleRosterUpdate"); echo "Connecting ...\n"; // connect to the Jabber server if (!$jab->connect(JABBER_SERVER)) { die("Could not connect to the Jabber server!\n"); } // now, tell the Jabber class to begin its execution loop $jab->execute(CBK_FREQ,RUN_TIME); // Note that we will not reach this point (and the execute() method will not // return) until $jab->terminated is set to TRUE. The execute() method simply // loops, processing data from (and to) the Jabber server, and firing events // (which are handled by our TwitterBot class) until we tell it to terminate. // // This event-based model will be familiar to programmers who have worked on // desktop applications, particularly in Win32 environments. echo "ended execution\n"; // disconnect from the Jabber server $jab->disconnect(); echo "ending script...\n"; exit(); ?>