2019年10月27日日曜日

FileMaker 18 標準機能でHTMLメール,複数添付ファイルを送信|Send HTML Email with cURL

FileMaker 18 標準機能でHTMLメール,複数添付ファイルを送信
送信先、送信元の表示名設定可能

動作検証
Windows 10
FileMaker 16, 17, 18
(FMP16,17は、外部 cURL を使用)
Windows 10 Ver.1803(RS4)以降は、cURL標準搭載

iOS 13.1.3
FileMaker Go 18

Mac OS 10.13.6
FileMaker 16, 17, 18
(FMP16,17は、外部 cURL を使用)

完成品をダウンロード(\500)
https://fm-aid.stores.jp/items/5db51c8cbc45ac23540f9787
Q&A 不明な点は以下で問い合わせ下さい。
https://fm-aid.com/community/viewforum.php?id=6

          使用方法          




SMTP設定:
 SMTP_Server:SMTPサーバー
 SMTP_Port:25,587,465
 SMTP_SSL:SSL ON=1, OFF=0
 SMTP_account:SMTPアカウント
 SMTP_password:SMTPパスワード
 From_Name:送信元アドレス表示名
 From_address:送信元メールアドレス
BodyTEXT
 メール内容 プレーンテキスト
BodyHTML
 [GetAsCSS]ボタンでBodyTEXTをCSS化、または、任意のHTMLを設定
Attachd File
 添付ファイルを設定
cURL Path
 Windows 10 Ver.1803(RS4)より前の場合、cURLをインストールし、
 curl.exe のフルパスを設定。例:C:\curl\curl.exe

[送信]ボタンでメールが送信されます。

FileMaker 16, 17 の場合、メールメッセージファイルを作成し、外部cURLで送信されます。

          作成方法          

テーブル:

フィールド:





リレーション:

Logs:

Mail_AttachedFile:

レイアウト:

ボタン設定:
 [送信]ボタンに スクリプト:SendMail を設定
 [GetAsCSS]ボタンに フィールド設定 [Mail::BodyHTML; GetAsCSS ( Mail::BodyTEXT )] を設定

     スクリプト     

