邮件转发问题:原始收件人(To)字段丢失
邮件转发问题:原始收件人(To)字段丢失
我完全理解你现在的困扰——用Laravel实现邮件转发后,原始邮件的收件人信息、发件人上下文全没了,看起来就像是从CRM账户新发的一封空白邮件,完全丢失了原邮件的结构对吧?这是因为你当前的实现只是提取了原邮件的正文,然后用Mail::raw()新建了一封邮件,自然不会带上原邮件的任何元数据和结构信息。
先给你指出当前代码里的一个小bug:在处理非multipart邮件的else块里,你用了$part->getContent(),但$part变量只在前面的foreach循环里定义过,非multipart场景下这个变量根本不存在,会直接报错,得改成$message->getContent():
else { $body = nl2br($message->getContent()); }
接下来给你两种解决方案,分别对应不同的转发需求:
方案一:保留原始邮件上下文的正文转发
这种方式会在转发邮件的正文中带上原邮件的发件人、收件人、主题等信息,让收件人能看到完整的转发上下文,同时保留原邮件内容:
public function emailForward(Request $request) { $imap = new Imap([ 'host' => config('app.mail_host'), 'user' => config('app.support_user_id'), 'password' => config('app.support_user_password'), 'port' => config('app.mail_port'), 'ssl' => config('app.mail_ssl'), 'novalidatecert' => config('app.mail_novalidatecert'), ]); // Fetch the email $message = $imap->getMessage(203); // 修复非multipart场景的bug,同时提取正文 $body = ''; if ($message->isMultipart()) { foreach (new RecursiveIteratorIterator($message) as $part) { if (stripos($part->contentType, 'text/plain') !== false) { $body = $part->getContent(); break; } elseif (stripos($part->contentType, 'text/html') !== false) { $body = nl2br($part->getContent()); } } } else { $body = nl2br($message->getContent()); } // 获取原邮件的元数据 $originalFrom = $message->getFrom(); $originalTo = $message->getTo(); $originalSubject = $message->getSubject(); // 构建转发邮件的标题和正文 $forwardSubject = 'Fwd: ' . $originalSubject; // 把原邮件的发件人、收件人信息加到正文开头,模拟标准转发格式 $forwardHeader = "--- 转发邮件 --- 发件人: {$originalFrom['address']} (" . ($originalFrom['name'] ?? '') . ") 收件人: " . implode(', ', array_map(function($to) { return "{$to['address']} (" . ($to['name'] ?? '') . ")"; }, $originalTo)) . " 主题: {$originalSubject} ----------------- "; $forwardBody = $forwardHeader . $body; // 转发邮件,同时设置Reply-To为原发件人,方便收件人回复 Mail::send([], [], function ($mail) use ($forwardSubject, $forwardBody, $originalFrom) { $mail->from('demo@zyz.com', 'Amazon') ->to('demo-1@abc.com', 'Jhon') ->subject($forwardSubject) ->setBody($forwardBody, 'text/html') ->replyTo($originalFrom['address'], $originalFrom['name'] ?? $originalFrom['address']); }); return response()->json(['message' => 'Email forwarded successfully!']); }
方案二:完全保留原邮件结构(作为附件转发)
如果需要让收件人看到100%完整的原邮件(包括所有邮件头、附件、格式),最稳妥的方式是把原邮件作为.eml附件发送,这样收件人可以直接打开附件查看完整的原始邮件:
public function emailForward(Request $request) { $imap = new Imap([ 'host' => config('app.mail_host'), 'user' => config('app.support_user_id'), 'password' => config('app.support_user_password'), 'port' => config('app.mail_port'), 'ssl' => config('app.mail_ssl'), 'novalidatecert' => config('app.mail_novalidatecert'), ]); // 获取原始邮件的完整MIME内容(如果你的Imap类没有getRawMessage方法,可能需要自己实现或找替代方法) $originalEmailRaw = $imap->getRawMessage(203); $message = $imap->getMessage(203); $originalSubject = $message->getSubject(); $forwardSubject = 'Fwd: ' . $originalSubject; // 用Swift_Message构建带附件的转发邮件 $swiftMessage = new \Swift_Message($forwardSubject); $swiftMessage->setFrom(['demo@zyz.com' => 'Amazon']) ->setTo(['demo-1@abc.com' => 'Jhon']) ->setBody('请查看附件中的原始邮件内容,完整保留了原邮件的所有信息'); // 添加原始邮件为.eml附件 $attachment = new \Swift_Attachment($originalEmailRaw, 'original-email.eml', 'message/rfc822'); $swiftMessage->attach($attachment); // 发送邮件 \Mail::send($swiftMessage); return response()->json(['message' => 'Email forwarded successfully!']); }
这两种方案里,方案一更符合日常邮件转发的体验,方案二则能100%保留原邮件的所有细节,你可以根据业务需求选择。
备注:内容来源于stack exchange,提问作者Husain
相关产品推荐
相关产品推荐

