目錄
    Add a header to begin generating the table of contents

    Python 可以發送電郵?教您用 Mailjet 免費使用 Email API

    Python 可以發送電郵?教您用 Mailjet 免費使用 Email API
    Share on facebook
    Share on twitter
    Share on linkedin
    Share on whatsapp
    目錄
      Add a header to begin generating the table of contents

      除了把 Python 整合出來的數據結果以表格、互動圖表等的方法展示出來以外,您亦可以在運算完畢時把結果以電郵方式寄送到自己的郵箱!

      假如您有一些每天都需要製做的報告,那麼除了人手在 Outlook 裡複製貼上以外,您還可以每天運行同一個 Python 的編程(script),自動把電郵發送到有關人士手上!

      以下我們來學學如何使用 Mailjet 的免費限額從 Python 發電郵吧。

      簡單的製成品

      完成這篇教學後,我們會製成以上的電郵,而這封電郵是直接從 Python 發出到我們的郵箱!

      當然,這只是一個初階的例子,我們在下一篇會介紹如何製成更加精美的電郵。在此之前,我們先來學習基本功吧!

      我是廣告 ^o^

      申請資格

      基本上如果您有一個電郵地址,便可以開始使用 Mailjet Email API!

      哪怕您的電郵地址是 @gmail.com,也可以透過簡單的電郵認證直接開始使用這個服務。

      當然,如果您有一個自訂的網域(Domain),那麼最好當然是使用自己的網域(例如 @mydomain.com),便可以享受完整的電郵服務。如果您的電郵地址是大眾服務(例如 Gmail、Hotmail 等),由 Python 發出電郵很大機會會墮進垃圾郵件(Spam)喔!

      第一步:註冊 Mailjet 帳戶

      首先我們到 Mailjet 網站註冊新的帳戶:https://www.mailjet.com/

      我是廣告 ^o^

      在主頁按一下 “Get Started”。

      填寫您希望使用的電郵地址、帳戶密碼,並完成 reCAPTCHA。

      填寫有關您的資料,例如公司/機構名稱等。

      因為我們只需要使用免費試用版,便不用填寫信用卡資料,可以直接按 “Complete Order”。

      Mailjet 應該會向您的電郵地址發送一封認證電郵。按一下電郵的認證連結。

      我是廣告 ^o^

      在瀏覽器新一頁會顯示 Welcome,在這頁選擇 “Developer”。

      選擇以 API 的形式發送電郵,並按一下 “Continue”。

      在 Coding Language 一欄選擇 “Python”。

      在下方會見到 “Install the package” 和 “Send your first email” 的指示。

      我們在下一步會介紹如何到 VS Code/您的編程器使用這段編程。

      我是廣告 ^o^

      第二步:到 VS Code 以 API 發送第一封電郵

      架設 Virtualenv 及安裝 mailjet_rest

      首先我們開啟一個新的文件夾,並架設一個新的 virtual environment。

      在這個 virtual environment(下圖為 .venv),我們在 Terminal 運行以下指令:

      pip install mailjet_rest

      開啟新的 .py 文件並加入 Python 編程

      接下來我們把第一步獲得的程式碼貼上一個新的文件,並取名為 mailjet.py。

      這裡略略介紹一下這段編程的元素。api_keyapi_secret 就是您 mailjet 帳戶的用戶名稱和密碼,這段編程透過一個網路的 POST request(就好像到瀏覽器開啟一個網頁一樣),以 api_keyapi_secret 「登入」mailjet 並指令 mailjet 系統發出郵件。因此記得把 api_keyapi_secret 保管妥當喔!

      除此之外,這個 POST request 的數據是 data 這個函數,而它是一個字典(Dictionary),可以讓您指定發件人(From)、收件人(To)、主題(Subject)、郵件內容(TextPart 和 HTMLPart)等。

      我是廣告 ^o^

      如果您使用 Python 3.X,記得將原本的編程最後兩句的 print 改為以下 Python 3.X 的語法:

      print(result.status_code)
      print(result.json())

      注意!不要把 .py 檔案命名為 email.py

      這是一個我找了很久才發現解決方法的一個小問題。如果您想使用 Mailjet 的 Python Library (即是 mailjet_rest),千萬不要把您的 .py 檔案命名為 email.py,否則您的 Python 程序會跳出以下的錯誤:

      ImportError: cannot import name 'Client' from 'mailjet_rest' 

      這裡附上找到這個答案的大大:https://github.com/mailjet/mailjet-apiv3-python/issues/33

      運行 mailjet.py 去發送 API 認證電郵

      儲存了 mailjet.py 以後,我們到 Terminal 輸入以下代碼運行:

      python mailjet.py

      我們可以見到在指令運行後有 2 個輸出。

      我是廣告 ^o^
      • 「200」是 result.status_code 的輸出,代表成功發出這個 POST 的網路請求(request)。如果見到這個輸出不是 200,就代表指令未能完成
      • {‘Messages’: []} 代表 mailjet 回送的結果,可以見到 Status 是 ‘success’ 和這個電郵的發送人/收件人。如果 result.status_code 不是 200 的話,{‘Messages’: []} 會顯示這段代碼失敗的原因

      確認收到郵件並完成 Mailjet API 登記

      回到您的電子郵箱,我們會發現剛才的API 認證電郵在我們的郵箱中。

      如果您使用 Gmail 或其他的免費郵箱註冊 Mailjet,那麼這封電郵很大機會將在您的垃圾郵件中。這是因為 Google 或其他的郵箱服務有時會把不是從 Gmail 發出的 @gmail.com 電郵認作虛假/詐騙電郵。

      因此,如果您希望發送電郵作商業用途/其他非個人用途,最好就註冊自己的域名(Domain name)並使用 @yourdomain.com 的電郵地址註冊 Mailjet 服務。

      完成後,我們回到 Mailjet 並按一下 “Verify Now” 的按鈕,可以見到 Mailjet 確認我們成功透過他們的 API 發送郵件!

      第三步:自訂含有 pandas dataframe 的簡單郵件

      現在我們把原來的程式碼稍為改變以下,製成我們開首展示的電郵吧!

      我是廣告 ^o^

      使用 pandas_datareader 讀取股票數據

      # 透過 pandas_datareader 讀取當天數據
      import datetime
      import pandas as pd
      from pandas_datareader import get_data_yahoo
      pd.options.display.float_format = '{:,.2f}'.format
      symbol = '0005.HK'
      
      endDate = datetime.datetime.now()
      startDate = endDate - datetime.timedelta(days=10)
      df = get_data_yahoo(symbol, startDate, endDate)
      lastprice = df.tail(1)['Adj Close'][0]

      這個具體的方法我們在 新手 2/3:Google Colab 如何製做互動表格和圖表?快來學 Import library/Jupyter 提及過,有興趣從零開始了解可以到上面的連結看看喔。

      由於我們新的 virtual environment 沒有安裝 pandas_datareader,記得先在 Terminal 運行以下指令:

      pip install pandas_datareader

      留意我們特別加入了 pd.options.display.float_format 的一句。這是為了在電郵上表格的數字格式。

      (重點)生成 HTML 代碼

      html = '''
      <center><h1>''' + symbol + ''' 的股價走勢報告</h1></center>
      <br>
      <p>''' + f'截止 {df.index[-1]:%Y/%m/%d},{symbol} 的股價為' + '''</p>
      <h2>'''+ f'{lastprice:.2f}' + '''</h2>
      <p>以下是 5 天走勢:</p>''' + df.tail(5).to_html()+ '''
      <br>
      <p>此致,</p>
      <p>Python Viz</p>
      '''

      這裡是本次教學的重點。我們需要透過生成一段 HTML 代碼,組成我們的電郵主體(body)。

      我們不在這裡詳談 HTML 的格式(畢竟我們不是 htmlviz),但這裡想重點介紹以下有關 Python 的要點:

      我是廣告 ^o^
      • f{'some string {num: format}'} 是一個強大的數字格式功能。我們透過例如 {df.index[-1]:%Y/%m/%d} 把日期轉換成為 “2021/04/16” 格式的 string。還未背熟這個編程方法的朋友記得記下來!
      • 我們使用 dataframe.to_html() 功能將 pandas dataframe 轉換稱 HTML 代碼,可以直接使用於這個電郵主體上。

      熟悉 HTML/網頁設計的朋友會知道我們可以透過加入 CSS 代碼,使電郵變得更加華倫華美。但是這個要留待我們下一篇教學了!

      生成電郵的 API request

      data = {
        'Messages': [
          {
            "From": {
              "Email": "[email protected]",
              "Name": "Python"
            },
            "To": [
              {
                "Email": "[email protected]",
                "Name": "Python"
              }
            ],
            "Subject": symbol + '的股價走勢報告',
            "TextPart": symbol + '的股價走勢報告',
            "HTMLPart": html,
            "CustomID": "AppGettingStartedTest"
          }
        ]
      }

      這裡我們修改了 Subject, TextPart 和 HTMLPart 的代碼,改為使用我們剛才生成的、含有股票價格數據的 HTML 代碼。

      第四步:完整代碼及結果

      以下是我們以上例子的完整代碼,您只要把 api_key、api_secret、data 裡面的 From/To 改成您的 Mailjet 設定便可以試試了:

      # Mailjet 的設定
      from mailjet_rest import Client
      import os
      api_key = '您的 Mailjet api_key'
      api_secret = '您的 Mailjet api_secret'
      mailjet = Client(auth=(api_key, api_secret), version='v3.1')
      
      # 透過 pandas_datareader 讀取當天數據
      import datetime
      import pandas as pd
      from pandas_datareader import get_data_yahoo
      pd.options.display.float_format = '{:,.2f}'.format
      symbol = '0005.HK'
      
      endDate = datetime.datetime.now()
      startDate = endDate - datetime.timedelta(days=10)
      df = get_data_yahoo(symbol, startDate, endDate)
      lastprice = df.tail(1)['Adj Close'][0]
      
      # 製做 HTML 內容作為郵件主體
      html = '''
      <center><h1>''' + symbol + ''' 的股價走勢報告</h1></center>
      <br>
      <p>''' + f'截止 {df.index[-1]:%Y/%m/%d},{symbol} 的股價為' + '''</p>
      <h2>'''+ f'{lastprice:.2f}' + '''</h2>
      <p>以下是 5 天走勢:</p>''' + df.tail(5).to_html()+ '''
      <br>
      <p>此致,</p>
      <p>Python Viz</p>
      '''
      
      data = {
        'Messages': [
          {
            "From": {
              "Email": "您的電郵地址",
              "Name": "您的名稱"
            },
            "To": [
              {
                "Email": "您的電郵地址",
                "Name": "您的名稱"
              }
            ],
            "Subject": symbol + '的股價走勢報告',
            "TextPart": symbol + '的股價走勢報告',
            "HTMLPart": html,
            "CustomID": "AppGettingStartedTest"
          }
        ]
      }
      result = mailjet.send.create(data=data)
      
      print(result.status_code)
      print(result.json())

      發出電郵以後,如果您使用 @gmail.com 的電郵地址發出,您會在 Gmail 見到以下的警告:

      這也再次說明如果我們有自己的域名(Domain name),使用自己域名的電郵地址(如 @yourdomain.com)可以減低電郵被郵件服務視作垃圾郵件的機會!

      我是廣告 ^o^

      下一步

      我們下一次會介紹如何把這個 Python 發出的電郵透過免費的網上服務變得更加精美,以及如何在電郵嵌入(Embed)透過 plotly 製做的數據圖表。記得留意詳情了!

      人氣文章

      快讓我學更多

      small_c_popup.png
      想學習 Python 嗎?
      快來訂閱我們的電子報!