2016-09-17 37 views
1

我正在用ruby製作自己的電子郵件客戶端,它目前可以解析/讀入消息。它還可以創建對消息的回覆,設置標題並將消息發送給原始發件人。格式電子郵件回覆在Ruby中

如何將原始引用的消息添加到回覆中?

我應該如何去回覆格式化原始郵件?是否有最佳做法或格式? MIME/RFC?我知道應該有一個HTML和文本的字符串。只是不確定如何製作這些字符串。

現在我的回覆沒有下面的原始信息,並且很難理解。

回答

1

撰寫電子郵件回覆是一項相當大的挑戰,特別是在您不知從何入手的最初階段。

最近我不得不編寫這樣的電子郵件,並以編程方式發送它們。我首先做的是看看電子郵件客戶端如何做到這一點,比如Thunderbird。它需要一些實驗和耐心。

我用郵件的整體結構很大程度上基於此堆棧溢出的答案:https://stackoverflow.com/a/23853079/1368043


1. HTML部分

注意,你有幾個選擇:要麼撰寫HTML片段(典型的<body>標籤的內容)或整個HTML文檔(使用<html>,<head><body>標籤)。我看了一下Thunderbird是如何做到的。原來它創建整個文檔,這大概是產生這樣的:

  1. 創建HTML文檔
  2. 添加元信息<meta content="text/html; charset=utf-8" http-equiv="Content-Type"><head>部分
  3. (你喜歡一個替換的字符集)在<body>部分添加您組成的HTML片段,添加引號的標題(如:「<div>Few days ago, John Smith wrote: </div>」),並在其後面添加<blockquote>塊:<blockquote cite="mid:[email protected]" type="cite">。請注意,原始消息有一個消息ID。

而這裏的,我真的不喜歡有關雷鳥部分:

  • 複製原始郵件的HTML內容,並將其粘貼到<blockquote>塊。
  • Thunderbird並不真正檢查複製的HTML是片段還是文檔。但是,如果它是一個文檔,它會剝離<html><head>標籤...而保留其內容。因此,您可以看到位於新消息的<body>標記中的原始消息的<head>部分中的<style><title>標記。這很混亂。

    此外,雷鳥不應付全球造型。您可以使用全局樣式而非內嵌樣式輕鬆編寫棘手的郵件,並且當郵件的收件人開始編寫回復時,樣式會溢出整個郵件。


    你可以做同樣的事情。它並沒有真正傷害任何人,他們通常不會對典型的郵件觀察到怪癖。加上它很容易。或者你可以進一步去清理這個爛攤子。

    首先,你必須讓自己任何HTML解析器。我使用Nokogiri,我用它的方式是這樣的:

    1. 它會自動轉換爲HTML文檔的任何片段,所以沒有必要來分析碎片和文件分別
    2. 找到<body>標籤的文檔中,並複製其內容
    3. 刪除任何<style>標籤找到
    4. 複製需要的地方,結果

    這將大致是這樣的:

    doc = Nokogiri::HTML.parse(strHTML) 
    body = doc.css('body')[0] 
    body.css('style').each { |node| 
        node.unlink 
    } 
    
    puts body.inner_html 
    

    引入nokogiri也有一個好處 - 如果你有在HTML消息中的任何內嵌圖像,你可以很容易地找到他們,用「CID更換網址:.. 。「方案並將圖像添加爲內聯附件。


    2.純文本部分

    對了,還有還有在multipart/alternative部分郵件的純文本版本。這裏最重要的過程是能夠將任何HTML文本轉換爲純文本版本。這比編寫HTML部分更復雜。畢竟,你必須寫一個簡單的渲染引擎(就像任何其他的Web瀏覽器一樣)。可能有寶石就是這樣,不幸的是我當時找不到任何寶石。爲了讓您雖然起步

    幾個要點:

    • 所有換行符(\ r \ n或\ n)的應用一個空格
    • 所有多個空格應減少到一個只更換之後他們(除非他們不換行)
    • 某些標記保護的內容,但其他人不(像<style><script>標籤VS <b><div>
    • 某些標籤需要一個換行符(S)(<br>和塊標記,如<p><div>是示例)
    • 您必須正確格式化表格。你必須計算列的寬度,考慮colspan S和rowspan S,墊單元格的內容用空格進行對齊等
    • 你必須找到<b><i>替代標記。 ..標籤(如用星號或諸如此類的東西他們周圍)
    • 您也可以格式化標題:加破折號線或星號低於和/或高於他們
    • 你必須<h1><h2> ...標籤正確格式化<a>標籤,即它們轉換成格式:Stack Overflow site [http://stackoverflow.com]
    • 你不得不放棄<img>標籤,也許用替代文本替換它們,如果存在
    • 你也不得不解碼HTML實體(&gt;等)。如果不引入nokogiri,該ヶ輛寶石可能在這種情況下

    幫助該列表可以繼續下去。當然這是不必要的

    在互聯網上有一些庫和項目可以做到這一點,但是它們不是爲Ruby編寫的和/或他們缺少上面列出的某些功能。例子是:


    一旦你有自己的方式,在text/plain部分的結構幾乎是相同的作爲HTML部分。在一開始就有你的回答。然後,引用標題,然後是引用的消息。它通常被格式化,以便每行都以'>'字符開頭。現在,有一個問題,你應該粘貼在那裏。

    第一個選項是將原始郵件的HTML部分(通過上述方法)轉換並粘貼爲帶引號的郵件。其次是使用原始消息的text/plain部分(如果存在)並粘貼它,而不進行任何轉換。後一種選擇的好處是,長時間對話中的'>'字符會以樹狀方式累積。此外,它還保留了發件人可能手動組裝的純文本格式,以便更準確。


    3.總結

    根據您的實際需要和想要達到的質量水平,撰寫這些郵件的難度範圍可以從易/棘手的努力,特別是如果你必須自己編寫所有代碼。如果您碰巧發現任何Ruby寶石可以幫助您完成這些任務中的至少一部分,請不要猶豫並使用它們。

    構建HTML部分可以像複製和粘貼HTML片段一樣簡單,最好是事先剝去一些標籤。組成純文本部分可以很簡單,只需刪除幾個標籤(<head>,<script>,<style>,...),按照該順序剝離所有標籤,同時保留其內容並解碼所有HTML實體。

    刪除HTML標籤可以用正則表達式來完成,但它是strongly discouraged,被認爲是一個窮人工具箱中的工具。所以我建議使用Nokogiri或類似的東西。

    儘管這不是問題的一部分,但我必須強調編寫電子郵件客戶端的一個方面。你應該總是記得消毒你的HTML郵件,尤其是你收到的。在收到的郵件中可疑地尋找iframe或腳本時沒有什麼好處,如果這些郵件沒有被垃圾郵件過濾器立即阻止/過濾,可能是XSS攻擊的一部分。在這種情況下,Sanitize寶石可能會證明是有用的。

    乾杯