スクリプト:SendMail
2019/10/28 テキストを挿入 部分のテキストが抜けていたので記述
変数を設定 [ $$Result; 値:"" ]
変数を設定 [ $$dump_header; 値:"" ]
スクリプト実行 [ 「_AttachedFile」 ]
変数を設定 [ $AttachedFile; 値:Get(スクリプトの結果) ]
テキストを挿入 [ 選択; ターゲット:$RawMail ;「Subject: =?utf-8?B?{Subject}?=
To: "=?utf-8?B?{To_Name}?=" <{To_Address}>
From: "=?utf-8?B?{From_Name}?=" <{From_Address}>
Content-Type: multipart/mixed; boundary={boundary}

--{boundary}
Content-Type: multipart/alternative;boundary=1_{boundary}

--1_{boundary}
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64

{BodyTEXT}
--1_{boundary}
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64

{BodyHTML}
{AttachedFile}
--1_{boundary}--
--{boundary}--」 ]
変数を設定 [ $DATA; 値:Substitute ( $RawMail ; [¶ ; Char(13) & Char(10) ] ; ["{boundary}" ; Mail::_k ] ; ["{Subject}" ; Base64EncodeRFC ( 4648 ; Mail::Subject )] ; ["{To_Name}" ; Base64EncodeRFC ( 4648 ; If ( IsEmpty ( Mail::To_Name ) ; Mail::To_Address; Mail::To_Name ) )] ; ["{To_Address}" ; Mail::To_Address ] ; ["{From_Name}" ; Base64EncodeRFC ( 4648 ; If ( IsEmpty ( mail_account::disp_mail_address ) ; mail_account::mail_address; mail_account::disp_mail_address ) )] ; ["{From_Address}" ; mail_account::mail_address ] ; ["{BodyTEXT}" ; Base64EncodeRFC ( 2045 ; Mail::BodyTEXT )] ; ["{BodyHTML}" ; Base64EncodeRFC ( 2045 ; If ( IsEmpty ( Mail::BodyHTML ) ; Mail::BodyTEXT; Mail::BodyHTML ) )] ; ["{AttachedFile}" ; $AttachedFile] ) ]
#アプリケーションバージョン チェック $App,$Ver
変数を設定 [ $er; 値:Let([ $App_Ver=Get (アプリケーションバージョン) ;$App_Ver_List=Substitute ( $App_Ver ; [" " ; ¶]; ["." ; ¶] ) ;$App=GetValue ( $App_ver_List ; 1 ) ;$Ver=GetValue ( $App_ver_List ; 2 ) ]; 0 ) ]
変数を設定 [ $cURL_URi; 値:Let([ ¢SMTP="{protocol}://{SMTP_Server}:{SMTP_Port}" ]; Substitute ( ¢SMTP ; [ "{protocol}" ; If ( mail_account::SMTP_SSL ; "smtps" ; "smtp" ) ] ; [ "{SMTP_Server}" ; mail_account::SMTP_Server ] ; [ "{SMTP_Port}" ; mail_account::SMTP_Port ] ) ) ]
変数を設定 [ $cURL_Options; 値:Let([ ¢Options=" --globoff --user {SMTP_account}:{SMTP_password} --mail-from {mail-from} --mail-rcpt {mail-rcpt} --upload-file $DATA {ssl} --show-error --dump-header $$dump_header " ]; Substitute ( ¢Options ; [ "{SMTP_account}" ; mail_account::SMTP_account ] ; [ "{SMTP_password}" ; mail_account::SMTP_password ] ; [ "{mail-from}" ; mail_account::mail_address ] ; [ "{mail-rcpt}" ; Mail::To_Address ] ; [ "{ssl}" ; If ( mail_account::SMTP_SSL ; "--ssl-reqd" ; "" ) ] ) ) /*--trace-ascii $$trace_ascii*/ ]
If [ GetAsNumber ( $Ver ) ≥ 18 ]
URL から挿入 [ $$Result; $cURL_URi; cURL オプション: $cURL_Options ] [ URL を自動的にエンコードしない; 選択; ダイアログなし ]
変数を設定 [ $LastError; 値:Get ( 最終エラー ) ]
Else
変数を設定 [ $bool; 値:ValueCount ( FilterValues ( $App ; "ProAdvanced¶Pro" )) ]
If [ $bool = 0 ]
カスタムダイアログを表示 [ タイトル: "!"; メッセージ: "この機能は、「ProAdvanced」または、「Pro」で利用可能です。"; デフォルトボタン: 「OK」, 確定: 「はい」 ]
現在のスクリプト終了 [ ]
End If
変数を設定 [ $System_platform; 値:Get (システムプラットフォーム) ]
#メールをファイル保存|戻り値:ファイルパス
スクリプト実行 [ 「ExportMailDataWithcURL(DATA)」; 引数: $DATA ]
変数を設定 [ $DataPath; 値:Get ( スクリプトの結果 ) ]
変数を設定 [ $Command; 値:$cURL_URi & " " & $cURL_Options ]
If [ $System_platform = -2 /*Windows*/ ]
変数を設定 [ $DataPathFor_cURL_Op; 値:Substitute ( $DataPath ; "file:///" ; "" ) ]
変数を設定 [ $DirPath; 値:Get ( テンポラリパス ) ]
変数を設定 [ $DirPathFor_cURL_Op; 値:Replace ( $DirPath ; 1 ; 1 ; "" ) ]
変数を設定 [ $dump_header_path; 値:$DirPathFor_cURL_Op & "dump_header_" & Mail::_k & ".txt" ]
変数を設定 [ $Command; 値:Substitute ( $Command ; [ "$DATA" ; Quote ( $DataPathFor_cURL_Op ) ] ; [ "$$dump_header" ; Quote ( $dump_header_path)] ) ]
スクリプト実行 [ 「Get_ProperPath(arg)」; 引数: "file:///" & $dump_header_path ]
変数を設定 [ $dump_header_pathFor_cURL; 値:Get ( スクリプトの結果 ) ]
URL から挿入 [ $$er; $dump_header_pathFor_cURL; cURL オプション: Let($DATA=0; " -T $DATA --trace-ascii $$trace " ) ] [ URL を自動的にエンコードしない; 選択; ダイアログなし ]
変数を設定 [ $cURL_Command; 値:If ( IsEmpty ( Setting_cURL::Path ) ; "curl" ; Setting_cURL::Path ) & Char ( 32 ) & $Command ]
Event を送信 [ ファイル/アプリケーションを開く; $cURL_Command ]
変数を設定 [ $LastError; 値:Get ( 最終エラー ) ]
Loop
スクリプト一時停止/続行 [ 間隔(秒): 1 ]
Exit Loop If [ $n>30 ]
URL から挿入 [ $$dump_header; $dump_header_pathFor_cURL ] [ URL を自動的にエンコードしない; 選択; ダイアログなし ]
Exit Loop If [ not IsEmpty ( $$dump_header ) and $$dump_header ≠ 0 ]
変数を設定 [ $n; 値:$n+1 ]
End Loop
変数を設定 [ $$dump_header; 値:Substitute ( $$dump_header ; Char(10) ; "" ) ]
Else If [ $System_platform = 1 /*Mac*/ ]
変数を設定 [ $DataPathFor_cURL_Op; 値:Substitute ( $DataPath ; "file://" ; "" ) ]
変数を設定 [ $Command; 値:Substitute ( $Command ; [ "$DATA" ; Quote ( $DataPathFor_cURL_Op ) ] ; [ "$$dump_header" ; "-"] ) ]
変数を設定 [ $AS; 値:Let([ AS= " set Result to do shell script {Command}¶ set cell \"Logs::dump_header\" of current record to Result " ]; Substitute ( AS ; "{Command}" ; Quote ( "curl " & $Command ) ) ) ]
AppleScript を実行 [ 計算済みの AppleScript: $AS ]
変数を設定 [ $LastError; 値:Get ( 最終エラー ) ]
変数を設定 [ $$dump_header; 値:Logs::dump_header ]
End If
End If
フィールド設定 [ Logs::LastError; $LastError ]
フィールド設定 [ Logs::dump_header; $$dump_header ]
フィールド設定 [ Logs::Result; $$Result ]
フィールドへ移動 [ ]

