F.81. utl_smtp — отправка электронных писем по протоколу SMTP #
utl_smtp — это расширение Postgres Pro, предназначенное для отправки электронных писем по протоколу SMTP из PL/pgSQL. Функциональность, предоставляемая этим модулем, во многом пересекается с функциональностью пакета UTL_SMTP
в Oracle.
F.81.1. Установка #
Расширение utl_smtp
включено в состав Postgres Pro Enterprise как стандартное расширение. Чтобы задействовать utl_smtp
, создайте расширение с помощью следующего запроса:
CREATE EXTENSION utl_smtp;
F.81.2. Использование #
Чтобы отправить электронное письмо с помощью расширения utl_smtp, необходимо вызывать функции в определённом порядке:
Сначала откройте соединение, вызвав функцию
open_connection
.Затем отправьте команду
HELO
/EHLO
SMTP-серверу, используя функцииhelo
/ehlo
соответственно.Отправьте адреса отправителя и получателя, используя функции
mail
иrcpt
.Вызовите функцию
opendata
, чтобы начать процесс отправки данных посредством отправки командыDATA
SMTP-серверу.После этого можно многократно вызывать функции
write_data
иwrite_raw_data
для отправки фактических данных.Процесс отправки данных завершается вызовом функции
close_data
.После вызова
open_data
можно вызывать только следующие функции:write_data
,write_raw_data
илиclose_data
. Вызов других функций приведёт к возникновению ошибки.Кроме того, процесс отправки данных можно упростить, однократно вызвав функцию
data
.После вызова
close_data
илиdata
электронное письмо отправлено — вызовите функциюquit
, чтобы завершить соединение.
F.81.3. Типы данных #
Расширение utl_smtp предоставляет следующие типы данных:
Тип
reply
представляет собой строку ответа SMTP. Каждая строка ответа SMTP состоит из кода ответа, за которым следует текстовое сообщение. Для большинства команд SMTP ожидается одна строка ответа, для некоторых — несколько строк.Таблица F.65. Параметры
reply
Параметр Описание code
3-значный код ответа int
Текстовое сообщение ответа Тип
connection
представляет собой соединение по протоколу SMTP.Таблица F.66. Параметры
connection
Параметр Описание host
Имя или IP-адрес удалённого узла при установке соединения. port
Номер порта подключённого удалённого SMTP-сервера. tx_timeout
Время ожидания расширением utl_smtp операций чтения или записи в этом соединении, в секундах. Таймаут соединения с сервером всегда составляет 60 секунд и не может быть настроен. private_socket
Этот параметр используется внутри Postgres Pro и не должен изменяться вручную.
F.81.4. Функции utl_smtp #
Расширение utl_smtp предоставляет функции для отправки электронных писем по протоколу SMTP. Обратите внимание, что функции, которые должны возвращать несколько строк ответа, возвращают массив типа reply
.
-
auth(
#c
connection
,username
text
,password
text
,schemes
text
default 'PLAIN') returnsreply
Отправляет SMTP-серверу команду
AUTH
для аутентификации. В настоящее время поддерживается только схема аутентификацииPLAIN
.-
close_all_connections() returns
#void
Закрывает все SMTP-соединения и освобождает все связанные с ними ресурсы.
-
close_connection(
#c
connection
) returnsvoid
Закрывает указанное SMTP-соединение. Эту функцию можно вызвать при отправке данных на сервер перед вызовом
close_data
. В этом случае следующий вызов функции с этим соединением выдаст исключение.-
close_data(
#c
connection
) returnsreply
Завершает сообщение электронной почты отправкой последовательности
<CR><LF>.<CR><LF>
(одна точка в начале строки).-
command(
#c
connection
,cmd
text
,arg
text
default null) returnsreply
Отправляет произвольную команду SMTP и может возвращать несколько строк ответа.
-
data(
#c
connection
,body
text
) returnsreply
Указывает тело электронного письма. По сути, это последовательность вызовов следующих функций:
open_data
,write_data
иclose_data
.-
ehlo(
#c
connection
,domain
text
) returnsreply
Выполняет начальное согласование с SMTP-сервером с помощью команды
EHLO
. Сервер возвращает часть своей конфигурации.-
helo(
#c
connection
,domain
text
) returnsreply
Выполняет начальное согласование с SMTP-сервером с помощью команды
HELO
.-
help(
#c
connection
,command
text
default null) returnsreply
Отправляет команду
HELP
. Эта команда может быть реализована не на всех SMTP-серверах.-
last_reply(
#c
connection
) returnsreply
Возвращает последний ответ SMTP-сервера.
-
mail(
#c
connection
,sender
text
,parameters
text
default null) returnsreply
Инициирует транзакцию отправки электронного письма с сервером, отправляя команду
MAIL
с адресом отправителя.-
noop(
#c
connection
) returnsreply
Выдаёт команду
NOOP
. Эта функция в основном используется для проверки соединения.-
open_connection(
#host
text
,port
int
default 25,tx_timeout
int
default null,secure_connection_before_smtp
bool
default false,verify_peer
bool
default true) returnsconnection
Открывает соединение с SMTP-сервером. Параметр
secure_connection_before_smtp
указывает, устанавливается ли подключение TLS до соединения SMTP (по сути, если этот параметр имеет значение true, соединение будет использовать SMTPS вместо SMTP). Параметрverify_peer
указывает, проверяются ли сертификаты при установке подключения TLS.-
open_data(
#c
connection
) returnsreply
Отправляет команду
DATA
, после которой можно использовать функцииwrite_data
иwrite_raw_data
, чтобы написать часть электронного письма.-
quit(
#c
connection
) returnsreply
Завершает сеанс SMTP и отключается от сервера.
-
rcpt(
#c
connection
,recipient
text
,parameters
text
default null) returnsreply
Указывает получателя электронного письма. Транзакция отправки сообщения должна быть запущена предыдущим вызовом
MAIL
, а соединение с почтовым сервером должно быть открыто и инициализировано предыдущими вызовамиopen_connection
иhelo
илиehlo
соответственно.-
rset(
#c
connection
) returnsreply
Завершает текущую транзакцию отправки письма. Клиент может вызвать
rset
в любое время после открытия соединения с SMTP-сервером с помощьюopen_connection
до вызоваdata
илиopen_data
.-
set_reply_error_check(
#c
connection
,enable
bool
) returnsvoid
Определяет поведение функции. Если для параметра
enable
установлено значение true (по умолчанию), любая ошибка на SMTP-сервере выдаёт исключение. Если установлено значение false, для определения ошибки пользователю следует самостоятельно анализировать результаты, возвращаемые функциями.-
starttls(
#c
connection
,verify_peer
bool
default true) returnsreply
Отправляет команду
STARTTLS
для защиты SMTP-соединения с использованием TLS.-
vrfy(
#c
connection
,recipient
text
) returnsreply
Отправляет команду
VRFY
для проверки корректности адреса получателя электронного письма. Эта команда может быть реализована не на всех SMTP-серверах и может возвращать некорректную информацию, поэтому не рекомендуется её использовать.-
write_data(
#c
connection
,data
text
) returnsvoid
Отправляет часть текста сообщения, включая заголовки, SMTP-серверу. При повторном вызове
write_data
добавляет данные к сообщению.-
write_raw_data(
#c
connection
,data
text
) returnsvoid
Отправляет часть текста сообщения, включая заголовки, SMTP-серверу. При повторном вызове
write_data
добавляет данные к сообщению. Эта функция аналогична функцииwrite_data
.
F.81.5. Примеры #
В следующем примере показана отправка электронного письма без вложения с помощью utl_smtp.
DO $$ DECLARE conn utl_smtp.connection; BEGIN conn := utl_smtp.open_connection('smtp.mail.ru', 25, 10); perform utl_smtp.ehlo(conn, 'localhost'); perform utl_smtp.starttls(conn); perform utl_smtp.ehlo(conn, 'localhost'); perform utl_smtp.auth(conn, 'test_email@example.com', 'super-secret-password'); perform utl_smtp.mail(conn, 'sender@example.com'); perform utl_smtp.rcpt(conn, 'recipient@example.com'); perform utl_smtp.open_data(conn); perform utl_smtp.write_data(conn, E'Content-Type: multipart/mixed; boundary=------------------------6f48b7d5ded0c5fc\n'); perform utl_smtp.write_data(conn, E'Mime-Version: 1.0\n'); perform utl_smtp.write_data(conn, E'From: Sender <sender@example.com>\n'); perform utl_smtp.write_data(conn, E'To: Recipient <recipient@example.com>\n'); perform utl_smtp.write_data(conn, E'Subject: mail from utl_smtp\n'); perform utl_smtp.write_data(conn, E'--------------------------6f48b7d5ded0c5fc\n'); perform utl_smtp.write_data(conn, E'Content-Type: text/plain; charset=\"UTF-8\"\n'); perform utl_smtp.write_data(conn, E'Content-Transfer-Encoding: 8bit\n\n'); perform utl_smtp.write_data(conn, E'This is body from inside Postgres Pro\n'); perform utl_smtp.write_data(conn, E'Sent using utl_smtp\n'); perform utl_smtp.write_data(conn, E'\n--------------------------6f48b7d5ded0c5fc--\n'); perform utl_smtp.close_data(conn); perform utl_smtp.quit(conn); END$$;
В следующем примере показана обработка исключений с помощью utl_smtp.
DO $$ DECLARE ... r utl_smtp.reply; BEGIN ... some utl_smtp funcion calls ... exception when others then r = utl_smtp.last_reply(conn); if r.code >= 500 then raise notice 'caught permanent error'; elsif r.code >= 400 then raise notice 'caught transient error'; else raise notice 'some other error'; end if; END$$;