折角実装したのに、Yahooにメールが届かなくなった。
パソコン側の問題?
アップデートでも走った?
うーん、どこまで通信ができているのだろう?
どうやらYahooのSTMPサーバから応答がないらしい。
なぜ?
原因は
2021年1月19日からSSL通信のみ受け付ける
Yahoo!メールではセキュリティ強化の取り組みとして、Yahoo!メールをより安全にご利用いただくためにこのたび、誠に勝手ながら2021年1月19日をもちまして、メールソフトでYahoo!メールを送受信する際の認証方式「POP(非暗号化ポート: ポート番号 110)」「SMTP(非暗号化ポート: ポート番号 25 , 587)」の提供を終了させていただくことになりました。
は〜ぁ?
こっちは、ようやく実装完了して稼働させたばかりなのに、もう実装変更だよ・・・。
稼働日は2週間じゃねーか!
これに気づくだけでも超時間がかかったわ!
そもそも停止日は2021年1月19日じゃなく、2021年2月2日からだったから!
ひとつ積んでは父のため。
ふたつ積んでは母のため。
みっつ積んではふるさとの、兄弟我が身と回向する。
日も入りあいのその頃は、地獄の鬼が現れて、我を恨むる事なかれと、くろがねの棒を伸べ、積みたる塔を押し崩す。
ガシャーン
あぁ・・・・またやり直し・・・。
これはこの世のことならず、死出の山路の裾野なる、賽の河原の物語
・・・現実にも何度も起きてるよ。
日記の更新頻度が上がって良いなぁ、糞。
株の自動売買進んでねーよ。
まだ公開してない日記が220件超えたよ。
ネット上に情報が見つからない
「STMP Proxy SSL python」とかでググっても全くヒットしない。
前回の実装を参考に修正してみてもうまくいかない・・・・。
もう、諦めて違う方法で対応しようかと何度も思った。
で、改めて前回の日記を開いて下記のサイトの内容を読み直した。
ダメ元で最初の返答内容で実装して、メールが送信できるか確認してみる。
pythonは標準ではsocksをサポートしてないようなので、SocksiPyというのを使う。
1 2 3 4 5 6 7 8 9 |
import ssl import socks import smtplib socks.setdefaultproxy(socks.HTTP, PROXY_HOST, PROXY_PORT) socks.wrapmodule(smtplib) context = ssl.create_default_context() conn = smtplib.SMTP_SSL("smtp.mail.yahoo.co.jp", 465, timeout=10, context=context) (以下変更なし) |
あれっ・・・できた!
簡単だね、setproxyが挟まるだけ。
だったら、前回のようにClassを定義した長い実装コードも不要じゃん。
まとめ
答えが分かってしまえば簡単だ。
でも、それが分かるまで息苦しさに悶ながら延々と調査をすることになる。
で、内容としては短いがググっても出てこないので、知りたい人には有効な情報だと思って公開した。
ソースコード
前述のとおり、システムトレードの検証データを送信するスクリプトなので、必要に応じて余計な処理は削除が必要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
import smtplib import socket from email.mime.text import MIMEText import functools print = functools.partial(print, flush=True) import ssl import socks #################################################### # # Setting # #################################################### # Proxy PROXY_HOST = "" PROXY_PORT = "" # STMP YOUR_EMAIL_ADDRESS = "" YOUR_PASSWORD = "" STMP_HOST = "smtp.mail.yahoo.co.jp" STMP_PORT = "465" # E-Mail FROM_ADDR = "" TO_ADDR = "" SUBJECT = "PER update" MESSAGE = "" # File Path PATH = ".\\data\\log\\lasttrading.txt" LINE = 20 #################################################### # Get line N from end of file def tail(f, lines=20): total_lines_wanted = lines BLOCK_SIZE = 1024 f.seek(0, 2) block_end_byte = f.tell() lines_to_go = total_lines_wanted block_number = -1 blocks = [] while lines_to_go > 0 and block_end_byte > 0: if (block_end_byte - BLOCK_SIZE > 0): f.seek(block_number*BLOCK_SIZE, 2) blocks.append(f.read(BLOCK_SIZE)) else: f.seek(0,0) blocks.append(f.read(block_end_byte)) lines_found = blocks[-1].count(b'\n') lines_to_go -= lines_found block_end_byte -= BLOCK_SIZE block_number -= 1 all_read_text = b''.join(reversed(blocks)) return b'\n'.join(all_read_text.splitlines()[-total_lines_wanted:]) def main(): if (PROXY_HOST != ""): socks.setdefaultproxy(socks.HTTP, PROXY_HOST, int(PROXY_PORT)) socks.wrapmodule(smtplib) if (STMP_PORT == "25" or STMP_PORT == "587"): # Both port 25 and 587 work for SMTP conn = smtplib.SMTP(STMP_HOST, STMP_PORT, timeout=10) if (STMP_PORT == "587"): # if STARTTLS extension supports by server conn.ehlo() conn.starttls() conn.ehlo() else: # In the case of SSL context = ssl.create_default_context() conn = smtplib.SMTP_SSL(STMP_HOST, int(STMP_PORT), timeout=10, context=context) r, d = conn.login(YOUR_EMAIL_ADDRESS, YOUR_PASSWORD) print('Login reply: %s' % r) # Create message f = open(PATH, 'rb') msg = MIMEText(MESSAGE + tail(f, LINE).decode('utf-8')) msg['Subject'] = SUBJECT msg['From'] = FROM_ADDR msg['To'] = TO_ADDR print('Send email.') conn.sendmail(FROM_ADDR, [TO_ADDR], msg.as_string()) print('Success.') conn.close() if __name__ == '__main__': main() |