スクリプト:_AttachedFile
2019/10/28 テキストを挿入 部分のテキストが抜けていたので記述
テキストを挿入 [ 選択; ターゲット:$header ;「--2_{boundary}
Content-Type: application/octet-stream;name="=?utf-8?B?{FileName}?=" 
Content-Transfer-Encoding: base64
Content-Disposition: attachment;filename="=?utf-8?B?{FileName}?=" 」]
変数を設定 [ $MAX; 値:Count ( Mail_AttachedFile::_k ) ]
変数を設定 [ $n; 値:1 ]
変数を設定 [ $CRLF; 値:Char(13) & Char(10) ]
Loop
Exit Loop If [ $n>$MAX ]
変数を設定 [ $File; 値:GetNthRecord ( Mail_AttachedFile::objFile ; $n ) ]
If [ not IsEmpty ( $File ) ]
変数を設定 [ $AttachedFile; 値:$AttachedFile & If (IsEmpty ( $AttachedFile ) ; ""; $CRLF ) & Substitute ( $header ; [¶ ; $CRLF ] ; ["{boundary}" ; Mail::_k ] ; ["{FileName}" ; Base64EncodeRFC ( 4648 ; GetContainerAttribute ($File; "filename") )] ) & $CRLF & $CRLF & Base64EncodeRFC ( 2045 ; $File ) ]
End If
変数を設定 [ $n; 値:$n+1 ]
End Loop
変数を設定 [ $DATA; 値:If ( not IsEmpty ( $AttachedFile ) ; "--1_" & Mail::_k & $CRLF & "Content-Type: multipart/mixed;boundary=2_" & Mail::_k & $CRLF & $CRLF & $AttachedFile & $CRLF & $CRLF & "--2_" & Mail::_k & "--" ) ]
現在のスクリプト終了 [ 結果: $DATA ]

