This is cool for a number of reasons.
- No need to run an IMAP application on your phone; updates are pushed to me from an external source.
- No need of a data plan to use it (although I may need to increase the number of texts I can receive without additional charges).
- You can reply directly from phone (although the message is received from a different address, depending on your carrier).
- It’s got an accuracy of around one minute, and so far that has been more than adequate.
You need to create a web-writable file (chmod 755) called timestamp.txt in the same directory. I’ll include the cron script at the end of this post.
Code: Select all
// filename: sms.php
$debug = false; // false = no output
$error = '';
// Define SMS parameters; your gateway may vary
$sms_to = '[email protected]';
// Define IMAP parameters
$imap_user = 'my.gmail.account';
$imap_pass = 'Secret-Password!';
$imap_host = '{imap.gmail.com:993/imap/ssl}INBOX';
// Define SMTP parameters
$smtp_host = 'smtp.mymailserver.com';
$smtp_port = '25';
$smtp_user = '[email protected]'; // a valid user must exist
$smtp_pass = 'Another-Password!';
// Open a pointer to the mailbox
if ($debug) { $error = 'error: imap connection failed'; }
$imap = imap_open ($imap_host, $imap_user, $imap_pass) or die ($error);
// Quick exit
if (imap_num_msg ($imap) == 0) {
imap_close ($imap);
if ($debug) { $error = 'error: no messages in mailbox'; }
die ($error);
}
// What was the last new message?
$old_timestamp = file_get_contents ('./timestamp.txt');
// Get last message
$msg_id = imap_num_msg ($imap);
// Gather IMAP message headers
$headers = imap_headerinfo ($imap, $msg_id);
// What's the timestamp on the most recent message?
$new_timestamp = $headers->udate;
// If it's the same message, get out of here.
if ($new_timestamp <= $old_timestamp) {
imap_close ($imap);
if ($debug) { $error = 'error: timestamp match'; }
die ($error);
}
// Write timestamp of new message to external file
$handle = fopen ('timestamp.txt', 'w');
fwrite ($handle, $new_timestamp);
fclose ($handle);
// Let's look at that email we grabbed
$message = imap_get_message ($imap, $msg_id);
// Close IMAP Connection
imap_close ($imap);
// Okay, who's it from? Let's just do the email address...
// This needs cleaned up a bit; not all addresses include brackets.
$from = trim ($message['from']);
$b1 = strpos ($from, '<') + 1;
$b2 = strpos ($from, '>');
$from = substr ($from, $b1, ($b2 - $b1) );
// Here's an oddity -- gmail doesn't work. Go figure.
$from = str_replace ('gmail.com', 'g-mail.com', $from);
// And what's it say? Get rid of everything except alphanumerics and basic punctuation
$body = $message['body'];
$body = strip_tags ($body);
$body = preg_replace ('/[^A-Za-z0-9!-~]/', ' ', $body);
$body = preg_replace ('/\s\s+/', ' ', $body);
// Cut it off at 150 characters; seems to be the max for Verizon, anyway
$body = (strlen ($body) > 150) ? substr ($body, 0, 147).'...' : $body ;
// Set mail parameters; this sets the 'Return-Path' value
$param = '-r '.$from;
$subject = '';
$headers = '';
// Send it off!
mail ($sms_to, $subject, $body, $headers, $param);
// IMAP message retrieval; returns a basic array
function imap_get_message ($imap_connection, $msg_no) {
$header = imap_header($imap_connection, $msg_no);
$message = array();
$message['subject'] = $header->subject;
$message['from'] = $header->fromaddress;
$message['to'] = $header->toaddress;
$message['date'] = $header->date;
$struct = imap_fetchstructure($imap_connection, $msg_no);
@$parts = $struct->parts;
$i = 0;
if (!$parts) {
$message['body'] = imap_body ($imap_connection, $msg_no);
} else {
$endwhile = false;
$stack = array(); // Stack while parsing message
$message['body'] = ''; // Content of message
while (!$endwhile) {
if (@!$parts[$i]) {
if (count ($stack) > 0) {
$parts = $stack[count ($stack) - 1]["p"];
$i = $stack[count ($stack) - 1]["i"] + 1;
array_pop($stack);
} else {
$endwhile = true;
}
}
if (!$endwhile) {
// Create message part first (example '1.2.3')
$partstring = '';
foreach ($stack as $s) {
$partstring .= ($s["i"]+1) . ".";
}
$partstring .= ($i+1);
if (strtoupper ($parts[$i]->subtype) == "PLAIN") {
$message['body'] .= imap_fetchbody ($imap_connection, $msg_no, $partstring); // Message
}
}
if (@$parts[$i]->parts) {
$stack[] = array("p" => $parts, "i" => $i);
$parts = $parts[$i]->parts;
$i = 0;
} else {
$i++;
}
} // While loop
}
return $message;
}