| README.md | ||
| server.go | ||
| test.html | ||
Simple Contact Form Email Server (SCFES)
This has the purpose of listening for POST requests from a "contact me" or "contact us" form on a static webpage. It will log these in a Postgres database and also email them to whomever should be notified.
This server is developed to be run on a debian 9 server running nginx and PostgreSQL. Go was chosen as the scripting language, because its built in http server is considered "safe" to expose to the greater internet. The same cannot be said about Python. And I don't like nodejs...
Setup
This assumes you have a go dev environment running go>=1.10.
Server Executable
First get all required dependencies and builds into an executable, then copy it to a good location. It is possible to cross compile this executable from a local go dev environment and copy it to the server if go cannot be easily installed. Run this as a non-privlaged user with a valid go environment:
go get -u gitlab.com/pleune/simple-contact-form-email-server
sudo sh -c "mkdir -p /usr/local/bin && cp '$GOPATH/bin/simple-contact-form-email-server' /usr/local/bin/scfes"
Database
Install PostgreSQL, and create a database and user for this site (if you have not already for other purposes)
- See the debian setup page. Think about
using the user
www-data(nginx user) or even creating a new user. - Need to setup a "comments" table:
CREATE TABLE comments (id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(100), sendingip INET, referer VARCHAR(1024), time TIMESTAMP NOT NULL, message VARCHAR NOT NULL)
Nginx
Setup a forwarding rule in your Nginx configuration:
For example, put this in /etc/nginx/sites-enabled/default.conf:
location /contact {
proxy_pass http://localhost:8456;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Systemd Service
All configuration options are passed to the server through environment variables.
/etc/scfes.conf:
SCFES_LISTEN=":8456"
SCFES_SMTP_SERVER="YourSmtpServerAddress"
SCFES_SMTP_PORT="587"
SCFES_SMTP_USER="YourSmtpServerUsername"
SCFES_SMTP_PASS="YourSmtpServerPassword"
SCFES_FROM="no-reply@example.com"
SCFES_TO="you@gmail.com"
SCFES_SUBJECT="Contact from example.com"
SCFES_PG_CONNSTR="dbname=exampledotcom user=www-data password=yourpassword sslmode=disable"
/etc/systemd/system/scfes.service:
[Unit]
Description=Simple Contact Form Email Server (SCFES)
After=network.target
[Service]
User=nobody
EnvironmentFile=/etc/scfes.conf
ExecStart=/usr/local/bin/scfes
[Install]
WantedBy=multi-user.target
Install everything (as root):
# Because the config file has secrets in it,
# remove read rights from it:
chmod 600 /etc/scfes.conf
systemctl enable scfes.service
systemctl start scfes.service
Updating
Here is a snippet to quickly update the server:
go get -u gitlab.com/pleune/simple-contact-form-email-server &&
sudo systemctl stop scfes.service &&
sudo sh -c "mkdir -p /usr/local/bin && cp '$GOPATH/bin/simple-contact-form-email-server' /usr/local/bin/scfes" &&
sudo systemctl start scfes.service &&
echo "Update Successful..."
Server Code
This is an example form:
<form method="post" action="/contact">
<label for="name">Name</label>
<input type="text" name="name" id="name" /> <br />
<label for="email">Email</label>
<input type="email" name="email" id="email" /> <br />
<label for="message">Message</label>
<textarea name="message" id="message" rows="4"></textarea> <br />
<input type="submit" value="Send Message" />
</form>
Here is some JQuery to highlight fields in red if they are returned as invalid, and prevents redirection on submit:
var $contact = $('#contact')
var $name = $contact.find('#name')
var $email = $contact.find('#email')
var $message = $contact.find('#message')
var name_default_border = $name.css('border-color')
var email_default_border = $email.css('border-color')
var message_default_border = $message.css('border-color')
$contact.submit(function (event) {
event.preventDefault()
var f = $(this)
var url = f.attr('action')
$.ajax({
type: 'POST',
url: url,
data: f.serialize()
})
.fail(function (jqXHR, textStatus) {
var data = ((typeof jqXHR.responseText === 'string') ? jqXHR.responseText : " ")
var badname = data.includes('badname')
var bademail = data.includes('bademail')
var badmessage = data.includes('badmessage')
if (badname)
$name.css('border-color', 'red')
else
$name.css('border-color', name_default_border)
if (bademail)
$email.css('border-color', 'red')
else
$email.css('border-color', email_default_border)
if (badmessage)
$message.css('border-color', 'red')
else
$message.css('border-color', message_default_border)
if (!badname && !bademail && !badmessage)
alert('An error occurred that prevented your message from being processed.')
})
.done(function (data) {
$name.css('border-color', name_default_border)
$email.css('border-color', email_default_border)
$message.css('border-color', message_default_border)
$message.val('')
alert('Your comment has been successfully processed.\r\nThank You!')
})
})