スクリプト: ExportMailDataWithcURL(DATA)
変数を設定 [ $DATA; 値:Get(スクリプト引数) ]
変数を設定 [ $FileName; 値:Mail::_k & ".eml" ]
変数を設定 [ $DirPath; 値:Get ( テンポラリパス ) ]
// 変数を設定 [ $DirPath; 値:Get ( ドキュメントパス ) ]
変数を設定 [ $FilePath; 値:"file:///" & Substitute ( $DirPath ; "\\" ; "/" ) & If ( Right ( $DirPath ; 1 ) ≠ "/" ; "/" ) & $FileName ]
変数を設定 [ $FilePath; 値:Substitute ( $FilePath ; ["file:////" ; "file:///"] ) ]
If [ Get (システムプラットフォーム) = -2 /*Windows*/ ]
#Windowsの場合は、SHIFT-JIS URLエンコード
変数を設定 [ $Path; 値:Let( [ $Val = $FilePath ; $MAX = Length ( $Val ) ; $n = 1 ; $fnc0= "Case ( $n > $MAX ; $Result ; Let( [ $text=Middle ( $Val ; $n ; 1 ); $Result = $Result & if(Code ( $text )>127; Let( [ $txt = HexEncode ( TextEncode ( $text ; \"shift_jis\" ; 1 ) ) ; $pos = Length ( $txt ) - 1 ; $fnc= \"Case ( $pos < 0 ; $txt ; Let( [ $txt = Replace ( $txt ; $pos ; 0 ; \\\"%\\\" ) ; $pos = $pos - 2 ]; Evaluate($fnc)) )\" ]; Evaluate($fnc) ) ; Middle ( $Val ; $n ; 1 ) ); $n = $n + 1 ]; Evaluate($fnc0)) )" ]; Evaluate($fnc0) ) ]
Else
#/var/から始まるパスでないとエラーになる
変数を設定 [ $FilePath; 値:"file:///" & "/var/" & GetValue ( Substitute ( $DirPath ; "/var/" ; ¶ ) ; 2 ) & If ( Right ( $DirPath ; 1 ) ≠ "/" ; "/" ) & $FileName ]
変数を設定 [ $FilePath; 値:Substitute ( $FilePath ; ["file:////" ; "file:///"] ) ]
変数を設定 [ $Path; 値:$FilePath ]
End If
エラー処理 [ オン ]
URL から挿入 [ $Result; $Path; cURL オプション: " -T $DATA --trace-ascii $trace " ] [ URL を自動的にエンコードしない; 選択; ダイアログなし ]
エラー処理 [ オフ ]
フィールドへ移動 [ ]
現在のスクリプト終了 [ 結果: $Path ]

スクリプト: Get_ProperPath(arg)
#Windows、全角やスペースw含むパスの対応
変数を設定 [ $FilePath; 値:Get(スクリプト引数) ]
変数を設定 [ $FilePath; 値:Substitute ( $FilePath ; ["file:////" ; "file:///"] ) ]
If [ Get (システムプラットフォーム) = -2 /*Windows*/ ]
#Windowsの場合は、SHIFT-JIS URLエンコード
変数を設定 [ $Path; 値:Let( [ $Val = $FilePath ; $MAX = Length ( $Val ) ; $n = 1 ; $fnc0= "Case ( $n > $MAX ; $Result ; Let( [ $text=Middle ( $Val ; $n ; 1 ); $Result = $Result & if(Code ( $text )>127; Let( [ $txt = HexEncode ( TextEncode ( $text ; \"shift_jis\" ; 1 ) ) ; $pos = Length ( $txt ) - 1 ; $fnc= \"Case ( $pos < 0 ; $txt ; Let( [ $txt = Replace ( $txt ; $pos ; 0 ; \\\"%\\\" ) ; $pos = $pos - 2 ]; Evaluate($fnc)) )\" ]; Evaluate($fnc) ) ; Middle ( $Val ; $n ; 1 ) ); $n = $n + 1 ]; Evaluate($fnc0)) )" ]; Evaluate($fnc0) ) ]
Else
変数を設定 [ $Path; 値:$FilePath ]
End If
現在のスクリプト終了 [ 結果: $Path ]
完成品をダウンロード(\500)
https://fm-aid.stores.jp/items/5db51c8cbc45ac23540f9787
Q&A 不明な点は以下で問い合わせ下さい。
https://fm-aid.com/community/viewforum.php?id=6

2 件のコメント:

  1. 興味があり、導入したいと考えています。
    現在ファイルメーカー18 Mac 10.13でSMTP経由で定期的にメール送信をしています。
    設定条件はPORT25、接続の暗号化はなし(認証なし)で送信しています。
    このような設定そのまま配信できるものなのでしょうか?
    もしサンプルのようなものがあれば見て見たいと思います。

    返信削除
  2. 完成品は、以下にあります。(500円)
    https://fm-aid.stores.jp/items/5db51c8cbc45ac23540f9787

    添付ファイル無しのファイルの解説はいかにあります。
    https://qbxxdp.blogspot.com/2019/09/filemaker-18-send-html-mail-with-curl.html
    添付ファイル無しのサンプルファイルは、無料です。
    https://sites.google.com/site/scriptmakerps/other-than-plug-ins/send-html-email-with-curl

    返信削除