Skip to content

Commit 61638c1

Browse files
committed
minor code improvements; added PLS-00322 trigger if constants aren't edited prior to compilation
1 parent 81e69ec commit 61638c1

File tree

2 files changed

+88
-67
lines changed

2 files changed

+88
-67
lines changed

mailgun_pkg.pkb

Lines changed: 84 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
create or replace package body mailgun_pkg is
2-
/* mailgun API v0.4
2+
/* mailgun API v0.4.2
33
by Jeffrey Kemp
44
*/
55

6-
g_public_api_key constant varchar2(200) := ''; --TODO: put your public API key here
7-
g_private_api_key constant varchar2(200) := ''; --TODO: put your private API key here
8-
g_my_domain constant varchar2(200) := ''; --TODO: put your domain here
6+
-- If you get "PLS-00322: declaration of a constant 'x' must contain an initialization assignment",
7+
-- it's probably because you forgot to edit the constants below.
8+
9+
g_public_api_key constant varchar2(200) /*:= 'TODO: put your public API key here' */;
10+
g_private_api_key constant varchar2(200) /*:= 'TODO: put your private API key here' */;
11+
g_my_domain constant varchar2(200) /*:= 'TODO: put your domain here' */;
912
g_api_url constant varchar2(200) := 'https://api.mailgun.net/v3/'; --TODO: change this if you are using reverse proxy method
1013
g_wallet_path constant varchar2(1000) := ''; --TODO: put your wallet path here if using Oracle wallet
1114
g_wallet_password constant varchar2(1000) := ''; --TODO: put your wallet password here if using Oracle wallet
1215

13-
crlf constant varchar2(50) := chr(13) || chr(10);
14-
boundary constant varchar2(100) := '-----zdkgyl5aalom86symjq9y81s2jtorr';
16+
boundary constant varchar2(100) := '-----n8vtmn6973vyrnsw1agnxs7gzc4e1r';
1517
max_recipients constant integer := 1000; -- mailgun limitation for recipient variables
1618
queue_name constant varchar2(30) := sys_context('userenv','current_schema')||'.mailgun_queue';
1719
queue_table constant varchar2(30) := sys_context('userenv','current_schema')||'.mailgun_queue_tab';
@@ -162,6 +164,10 @@ begin
162164
assert(p_email is not null, 'add_recipient: p_email cannot be null');
163165
assert(p_send_by is not null, 'add_recipient: p_send_by cannot be null');
164166
assert(p_send_by in ('to','cc','bcc'), 'p_send_by must be to/cc/bcc');
167+
168+
-- don't allow a list of email addresses in one call
169+
assert(instr(p_email,',')=0, 'add_recipient: p_email cannot contain commas (,)');
170+
assert(instr(p_email,';')=0, 'add_recipient: p_email cannot contain semicolons (;)');
165171

166172
name := nvl(p_name, trim(p_first_name || ' ' || p_last_name));
167173

@@ -362,30 +368,35 @@ procedure send_email (p_payload in out nocopy t_mailgun_email) is
362368
resp utl_http.resp;
363369
my_scheme varchar2(256);
364370
my_realm varchar2(256);
365-
buf varchar2(32767);
366371
attachment_size integer;
367372
resp_text varchar2(32767);
368373
recipient_count integer := 0;
369374
attachment_count integer := 0;
370375
log mailgun_email_log%rowtype;
371376

372377
procedure append_recipient (rcpt_list in out varchar2, r in t_mailgun_recipient) is
373-
begin
374-
378+
begin
375379
if rcpt_list is not null then
376-
rcpt_list := rcpt_list || ', ';
380+
rcpt_list := rcpt_list || ',';
377381
end if;
378382
rcpt_list := rcpt_list || r.email_spec;
379-
383+
end append_recipient;
384+
385+
procedure add_recipient_variable (r in t_mailgun_recipient) is
386+
begin
380387
apex_json.open_object(r.email);
381388
apex_json.write('email', r.email);
382389
apex_json.write('name', r.name);
383390
apex_json.write('first_name', r.first_name);
384391
apex_json.write('last_name', r.last_name);
385392
apex_json.write('id', r.id);
386393
apex_json.close_object;
387-
388-
end append_recipient;
394+
end add_recipient_variable;
395+
396+
procedure append_header (buf in varchar2) is
397+
begin
398+
dbms_lob.writeappend(header, length(buf), buf);
399+
end append_header;
389400

390401
procedure log_response is
391402
-- needs to commit the log entry independently of calling transaction
@@ -446,72 +457,79 @@ begin
446457

447458
if p_payload.to_email is not null then
448459
assert(recipient_count = 0, 'cannot mix multiple recipients with to_email parameter');
449-
if p_payload.to_email like '% <%>%' then
450-
recipients_to := p_payload.to_email;
451-
else
460+
461+
if p_payload.to_name is not null
462+
and p_payload.to_email not like '% <%>%'
463+
and instr(p_payload.to_email, ',') = 0
464+
and instr(p_payload.to_email, ';') = 0 then
465+
-- to_email is just a single, simple email address, and we have a to_name
452466
recipients_to := nvl(p_payload.to_name, p_payload.to_email) || ' <' || p_payload.to_email || '>';
467+
else
468+
-- to_email is a formatted name+email, or a list, or we don't have any to_name
469+
recipients_to := replace(p_payload.to_email, ';', ',');
453470
end if;
471+
454472
end if;
455473

