diff --git a/sending-email-in-common-lisp.html b/sending-email-in-common-lisp.html new file mode 100644 index 0000000..524e9cc --- /dev/null +++ b/sending-email-in-common-lisp.html @@ -0,0 +1,172 @@ + + + + + + + +Sending email in common-lisp + + + + + + + + + + +
+

Sending email in common-lisp

+ +
+

Summary:

+
+

+This page covers how to send an email from your common-lisp coding using the cl-smtp library using googles gmail servers. +

+
+
+ + +
+

Introduction

+
+

+This post covers a working example on how to send email from the common-lisp (cl) language using googles servers. The provided +example has been tested as an individual, and regularly used from the 'google workspace' account. +

+
+
+ + +
+

Requirements:

+
+

+An Application password. +

+ +

+Google detailed getting one here. One fact that was missed is that you now need 2FA +configured for the account or you can not make app passwords. +

+
+
+ + +
+

Ideas for improvement.

+
+
+
+

1. Secret Storage mechanism.

+
+

+The application password needs to be stored somewhere, my advice is not to have it stored in plaintext. +

+ +

+If your application is hosted on a containerized platform, you can pass it as environment variables, or +some of them have secrets file. +

+
+
+ +
+

2. Preventing secret leaks.

+
+

+After the secret is loaded into memory, destroy the file or environment setting so it is harder for attackers +to abuse the information. +

+ +
+
(setf (uiop:getenv "SOME_ENVIRONMENT_VARIABLE") "PASSWORD-REMOVED-FOR-SECURITY-REASONS")
+
+
+ +

+When it is loaded, use Secret Values which will prevent passwords appearing in backtraces or logs. +

+
+
+ +
+

3. Preventing accidental/intention spamming.

+
+

+Your application may accidentally send out hundreds of mail if a function is run repeatedly accidentally. +It is important that the program keep an accurate, reliable mechanism to know when a limits are abused. +

+
+
+
+ + +
+

The code:

+
+

+Listed below is the common-lisp code that is required to send email. The "password" is stored +in the environment variable GMAIL_KEY, as a single string. Google often displays on the 'app password' +page as 4 sets of 4 characters, aka xxxx xxxx xxxx xxxx , however experience shows that there was no space required. +

+ +
+
+(ql:quickload "cl-smtp")
+(ql:quickload "cl-mime")
+
+(defun email-report (&key to cc subject html)
+       "Generic send SMTP mail with some TEXT to RECIEPIENTS"
+       (let ((from "your@gmail.com")
+             (login "youraccount@gmail.com")
+             (passwd (uiop:getenv "GMAIL_KEY")))
+
+         (cl-smtp:with-smtp-mail (out "smtp.gmail.com" to cc
+                                      :ssl :tls
+                                      :authentication `(,login ,passwd))
+
+           (format out "To: ~A~%" to )
+           (format out "Subject: ~A~%" subject)
+
+           (cl-mime:print-mime out (make-instance 'cl-mime:mime
+                                                  :type "text" :subtype "html"
+                                                  :encoding :base64
+                                                  :content html) t t))))
+
+(devar html-mail-content "<html><h1> THis is html, but not really. </h1></html>")
+
+(email-report :to "someone@example.com"
+              :cc *cc-list*
+              :subject email-subject
+              :html html-content)
+
+
+
+
+ +
+

Conclusion

+
+

+This example works for both personal and google workspace accounts. +

+
+
+ + + +
+

Resources:

+ +
+
+ + diff --git a/sending-email-in-common-lisp.org b/sending-email-in-common-lisp.org new file mode 100755 index 0000000..6205dd1 --- /dev/null +++ b/sending-email-in-common-lisp.org @@ -0,0 +1,101 @@ +#+TITLE: Sending email in common-lisp + +#+OPTIONS: ^:nil num:nil toc:nil date:nil author:nil html-postamble:nil +#+SETUPFILE: "./setupfile.org" +#+HTML_HEAD: + +* Summary: + +This page covers how to send an email from your common-lisp coding using the cl-smtp library using googles gmail servers. + + +* Introduction + +This post covers a working example on how to send email from the common-lisp (cl) language using googles servers. The provided +example has been tested as an individual, and regularly used from the 'google workspace' account. + + +* Requirements: + + + An Application password. + + [[https://knowledge.workspace.google.com/kb/how-to-create-app-passwords-000009237][Google detailed getting one here.]] One fact that was missed is that you now need 2FA + configured for the account or you can not make app passwords. + + +* Ideas for improvement. + +** 1. Secret Storage mechanism. + + The application password needs to be stored somewhere, my advice is not to have it stored in plaintext. + + If your application is hosted on a containerized platform, you can pass it as environment variables, or + some of them have secrets file. + +** 2. Preventing secret leaks. + + After the secret is loaded into memory, destroy the file or environment setting so it is harder for attackers + to abuse the information. + + #+BEGIN_SRC lisp + (setf (uiop:getenv "SOME_ENVIRONMENT_VARIABLE") "PASSWORD-REMOVED-FOR-SECURITY-REASONS") + #+END_SRC + + When it is loaded, use [[https://github.com/rotatef/secret-values][Secret Values]] which will prevent passwords appearing in backtraces or logs. + +** 3. Preventing accidental/intention spamming. + + Your application may accidentally send out hundreds of mail if a function is run repeatedly accidentally. + It is important that the program keep an accurate, reliable mechanism to know when a limits are abused. + + +* The code: +:LOGBOOK: +- Note taken on [2024-09-13 Fri 00:25] +:END: + + Listed below is the common-lisp code that is required to send email. The "password" is stored + in the environment variable GMAIL_KEY, as a single string. Google often displays on the 'app password' + page as 4 sets of 4 characters, aka xxxx xxxx xxxx xxxx , however experience shows that there was no space required. + + #+BEGIN_SRC lisp + + (ql:quickload "cl-smtp") + (ql:quickload "cl-mime") + + (defun email-report (&key to cc subject html) + "Generic send SMTP mail with some TEXT to RECIEPIENTS" + (let ((from "your@gmail.com") + (login "youraccount@gmail.com") + (passwd (uiop:getenv "GMAIL_KEY"))) + + (cl-smtp:with-smtp-mail (out "smtp.gmail.com" to cc + :ssl :tls + :authentication `(,login ,passwd)) + + (format out "To: ~A~%" to ) + (format out "Subject: ~A~%" subject) + + (cl-mime:print-mime out (make-instance 'cl-mime:mime + :type "text" :subtype "html" + :encoding :base64 + :content html) t t)))) + + (devar html-mail-content "

THis is html, but not really.

") + + (email-report :to "someone@example.com" + :cc *cc-list* + :subject email-subject + :html html-content) + #+END_SRC + +* Conclusion + +This example works for both personal and google workspace accounts. + + + +* Resources: + +https://gitlab.common-lisp.net/cl-smtp/cl-smtp diff --git a/setupfile.org b/setupfile.org index b5dbaf5..7c18b0f 100644 --- a/setupfile.org +++ b/setupfile.org @@ -9,4 +9,9 @@ #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: -#+HTML_HEAD_EXTRA: +--- #+HTML_HEAD_EXTRA: +#+HTML_HEAD_EXTRA: + + + +*