1754989919
2025-08-11 18:22:00
添付ファイルをOptimizelyフォームのメールに追加することに関するほとんどの記事は、2019年頃からのもので、最新のバージョンについては説明していません。この投稿では、2025年の実装と学んだ教訓をご覧ください。あなたの走行距離は異なる場合があります。
問題
Optimizely Formsの組み込み sendemailaftersubmissivesactor フォームが送信された後、クリーンで簡単なメールを送信します。使用するとき ファイルフォーム要素ブロックをアップロードします、アクターには、ファイルがCMSに保存されている場所への電子メールにリンクを含めます。
CMSアクセスを持つ内部ユーザーにとっては問題ありません。しかし、あなたの受信者がそうであるなら 外部の – 顧客、パートナー、ベンダー – これらのリンクはそれらには機能しません。
私が必要としていたのは:
サブクラス化が機能しない理由
Optimizely’s sendemailaftersubmissivesactor 限られたサブクラスのみを許可します。
重要な操作の多くはです プライベート、 ない 保護されています、 そして mimemessage カスタマイズのために引き戻されることはありません。
つまり、単に「フックに入って」添付ファイルを追加する方法はありません。それが私が選択した理由です。
-
元の俳優を逆コンパイルします。
-
論理卸売をコピーします。
-
必要に応じて変更を挿入します。
アプローチ
元の俳優:
修正された俳優:
-
ビルドa MultiPart( “Mixed”) メッセージ。
-
元の本体をaとして追加します TextPart。
-
新しいヘルパーメソッドを呼び出します addfileattachments(multipart)、アップロードされたファイルを追加します。
-
CMS Blobからアップロードされたファイルを解決し、コンテンツタイプを決定し、発信電子メールに添付します。
添付ファイルのサポート
添付ファイルの処理には以下が含まれます。
-
フォームの送信からファイルアップロードフィールドの検出(FriendlyNameInfo およびフィールドネーミングパターンのような ファイル、 アップロード、 添付ファイル)。
-
介してBLOB参照を解決します iblobfactory そして iurlresolver。
-
ファイル拡張機能に基づいてコンテンツタイプを決定します。
-
添付ファイルを埋め込みます ミメパート base64エンコーディングのインスタンス。
依存関係の追加
この作業を行うために、私は追加しました:
-
IformRepository – フォームフィールドメタデータを取得します。
-
iblobfactory & iurlresolver – アップロードされたファイルのバイナリデータを取得します。
-
a sechinecontenttype ヘルパー – 添付ファイルには正しいMIMEタイプがあることを確認します。
身体の建設が変化します
オリジナル
使用済み:
message.Body = new TextPart(subtype) { Text = this.RewriteUrls(content) };
修正
aで体を包みます MultiPart( “Mixed”) したがって、ボディとアタッチメントの両方を含めることができます。
重要な新しい方法
添付処理
protected virtual void AddFileAttachments(Multipart multipart)
{
var friendlyNameInfos = _formRepository.Service.GetFriendlyNameInfos(this.FormIdentity);
foreach (var submissionDataItem in this.SubmissionData.Data)
{
var friendlyNameInfo = friendlyNameInfos
.FirstOrDefault(f => string.Equals(f.ElementId, submissionDataItem.Key, StringComparison.OrdinalIgnoreCase));
if (friendlyNameInfo != null && IsFileUploadField(friendlyNameInfo, submissionDataItem.Value))
{
var fileUploads = submissionDataItem.Value.ToString().Split("|");
foreach (var fileUpload in fileUploads)
{
AttachFileFromBlob(multipart, fileUpload, friendlyNameInfo.FriendlyName);
}
}
}
}
注記: フォームが複数のアップロードを許可する場合、それらは分離された単一の文字列として通過します |。
ファイル添付ファイルヘルパー
protected virtual void AttachFileFromBlob(Multipart multipart, string blobIdentifier, string friendlyName)
{
Blob blob = null;
IContent contentData = _urlResolver.Service.Route(new UrlBuilder(blobIdentifier));
if (contentData is MediaData media)
{
blob = _blobFactory.Service.GetBlob(media.BinaryData.ID);
}
if (blob != null)
{
var memoryStream = new MemoryStream();
blob.OpenRead().CopyTo(memoryStream);
memoryStream.Position = 0;
var fileName = blobIdentifier.Split(new[] { "#@" }, StringSplitOptions.None).Last();
var contentType = DetermineContentType(blob, fileName);
multipart.Add(new MimePart(contentType)
{
Content = new MimeContent(memoryStream, ContentEncoding.Default),
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
ContentTransferEncoding = ContentEncoding.Base64,
FileName = fileName
});
}
}
元のファイル名は識別子に追加されます #@ – これは、電子メールの添付ファイル用に抽出します。
コンテンツタイプのヘルパーを決定します
protected virtual string DetermineContentType(Blob blob, string fileName)
{
// Try to get content type from blob
// This might be available in blob metadata depending on your implementation
// Fall back to determining from file extension
string extension = Path.GetExtension(fileName)?.ToLowerInvariant();
return extension switch
{
".pdf" => "application/pdf",
".doc" => "application/msword",
".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".xls" => "application/vnd.ms-excel",
".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
".jpg" or ".jpeg" => "image/jpeg",
".png" => "image/png",
".gif" => "image/gif",
".txt" => "text/plain",
".csv" => "text/csv",
".zip" => "application/zip",
".xml" => "application/xml",
".json" => "application/json",
_ => "application/octet-stream"
};
}
sendmessage()変更
オリジナル:
MimeMessage message = new MimeMessage();
message.Subject = str1;
string subtype = this._sendMessageInHTMLFormat ? "html" : "plain";
message.Body = (MimeEntity) new TextPart(subtype, new object[1]
{
(object) this.RewriteUrls(content)
});
修正:
MimeMessage message = new MimeMessage();
message.Subject = str1;
// Create multipart message to support attachments
var multipart = new Multipart("mixed");
string subtype = this._sendMessageInHTMLFormat ? "html" : "plain";
multipart.Add(new TextPart(subtype, new object[1]
{
(object) this.RewriteUrls(content)
}));
// Add file attachments
this.AddFileAttachments(multipart);
message.Body = multipart;
配線します
すぐにボックスの俳優を置き換えるには、依存関係の噴射セットアップでそれを行う必要があるでしょう。
私の場合、私はそれをグローバルに置き換えませんでした – 私たちはすでに異なるHTMLテンプレートを適用するためにサブクラス化されたアクターを持っていたので、私はそのサブクラスをから継承しました 新しい代替品 オリジナルの代わりに。
持ち帰り
-
オリジナル俳優: シンプルで信頼性の高い、ゼロの添付ファイルのサポート。
-
修正俳優: 同じ基礎に加えて、マルチパートマイムとアタッチメント処理。
パブリックAPIが提供するものを超えて、組み込みのアクターを最適な形で拡張する必要がある場合は、コードレベルで作業する必要がある場合があります。
注意: Formsパッケージの更新後、sendemailaftersubmissionactorが変更されたかどうかを確認します。バージョンを再度並べるか、新しいコア機能を活用する必要がある場合があります。
何か考えや意見がありますか?コメントで教えてください!
2025年8月11日
#2025年にオプティゼリーフォームの添付ファイルを使用して電子メールを送信します