Send and Receive SMS with PHP
I have wanted a way to send and receive text-messages (SMS) with PHP for some time now. The main problem isn’t that it is impossible — there are dozens of companies that provide PEAR or other gateways that do exactly this — it is the fact that I do not want to pay every time I need to send a message. I understand that there is no intrinsic connection between the internet and the cell-phone providers’ wireless networks. The companies that provide gateways between the two do so by having a GSM modem or another piece of physical hardware that sends the message — it is obvious why they charge.
What hit me today was kind of interesting: Most wireless companies provide an SMS gateway to their subscribers (a large list can be found on Wikipedia). This allows SMS messages to be sent via e-mail. For example, if I wanted to send a message to a Verizon customer with the phone number 123-456-7890, I can e-mail it to 1234567890@vtext.com. This is then forwarded, by Verizon, to the cell-phone. That means, it is completely possible to setup a PHP script, using nothing more than the mail() function, to send a text message.
Although that thought really excited me, I then realized I still had to tackle the other side of the problem: How do I send a text message to my server? This turned out to be a bit of a thought-process challenge but the implementation was very easy.
Most web hosts allow customers to setup mail forwarding. What many people do not know is this forwarding is not limited to other e-mail addresses. You can also “forward” (technically you “pipe” it) mail to a script. How this is actually done depends on the web-server. If Cpanel is installed, it is very simple. Apache requires a module to do this.
With all of these things in my head, I setup the e-mail address sms@aaron-rosenfeld.com to pipe to the script |/path/myroot/sms.php (for the non-Linux type, the first character “|” is required. That is why it’s known as the pipe!). The script did nothing besides write to a log file “Message Received!” when it was executed (another side note: make sure the file being piped to has execute privileges and starts with #!/usr/bin/php -q).
I quickly sent a text-message from my phone to sms@aaron-rosenfeld.com and sure enough I had “Message Received!” in my log file! To read the e-mail itself requires a bit more code:
$handle = fopen('php://stdin', 'r');
$content = '';
while (!feof($handle))
$content .= fread($handle, 1024);
fclose($handle);
I won’t go into detail but this just reads all the data that was piped from the e-mail to the PHP script. At the end, $content will store the entire e-mail including headers. To parse all of this out into a more readable form I used the following function (where $fullText is the $content from the last code-snippet):
$lines = explode("\n", $fullText);
$inMsg = false;
$this->message = '';
for ($i=0;$i<sizeof($lines);$i++)
{
if (!$inMsg)
{
$this->headers['all'][] = $lines[$i];
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches))
$this->headers['subject'] = $matches[1];
if (preg_match("/^From: (.*)/", $lines[$i], $matches))
$this->headers['from'] = $matches[1];
}
else
$this->message .= $lines[$i] . "\n";
if (trim($lines[$i]) == '')
$inMsg = true;
}
This sticks the e-mail message in $this->message and the headers in their own array, $this->headers[]. From here the possibilities are endless: database queries, server status monitors, checking e-mail, etc. I may post the full classes that I ended up using at some point but for now I though this would be adequate.
- Posted by Aaron Rosenfeld at 02:07 pm
- Permalink for this entry
- Filed under: Servers, Web Development
- RSS comments feed of this entry
- TrackBack URI
I’ve been reading along for a while now. I just wanted to drop you a comment to say keep up the good work.
Where did you get your blog layout from? I’d like to get one like it for my blog.
The theme is Hemingway: http://warpspire.com/hemingway/