456-
recipients_cc := p_payload.cc;
457-
recipients_bcc := p_payload.bcc;
474+
recipients_cc := replace(p_payload.cc, ';', ',');
475+
recipients_bcc := replace(p_payload.bcc, ';', ',');
476+
477+
if recipient_count > 0 then
478+
for i in 1..recipient_count loop
479+
-- construct the comma-delimited recipient lists
480+
case p_payload.recipient(i).send_by
481+
when 'to' then
482+
append_recipient(recipients_to, p_payload.recipient(i));
483+
when 'cc' then
484+
append_recipient(recipients_cc, p_payload.recipient(i));
485+
when 'bcc' then
486+
append_recipient(recipients_bcc, p_payload.recipient(i));
487+
end case;
488+
end loop;
489+
end if;
458490

459-
begin
460-
apex_json.initialize_clob_output;
461-
apex_json.open_object;
491+
assert(recipients_to is not null, 'send_email: recipients list cannot be empty');
492+
493+
dbms_lob.createtemporary(header, false, dbms_lob.call);
494+
495+
append_header(crlf
496+
|| form_field('from', sender)
497+
|| form_field('h:Reply-To', p_payload.reply_to)
498+
|| form_field('to', recipients_to)
499+
|| form_field('cc', recipients_cc)
500+
|| form_field('bcc', recipients_bcc)
501+
|| form_field('o:tag', p_payload.tag)
502+
|| form_field('subject', p_payload.subject)
503+
);
462504

463-
if recipient_count > 0 then
505+
if recipient_count > 0 then
506+
begin
507+
-- construct the recipient variables json object
508+
apex_json.initialize_clob_output;
509+
apex_json.open_object;
464510
for i in 1..recipient_count loop
511+
add_recipient_variable(p_payload.recipient(i));
512+
end loop;
513+
apex_json.close_object;
465514

466-
case p_payload.recipient(i).send_by
467-
when 'to' then
468-
append_recipient(recipients_to, p_payload.recipient(i));
469-
when 'cc' then
470-
append_recipient(recipients_cc, p_payload.recipient(i));
471-
when 'bcc' then
472-
append_recipient(recipients_bcc, p_payload.recipient(i));
473-
end case;
474-
475-
end loop;
476-
end if;
477-
478-
apex_json.close_object;
479-
480-
assert(recipients_to is not null, 'send_email: recipients list cannot be empty');
481-
482-
dbms_lob.createtemporary(header, false, dbms_lob.call);
483-
484-
header := crlf
485-
|| form_field('from', sender)
486-
|| form_field('h:Reply-To', p_payload.reply_to)
487-
|| form_field('to', recipients_to)
488-
|| form_field('cc', recipients_cc)
489-
|| form_field('bcc', recipients_bcc)
490-
|| form_field('o:tag', p_payload.tag)
491-
|| form_field('subject', p_payload.subject)
492-
|| field_header('recipient-variables');
493-
494-
dbms_lob.append(header, apex_json.get_clob_output);
495-
496-
apex_json.free_output;
497-
498-
exception
499-
when others then
500-
apex_json.free_output;
501-
raise;
502-
end;
515+
append_header(field_header('recipient-variables'));
516+
dbms_lob.append(header, apex_json.get_clob_output);
517+
518+
apex_json.free_output;
519+
exception
520+
when others then
521+
apex_json.free_output;
522+
raise;
523+
end;
524+
end if;
503525

504526
if p_payload.mail_headers is not null then
505-
buf := render_mail_headers(p_payload.mail_headers);
506-
dbms_lob.writeappend(header, length(buf), buf);
527+
append_header(render_mail_headers(p_payload.mail_headers));
507528
end if;
508529

509-
buf := crlf || field_header('html');
510-
dbms_lob.writeappend(header, length(buf), buf);
511-
530+
append_header(field_header('html'));
512531
dbms_lob.append(header, p_payload.message);
513-
514-
dbms_lob.writeappend(header, length(crlf), crlf);
532+
append_header(crlf);
515533

516534
footer := '--' || boundary || '--';
517535

mailgun_pkg.pks

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
create or replace package mailgun_pkg is
2-
/* mailgun API v0.4
2+
/* mailgun API v0.4.2
33
by Jeffrey Kemp
44

55
Refer to https://github.com/jeffreykemp/mailgun-plsql-api for detailed
@@ -85,6 +85,9 @@ repeat_interval_default constant varchar2(200) := 'FREQ=MINUTELY;INTERVAL=5;';
8585
-- mail datetime format
8686
datetime_format constant varchar2(100) := 'Dy, dd Mon yyyy hh24:mi:ss tzh:tzm';
8787

88+
-- copy of utl_tcp.crlf for convenience
89+
crlf constant varchar2(2) := chr(13) || chr(10);
90+
8891
-- validate_email: validate an email address (procedure version)
8992
-- p_address: email address to validate
9093
-- p_is_valid: true if the email address appears to be valid

0 commit comments

Comments
 (0)