2011年5月11日 星期三

讓 Oracle 透過 SMTP 元件發送 iPhone 看得懂的 eMail

系統透過 Oracle 發送郵件,原本是沒有特別指定什麼編碼什麼的,
Outlook 收信收的好好的,開放 Push Mail 後,User 開始用手機收信了,
但是透過 Oracle 發送出來的郵件,在 iPhone 上看,
在郵件清單預覽的時候,主旨跟內文兩行看起來是正常的,
但是點進去看郵件內文就變成全部亂碼了,
試了很多編碼組合,看起來用 base64 比較沒有問題,
內文除了 UTL_RAW.CAST_TO_RAW 外還需要轉成 base64編碼 UTL_ENCODE.BASE64_ENCODE
.
sample code

CREATE OR REPLACE PROCEDURE "SEND_MAIL" (
msg_to varchar2 :='',
msg_subject varchar2 :='',
msg_sender varchar2 :='',
msg_text varchar2 := '' )
IS
lv_conn UTL_SMTP.CONNECTION;
lv_server VARCHAR2(255) := 'SERVERIP';
lvmsg_to VARCHAR2(50) := '';
lv_encoded_subject VARCHAR2(255) := '';
BEGIN

lvmsg_to :=replace(msg_to,';','');
--建立連線
lv_Conn := UTL_SMTP.Open_Connection(lv_server, 25);
UTL_SMTP.Helo(lv_conn, lv_server);
UTL_SMTP.Mail(lv_conn, msg_sender);
UTL_SMTP.Rcpt(lv_conn, lvmsg_to);
UTL_SMTP.OPEN_DATA(lv_conn);

-- 主旨
UTL_smtp.write_raw_data(lv_Conn,utl_raw.cast_to_raw(convert('Subject: ' ||msg_subject||utl_tcp.crlf,'zht16big5')));

--設定編碼
UTL_SMTP.WRITE_DATA(lv_conn, 'Content-Type: text/html;charset=Big5' || UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(lv_conn, 'Content-Transfer-Encoding: base64'|| UTL_TCP.CRLF);
--寄送日期
UTL_SMTP.WRITE_DATA(lv_conn,'Date: ' || to_char(sysdate-1/3,'YYYY-MON-DD hh24:mi:ss','NLS_DATE_LANGUAGE=AMERICAN') ||UTL_tcp.CRLF);
--寄件人
UTL_SMTP.WRITE_DATA(lv_conn, 'From: ' || msg_sender || UTL_TCP.CRLF);
--收件人
UTL_SMTP.WRITE_DATA(lv_conn, 'To: ' || lvmsg_to || UTL_TCP.CRLF);

--一定要空一行開始傳送郵件內文
UTL_SMTP.WRITE_DATA(lv_conn, UTL_TCP.CRLF);
--內文編碼後輸出
UTL_SMTP.WRITE_DATA(lv_conn, UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(convert(msg_text,'ZHT16BIG5')))));

--關閉連線
UTL_SMTP.CLOSE_DATA(lv_conn);
UTL_SMTP.QUIT(lv_conn);

EXCEPTION
WHEN UTL_SMTP.INVALID_OPERATION THEN
dbms_output.put_line(' Invalid Operation in SMTP transaction.');
WHEN UTL_SMTP.TRANSIENT_ERROR THEN
dbms_output.put_line(' Temporary problems with sending email - try again later.');
WHEN UTL_SMTP.PERMANENT_ERROR THEN
dbms_output.put_line(' Errors in code for SMTP transaction.');
END;

沒有留言: