OCI Email Deliveryを通してOracle APEXから電子メールを送信できるようになりました。これから、Salim Hlayelの記事にある電子メールによるキャンペーンを行うアプリケーションを作ります。
クイックSQLの以下のモデルから、表を作成します。
#prefix: cust
#language: ja
customers /insert 10
name
email
gender vc6 /values 男性, 女性
marital status /values 既婚, 死別, 独身
country vc255 /values 米国, 日本, 英国
モデルを画面左側に書き込み、SQLの生成、SQLスクリプトを保存、レビューおよび実行を順次クリックします。
SQLスクリプトを保存をクリックするとポップアップが開きます。
スクリプト名を入力してスクリプトの保存をクリックします。
レビューおよび実行をクリックすると、SQLワークショップのSQLスクリプトに含まれるスクリプト・エディタへ画面が遷移します。生成されたスクリプトを編集できます。
今回は編集は不要です。そのまま実行をクリックします。
アプリケーションの作成をクリックします。
アプリケーションを作成する
SQLスクリプトの実行結果が表示されている画面の、右上にあるアプリケーションの作成をクリックします。
確認画面が表示されるので、再度、アプリケーションの作成をクリックします。
アプリケーション作成ウィザードが起動します。
作成するアプリケーションの名前は電子メールキャンペーンとしています。
今回はホームページを使用しないため、編集をクリックしてダイアログを開きページを削除します。残りは対話レポートのページだけなので、自動的にレポートのページがホームになります。その他はデフォルトから変更しません。
アプリケーションの作成をクリックします。
アプリケーションの実行をクリックします。
デフォルトでは、Oracle APEXのワークスペースに登録されているユーザーによって認証されます。開発画面へのログインに使用したユーザー名とパスワードを入力してください。
Gender(性別)のヘッダーをクリックしフィルタ条件として男性を選びます。続けて、Marital Status(婚姻状況)のヘッダーをクリックし、独身を選びます。フィルタ条件は、アクション・メニューに含まれるフィルタからも設定できます。どのようなフィルタ条件を設定しても、これ以降の作業に影響はありませんので、好みのフィルタ条件を設定して構いません。
電子メールのテンプレートを作成する
キャンペーンとして送信する電子メールのテンプレートを作成します。
テンプレートは置き換え可能な顧客名や商品名の記述を含みます。テンプレートに含まれる顧客名や商品名といった情報は、電子メールとして送信する際に実際のデータで置換します。
共有コンポーネントのユーザー・インターフェースに含まれる、電子メール・テンプレートを開きます。
共有コンポーネントのユーザー・インターフェースに含まれる、電子メール・テンプレートを開きます。
電子メール・テンプレートの作成をクリックします。
識別として、テンプレート名、静的識別子、電子メールの件名を設定します。テンプレート名、静的識別子は英数字限定です。
- テンプレート名: New Year Promotion from Japan Branch
- 静的識別子: NEW_YEAR_PROMOTION_FROM_JAPAN_BRANCH
- 電子メールの件名: 新春プロモーション - 東京
HTMLフォーマットでの電子メールのヘッダー、本文、フッターを設定します。
ヘッダー
<b style="font-size: 24px;">New Year Promotion!</b>
本文
<b>こんにちは #CUSTOMER#さん</b><br>
<br>
<b>ただいま私たちのオンラインショップからの購入に限り、最大<span style="color: red;">75%</span>の割引を実施しております:</b><br>
<br>
<table width="100%">
<tr>
<th align="left">セール期間の開始</th>
<td>#START_DATE#</td>
</tr>
<tr>
<th align="left">セール期間の終了</th>
<td>#END_DATE#</td>
</tr>
<tr>
<th align="left" valign="top">対象店舗</th>
<td>#LOCATION#</td>
</tr>
<tr>
<th align="left" valign="top">ご案内</th>
<td>#NOTES#</td>
</tr>
<tr>
<th align="left" valign="top">対象製品</th>
<td>#ITEMS!RAW#</td>
</tr>
</table>
<br>
<b>数量に限りがこざいますので、ご購入はお早めに。</b><br>
<br>
フッター
<a href="#MY_APPLICATION_LINK#">This App created proudly using Oracle APEX</a>.
画面では以下のようになります。CUSTOMERとして与えた文字列は、HTMLとしてエスケープ(例えば>を>、"を"とする)した上で置き換えられます。これは、クロスサイトスクリプティングというセキュリティ上のリスクへの対応です。#ITEMS!RAW#として!RAWを指定すると、エスケープ処理は抑制されます。例えば置き換える文字列に<br>が含まれていると、デフォルトでは<br>と画面にそのまま表示されますが、!RAWが指定されるとHTMLタグ本来の意味である改行として扱われます。さらに、プレーン・テキスト・フォーマットの指定にある#ITEMS!STRIPHTML#のように!STRIPHTMLが指定されると、HTMLのタグ自体が置き換え対象から除外されます。<br>であれば、<br>が丸ごと除外されます。
電子メール・テンプレートの説明はマニュアルのこちら、置換文字列の説明はこちらにあります。
最近はあまりないと思いますが、HTMLの表示ができないクライアント向けにプレーン・テキスト・フォーマットでの本文を設定します。
プレーン・テキスト・フォーマット
最近はあまりないと思いますが、HTMLの表示ができないクライアント向けにプレーン・テキスト・フォーマットでの本文を設定します。
Hello #CUSTOMER#,
This email is to remind you of an upcoming event you are associated with.
Sale Starts: #START_DATE#
Sale Ends: #END_DATE#
Location: #LOCATION#
Notes: #NOTES#
Items: #ITEMS!STRIPHTML#
View additional details at: #MY_APPLICATION_LINK#
画面では以下のようになります。このテンプレートの使用を前提とした、APEX_MAILパッケージのSENDプロシージャの記述方法が示されます。このテンプレートが、CUSTOMER, END_DATE, ITEMS, LOCATION, MY_APPLICATION_LINK, NOTES, START_DATEの置換文字列を含んでいることがわかります。
以上で、電子メール・テンプレートの作成をクリックし、テンプレートを作成します。
電子メール・テンプレートが作成されました。
電子メールを送信するフォームを作成する
対話レポートで選択済みの顧客を対象として、キャンペーンを案内する電子メールを一括で送信するプロシージャーを作成します。
以下のコードをSQLワークショップのSQLコマンドに貼り付け実行すると、対話レポートで選択済みの顧客に電子メールを送信するプロシージャーsend_chanpaign_emailが作成されます。電子メールの本文は、登録したテンプレートをそれぞれの顧客名と、キャンペーン開始日(p_start_date)、キャンペーン終了日(p_end_date)、対象店舗(p_location)、案内文(p_notes)、対象商品(p_items)で穴埋めします。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
create or replace procedure send_campaign_email( | |
p_start_date in date | |
,p_end_date in date | |
,p_location in varchar2 | |
,p_notes in varchar2 | |
,p_items in varchar2 | |
) | |
is | |
l_context apex_exec.t_context; | |
l_emailsidx pls_integer; | |
l_namesids pls_integer; | |
l_region_id number; | |
begin | |
-- 対話モード・レポートのリージョンIDを取得する。 | |
select region_id | |
into l_region_id | |
from apex_application_page_regions | |
where application_id = v('APP_ID') | |
and page_id = 1 | |
and static_id = 'CUSTOMERS'; | |
-- 指定した対話レポートに設定済みのフィルタ条件で検索し、結果セットを l_context として取得する。 | |
l_context := apex_region.open_query_context( | |
p_page_id => 1 | |
,p_region_id => l_region_id | |
); | |
-- EMAILとNAMEの値を取り出すためのインデックスを取得する。 | |
l_emailsidx := apex_exec.get_column_position( l_context, 'EMAIL' ); | |
l_namesids := apex_exec.get_column_position( l_context, 'NAME' ); | |
-- 結果セットより一行つづ取り出し、それぞれキャンペーンのメールを送信する。 | |
while apex_exec.next_row( l_context ) loop | |
apex_mail.send( | |
p_to => apex_exec.get_varchar2( l_context, l_emailsidx ) | |
,p_from => '承認済送信者の電子メール・アドレスに置き換える' | |
,p_template_static_id => 'NEW_YEAR_PROMOTION_FROM_JAPAN_BRANCH' | |
,p_placeholders => '{' || | |
' "CUSTOMER":' || apex_json.stringify( apex_exec.get_varchar2( l_context, l_namesids )) || | |
' ,"START_DATE":' || apex_json.stringify( p_start_date ) || | |
' ,"END_DATE":' || apex_json.stringify( p_end_date ) || | |
' ,"LOCATION":' || apex_json.stringify( p_location ) || | |
' ,"NOTES":' || apex_json.stringify( p_notes ) || | |
' ,"ITEMS":' || apex_json.stringify( p_items ) || | |
' ,"MY_APPLICATION_LINK":' || apex_json.stringify( apex_mail.get_instance_url || apex_page.get_url( 1 )) || | |
'}'); | |
end loop; | |
apex_exec.close( l_context ); | |
apex_mail.push_queue; -- 即座にメールを送信する。テスト用途でありプロダクションでは推奨されない。 | |
exception | |
when others then | |
apex_exec.close( l_context ); | |
raise; | |
end send_campaign_email; |
フォームを作成する
作成したプロシージャを呼び出し、電子メールを送信するフォームを作成します。
ページの作成をクリックします。
ページ番号として3、ページ名として電子メールの送信、ページ・モードはモーダル・ダイアログを選択します。ページ・モードがモーダル・ダイアログなので、ナビゲーションのブレッドクラムの使用、ナビゲーションの使用ともにOFFになります。
次へ進みます。
作成するページに含まれるフォームを送信したときに呼び出されるプロシージャを指定します。
プロシージャの所有者には現在作業中のワークスペースに紐づいたスキーマがデフォルトで設定されます。変更の必要はありません。ストアド・プロシージャ名として、先ほど作成したプロシージャSEND_CAMPAIGN_EMAILを選びます。プロシージャを選択すると、その引数がフォームに含まれるプロシージャ引数の選択に一覧されます。
デフォルトでSEND_CAMPAIGN_EMAILプロシージャが持つすべての引数が含まれるので、それはそのままにします。ラベルと表示タイプをそれぞれ以下のように設定します。
- P_START_DATE: キャンペーン開始日、日付ピッカー
- P_END_DATE: キャンペーン終了日、日付ピッカー
- P_LOCATION: 対象店舗、テキスト・フィールド
- P_NOTES: 案内文、テキスト・フィールド
- P_ITEMS: 対象商品、テキスト・フィールド
以上を設定したのち、作成をクリックします。
電子メールを送信するページが作成されます。
ページ・アイテムP3_ITEMSのタイプをHTMLの入力が可能なようにリッチ・テキスト・エディタに変更します。設定の書式はHTMLです。電子メール・テンプレートでは#ITEMS!RAW#としてHTMLをエスケープせずに埋め込む記述になっていますので、P3_ITEMS(ラベル名は対象商品)として記載したHTMLは、電子メールでもHTMLとしてレンダリングされて表示されます。
プロセス・ビューを開き、プロセスRun Stored Procedureを選択します。
識別のタイプをAPIの呼出しに変更し、設定のタイプとしてPL/SQL Procedure or Function、プロシージャまたはファンクションとしてSEND_CAMPAIGN_EMAILを選択します。パラメータはデフォルトで、適切なページ・アイテムが割り当たります。
以上で電子メールを送信するページは完成です。
電子メールの送信を行うページはモーダル・ダイアログとして作成されています。ですので、かならず基底となるページがあって、そのページからダイアログとしてページを開きます。
対話モード・レポートから電子メールの送信ページを開く
電子メールの送信を行うページはモーダル・ダイアログとして作成されています。ですので、かならず基底となるページがあって、そのページからダイアログとしてページを開きます。
作成したページをダイアログとして開くボタンを、対話モード・レポートがあるページに追加します。
ページ1をページ・デザイナで開きます。そして、右ペインに表示されているレンダリング・ツリーのBreadcrumb Barに含まれる電子メールキャンペーンのリージョン上でコンテキスト・メニューを表示させ、ボタンの作成を実行します。
作成したボタンにたいして、識別のボタン名をSEND_MAIL、ラベルを電子メールの送信、レイアウトのボタン位置をNextとし、動作のアクションとしてこのアプリケーションのページにリダイレクト、ターゲットとして電子メールを送信するページを指定します。
タイプはこのアプリケーションのページ、ページは3です。
以上でページの変更を保存し、実行します。
ボタン電子メールの送信をクリックすると、追加で作成したキャンペーンの電子メールを送信するダイアログが開きます。
対話モード・レポートでGenderを男性、Marital Statusを独身としてフィルタします。リストに現れるEmailはサンプル・データであるため、このままではメールの送信は確認できません。送信されたメールを受け取ることができる電子メール・アドレス(大抵はこの作業を行っている本人の電子メール・アドレスになるかと思います)を設定してください。サンプル・データの電子メール・アドレスは実際の電子メール送信には使わないでください。
電子メール・アドレスを修正した後、電子メールの送信ボタンをクリックし、ダイアログを開きます。