Let's start Scheme

2015-09-22

SMTPクライアント

何かが失敗したときにメールを飛ばせると便利かなぁと思い書いた。こんな感じでメールが飛ばせる(サンプルはドキュメントから)。

(import (rnrs) (rfc client))

;; creates SMTP mail object
(define mail 
  (smtp:mail
   (smtp:from "Your name" "your-address@example.com")
   (smtp:subject "Subject")
   "Message"
   (smtp:to "recipient@example.com")))

;; creates an SMTP connection
(define smtp-conn (make-smtp-connection "your.smtp.server.com" "587"))

;; connect to the server
(smtp-connect! smtp-conn) ;; returns SMTP connection

;; Authenticate if required.
(when (smtp-authentication-required? smtp-conn)
  ;; NOTE: only AUTH PLAIN is supported for now
  (cond ((memq 'PLAIN (smtp-connection-authentication-methods smtp-conn))
         (smtp-authenticate! smtp-conn (smtp-plain-authentication
                                        "username"
                                        "password")))
        (else (smtp-disconnect! smtp-conn)
              (error #f "authentication method not supported" 
                     (smtp-connection-authentication-methods smtp-conn)))))

;; Send it
(smtp-send! smtp-conn mail) ;; returns SMTP connection

;; Clean up
(smtp-disconnect! smtp-conn)
メールを作る部分は利便性を高めるためにマクロを用意してて、これの嬉しい点としては、記述力が高いこともあるけど、以下のようにメールをテンプレートとして外部ファイルに書き出しておいて、readevalで手軽に作成することができることもある。
(define mail
  (eval (call-with-input-file "mail.scm" read)
        (environment '(rnrs) '(rfc smtp))))
今のところは考えてないけど、メールのソース(MIMEテキスト)からメールをパース・生成するというのがあってもいいかもしれない。(その前に認証をもう少しなんとかしないとという感じではあるのだが。PLAINだけとかいくらなんでもねぇ・・・)

 一応RFC5321に書いてあるコマンドは全部実装してあるが、拡張とかは全然だし、エラー処理とかもまだ大分甘いので使って直していくという感じ。

No comments:

Post a Comment