Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: captbrando
18 changes: 18 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
Change Log.

v1.5 - pgMail has been updated to support the utf-8 character set
inside pltclu. (thanks Glukhov Sergey)
- Updated README to reflect modern PostgreSQL implementations
as some commands and suggestions were actually deprecated. (me)
- Updated the example scripts to use modern trigger return
vs opaque data type. (me)

v1.4 - pgMail now supports both HTML messaging and MULTIPART MIME
messaging. It's backwards compatible. If you want to ONLY send
HTML, you need to pass an empty string as your 4th argument.
But why not just do both plain text & HTML? Thanks to
Nicklas Aven for the idea and original patch! I changed his
pull request a bit to avoid duplicate code. (me)

v1.3 - pgMail will now add a properly formatted Date header. This was
particularly troubling for some Android users. Thanks to
Nicklas Aven for the patch! (me)

v1.2 - pgMail now properly sends UTF-8 encoded emails. Thanks to
Balazs Keresztury for the patch! (me)
- Fixed an issue whereby some servers would reject emails due to
Expand Down
94 changes: 0 additions & 94 deletions README

This file was deleted.

84 changes: 84 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# pgMail v1.5 (12/10/2024)
pgMail is maintained by Branden R. Williams

![Open Issues](https://img.shields.io/github/issues/captbrando/pgMail) ![Open PRs](https://img.shields.io/github/issues-pr/captbrando/pgMail) ![Last Commit](https://img.shields.io/github/last-commit/captbrando/pgMail)

Visit the homepage at [BrandoLabs](http://www.brandolabs.com/pgmail)

If you are interested in contributing to the project please email the maintainer directly.

---

Copyright 2002-2025 Branden R. Williams.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

---

## Getting Started

Welcome! This README will be short and sweet so you can get to coding!

Essentially, pgMail is simply a stored function written in TCL which takes 4 arguments of type 'text' (Who is it from, who is it to, subject, and body of message), contacts the email server via TCL sockets, and transmits your email (Now UTF-8 Compatible!).

Before you can use pgMail, you must install the TCL/u procedural language. TCL/u is an UNRESTRICTED version of TCL that the database may use in its stored functions. ** Take into account that you must prepare adequate security precautions when adding the TCL/u language to your database! ** The author will not be responsible for misconfigured servers allowing dangerous users to do bad things.

To install the TCL/u procedural language, you must have compiled and installed the TCL extensions of PostgreSQL (or in the binary versions, just make sure you install the TCL package for your distribution). Once you are sure this has been completed, simply type the following at the unix shell prompt as a database administrator.

```bash
# psql -c 'CREATE EXTENSION pltclu' <DATABASE>
```

In the place of <DATABASE>, put the name of your database that you will be adding the stored procedure to. If you want it to also be added to all new databases, use "template1" as your database name.

**BEFORE ADDING THE PROCEDURE TO YOUR DATABASE YOU MUST DO THE FOLLOWING!**

* Replace the text <ENTER YOUR MAILSERVER HERE> with the fully qualified domain name for your mailserver. i.e., mail.server.com.
* Replace the text <ENTER YOUR DATABASESERVER HERE> with the fully qualified domain name for your database server. i.e., db.server.com.

**NOW ON TO LESS DRAMATIC TEXT!**

Once you have completed this step, use the psql interface to add the pgMail function. Just copy the contents of the pgmail.sql file and paste it into your window. You may also load it directly from the command line by typing:

```bash
# psql -e [database] < pgmail.sql
```

Once you have installed the stored function, simply call the procedure as follows.

```
select pgmail('Send From <from@from.com>','Send To <to@to.com>',
'Subject goes here','Plaintext message body here.');

select pgmail('Send From <from@from.com>','Send To <to@to.com>',
'Subject goes here','','HTML message body here.');
```

Or now, multipart MIME!

```
select pgmail('Send From <from@from.com>','Send To <to@to.com>',
'Subject goes here','Plaintext message body here.', 'HTML message body here.');
```

In both the Send From and Send To fields, you may include either only the email, or the email enclosed in <> with a plaintext name.

The code in this repository is certified against PostgreSQL 15+.

## Testing Your Install

There are some examples to try which have been included. You MUST FIRST replace the string <YOUREMAIL> in the example.execute.sql script with your real email address, and install the plpgsql language just like you did the pltclu above. You can do that by entering a "createlang [YOUR DATABASE] plpgsql".

Once that is complete, execute the example.setup.sql. Then execute the example.execute.sql script. You will see 2 emails in your mailbox. To remove this example, execute the example.cleanup.sql script.

If you have any other questions, please visit the [homepage](http://www.brandolabs.com/pgmail/) or open an issue at GitHub.
2 changes: 1 addition & 1 deletion example.setup.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ create table orders (
paystatus varchar(1) default 'n'
);

create function checkordermail() returns opaque as '
create function checkordermail() returns trigger as '
DECLARE
customerRec RECORD;
textMessage text;
Expand Down
33 changes: 27 additions & 6 deletions pgMail.sql
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
create function pgmail(text, text, text, text) returns int4 as '
create function pgmail(text, text, text, text, text default '') returns int4 as '
set mailfrom $1
set mailto $2
set mailsubject $3
set mailmessage $4
set mailmessage_html $5
if {$mailmessage ne "" && $mailmessage_html ne ""} {
set multipart true
} else {
set multipart false
}
set myHost "<ENTER YOUR MAILSERVER HERE>"
set myPort 25
set mySock [socket $myHost $myPort]
Expand All @@ -25,7 +31,7 @@ if {$fromemailaddress_start != -1} {
set fromemailaddress $mailfrom
}
fileevent $mySock writable [list svcHandler $mySock]
fconfigure $mySock -buffering line
fconfigure $mySock -buffering line -encoding utf-8
puts $mySock "HELO <ENTER YOUR DATABASESERVER HERE>"
gets $mySock name
puts $mySock "MAIL FROM: $fromemailaddress"
Expand All @@ -34,14 +40,29 @@ puts $mySock "RCPT TO: $toemailaddress"
gets $mySock name
puts $mySock "DATA"
gets $mySock name
puts $mySock "Date: [clock format [clock seconds] -format {%a, %d %b %Y %H:%M:%S +0000} -gmt true]"
puts $mySock "From: $mailfrom"
puts $mySock "To: $mailto"
puts $mySock "Subject: $mailsubject"
puts $mySock "MIME-Version: 1.0"
puts $mySock "Content-type: text/plain; charset=UTF-8"
puts $mySock "Content-Transfer-Encoding: 8bit"
puts $mySock ""
puts $mySock "$mailmessage"
if {$multipart} {
puts $mySock {Content-type: multipart/mixed; boundary="just_a_simple_boundary"}
}
if {$mailmessage ne ""} {
if {$multipart} {puts $mySock "--just_a_simple_boundary"}
puts $mySock "Content-type: text/plain; charset=UTF-8"
puts $mySock "Content-Transfer-Encoding: 8bit"
puts $mySock ""
puts $mySock "$mailmessage"
}
if {$mailmessage_html ne ""} {
if {$multipart} {puts $mySock "--just_a_simple_boundary"}
puts $mySock "Content-type: text/html; charset=UTF-8"
puts $mySock "Content-Transfer-Encoding: 8bit"
puts $mySock ""
puts $mySock "$mailmessage_html"
}
if {$multipart} {puts $mySock "--just_a_simple_boundary--"}
puts $mySock ""
puts $mySock "."
gets $mySock name
Expand Down