You are here

cloud

Parse emails and insert into a MySQL Database using PHP

I had a problem where I needed to parse emails and insert them into a MySQL database in real time as they are received. This is a relatively easy problem to figure out, but I wanted to outline the steps I took to tackle this in case anyone else wanted simple, step by step instructions on how to solve this problem.

First of all, this solution uses Linux, specifically I like to use Ubuntu. I also used Postfix, an open source mail server. Finally, the mail script is based on Eric London's mail parsing script so he did all the mail heavy lifting. I simply added some database stuff to insert it into a MySQL table using PDO. Props to Eric for a great script that simplified this task for me.

To start, you will need a linux server. I use Amazon EC2 instances in the cloud so I just fire up one of alestic's AMIs and bam, server. I make sure the security preferences allow incoming on port 25 (SMTP). (Note: if you are having issues, it could be a security / firewall issue.) For testing purposes I use the micro AMI because they are inexpensive.

Once I have SSH-ed into the box, I run a few commands to make sure everything is up to date and that I have all the tools and software I need installed.


apt-get update && apt-get upgrade -y
tasksel install lamp-server
apt-get install postfix php5-cli

You don't actually need Apache for what we are doing here but I am installing the entire lamp stack for ease and simplicity and I will be using it later.

Let's create our database called email and the mail table where we will store the incoming email:


mysql -p
create database email
CREATE TABLE `mail` (
`mid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created` int(10) unsigned NOT NULL DEFAULT '0',
`body` longtext,
`return_path` varchar(255) DEFAULT NULL,
`x_original_to` varchar(255) DEFAULT NULL,
`delivered_to` varchar(255) DEFAULT NULL,
`mailto` varchar(255) DEFAULT NULL,
`subject` varchar(255) DEFAULT NULL,
`message_id` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`maildate` int(11) DEFAULT NULL,
`mailfrom` varchar(255) DEFAULT NULL,
`added` tinyint(3) unsigned NOT NULL,
`content_transfer_encoding` varchar(255) DEFAULT NULL,
PRIMARY KEY (`mid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='incoming mail';

Its important that the default charset is UTF8 because this can be a problem if you are in the UK or other countries where character set issues can happen.

Now we are going to make a folder in our home directory and put our mail script in there:


mkdir /home/default/scripts

I have attached the mail.php script file to this post so grab it and put it in your scripts directory that you created above. (Its named mail.php_.txt, you you will need to rename it to mail.php.)

You will need to edit the configuration variables at the top of the file to connect to the database properly and send emails to your email address if there are errors. Another thing to keep in mind is that the script uses PDO so your version of PHP needs to support that (PHP 5.1 or greater).

Now we edit our Postfix aliases file to pipe mail from a specific account to a script that we will be added later:


nano /etc/aliases

Add a line at the bottom of the file:


import: "|php -q /home/default/scripts/mail.php"

Import is the name of the account so if you want the beginning of the email address (before the @) to be something different, change this.

Finally, you are going to need to setup some DNS entries to route mail to your linux server: an A and MX record. There are lots of resources on how to do this on the Internet. Lets say the email address you were using for this was import@server.domain.com, you would need two records to make this work:

server.domain.com. IN A 50.50.50.50
server.domain.com. IN MX 10 server.domain.com.

If you don't know what any of this means, hopefully you have access to a web interface that can set this up for you.

Assuming everything went well, you should be able to send email to your linux server and it will be inserting the mail into your database table. Enjoy!

Using Amazon EC2 micro instances to create development sandboxes for Drupal

I recently contracted out some work for a project I am working on in Drupal because it involved CSS, HTML and theming and quite frankly, my skills in that area suck. I used ODesk because I do some other data entry outsourcing there and it works quite well. Anyways, it was relatively easy to find a qualified person to do the work. Now the supposedly hard part, setting up a sandbox for a remote worker to access and do the work. This was a rush job that needed to get done yesterday so I needed something setup quickly.

Well luckily with Amazon EC2 and its nifty cloud, this turned out to be quite easy. I created a a micro instance in the US East (Virginia) region which costs a whopping 2 cents per hour (works out to about $15 / month). This can be decreased significantly by purchasing reserved instances. I used an EBS-backed instance so that I can start / stop it at will and not have it running if I don't need. I also assign a custom security group to it so I can add or drop custom firewall rules and it doesn't affect my other live instances. Finally, I use Ubuntu 10.04 LTS and Alestic's AMIs because its fast and simple to setup and run.

So now I have a running Ubuntu instance, now what? Well with a few simple commands, I can get a Drupal website up and running. Keep in mind this is a short term server that I need to focus on ease of use, not security so what I am doing would not be appropriate for anything else.

Copy authorized keys to root .ssh dir so I can login as root:
sudo cp ~/.ssh/authorized_keys /root/.ssh/

Now logout and SSH back in as root.

Update your Ubuntu instance:
apt-get update && apt-get -y upgrade

Install LAMP server:
tasksel install lamp-server

Edit your default site Apache configuration file with your favourite editor and point to your new htdocs dir (/home/htdocs):
pico /etc/apache2/sites-available/default

Enable mod rewrite for Drupal and reload Apache:
a2enmod rewrite
/etc/init.d/apache2 reload

Login to MySQL and create your database:
mysql -p
create database databasename

Now ssh to your live/development server and create a backup of your site with db to move to sandbox:
cd /home/htdocs
mysqldump -p databasename > db_date.sql
cd ..
tar .zcvf mywebsite.tar.gz htdocs/
rm htdocs/db_date.sql
scp mywebsite.tar.gz sandbox:/home/htdocs/

Now flip back to your sandbox and extract your tar file:

tar xfz mysqwebsite.tar.gz

Edit your Drupal settings file to point to database:

pico sites/default/settings.php

Load your database from the dump and delete the dump file:

mysql -p databasename < /home/htdocs/db_date.sql
rm /home/htdocs/db_date.sql

Now your website should be operational.

For quick access to your remote developer you can simply enable password security for your SSH daemon by changing PasswordAuthentication setting to Yes, assign a password for root and reloading SSH daemon:

pico /etc/ssh/sshd_config
passwd
/etc/init.d/sshd reload

Because most FTP clients support SFTP (FTP over SSH), your remote developer can now access your sandbox and you should be good to go.

Keep in mind that giving out root access is not ideal, nor is most of what I have talked about here good for security. In fact, it flies in the face of most best practice security measures that should be taken for any server. But if you need to get a server up and running fast for a remote worker to get stuff done quickly, it works and does the job.

Make sure you stop and/or terminate your instance as soon as you are done with it! Enjoy.

Managing linux EC2 instances (or any remote linux machines)

Its been a while since I posted anything so I thought I would talk about how I've setup my servers using Amazon's EC2 cloud services for easy administration. I have several instances running mostly Ubuntu 10.04.

Some of this stuff may be pretty simple to you depending on your level of expertise but it really simplified administration for me so I wanted to share.

I put all my keys in a folder in my home directory and then I have a file named config in my ~/.ssh folder that looks something like this:


Host server_alias
User ubuntu
Hostname public_address_to_server
IdentityFile ~/.keys/key_file.pem
Localforward 6033 localhost:3306

I have an entry like what is shown above for each server. Once you have a host setup in your config file, you can ssh to your server with one very simple command:

ssh server_alias

Wow, that was easy. There's also a bunch of other cool things you can do once you have this setup.

You'll notice I have a local forward setup on port 6033. This allows me to connect to my remote MySQL server (running on its default port of 3306) once I have established an SSH connection using the port 6033. I can use MySQL GUI tools or simply connect with the MySQL command line utility like so:

mysql -h 127.0.0.1 -P 6033 -p

I am not sure why but for whatever reason, it doesn't work if I enter localhost but if I use 127.0.0.1 it does. Weird.

File sharing over ssh is also super simple. Simply use the sshfs command line tool:

sshfs server_alias:/home/whatever_dir ~/server_alias

Booyah, now I can manipulate folders and files on my remote server locally. If you want to kill the share, simply use:

fusermount -uz server_alias

Props to @netwonk for helping me get a lot of this stuff going. Happy server administrating!

Free hosting for a year

Amazon recently announced that they are giving away a free micro instance to new accounts on their EC2 service. They call it their free usage tier.

So what is a micro instance then? Well, its their smallest computing unit in Amazon's cloud service. Basically, fire up one of these bad boys and you have your own little virtual server that exists somewhere in Amazon's vast computing nebulous.

What can you do it with it? Anything you want really. But most people will probably run linux on it and set up a LAMP (linux, apache, mysql, php) server to run web sites / applications.

What kind of experience do I need? Unfortunately, you need some skills to use Amazon's cloud services, its like running your own server with a little added complication.

I have found that micro instances are decent for most small to medium websites and testing. However, they can be a little underpowered especially with memory because they only have 630 something megabytes of RAM.

But who can complain with free? Existing customers like me I guess who the deal doesn't extend to.

More information on Amazon's EC2 free usage tier.