ส่ง email ด้วย Spring Boot และ Gmail

ในบทความนี้ เราจะมาเขียนคำสั่งส่ง email ด้วย Spring Boot โดยทำการส่ง email ผ่าน Gmail SMTP

ขั้นตอนในการเขียน program มีดังนี้

  • สร้าง Gradle project ด้วย IntelliJ IDEA หรือ editor อื่นๆ ที่รองรับ Gradle
  • เพิ่ม library ที่จำเป็นเข้าไปใน project
  • แก้ไข config file สำหรับเชื่อมต่อกับ Gmail
  • เขียนคำสั่ง Java ส่ง email

สร้าง Gradle project ด้วย IntelliJ IDEA หรือ editor อื่นๆ ที่รองรับ Gradle

ให้เราเปิด IntelliJ IDEA แล้วสร้าง Gradle Project ใหม่ image 1

image 2

image 3

image 4

เพิ่ม library ที่จำเป็นเข้าไปใน project

library ที่จำเป็นที่เราจะเพิ่มเข้าไปใน gradle.build คือ

  • org.springframework.boot:spring-boot-starter-web:1.3.2.RELEASE เป็น library ที่จำเป็นอย่าง ที่เตรียม library อื่นที่จำเป็นในการสร้าง Spring Boot web application มาแล้ว
  • org.springframework.boot:spring-boot-starter-mail:1.3.2.RELEASE เป็น library ที่ Spring Boot ได้เตรียม auto config ค่าต่างๆ ในการส่ง email ช่วยอำนวยความสะดวกให้มากขึ้น

เปิด file build.gradle แล้วแก้ไข เป็นดังนี้

\spring-boot-gmail\build.gradle

group 'com.codesanook'
version '1.0-SNAPSHOT'


buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.2.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'spring-boot'
sourceCompatibility = 1.7

repositories {
    mavenCentral()
}

dependencies {
    compile "org.springframework.boot:spring-boot-starter-web:1.3.2.RELEASE"
    compile "org.springframework.boot:spring-boot-starter-mail:1.3.2.RELEASE"
}

หลังจากแก้ไข gradle.build ให้เราทำการ update เสมอโดยไปที่ Gradle window click ปุ่ม update

image 5

แก้ไข config file สำหรับเชื่อมต่อกับ Gmail

ให้เราสร้าง file application.properties ใน folder /src/main/resources แล้วแก้ไขค่าต่างๆ ดังต่อไปนี้ โดย username และ password แก้ไขให้ตรงกับ email ที่เราใช้อยู่

\src\main\resources\application.properties

spring.mail.default-encoding = UTF-8
spring.mail.host = smtp.gmail.com
spring.mail.username= you-username
spring.mail.password= you-password
spring.mail.port= 587
spring.mail.properties.mail.smtp.ssl.enable = true
spring.mail.protocol = smtp
spring.mail.test-connection=false

สร้าง HomeController.java ใน package com.codesanook แล้วแก้ไขเป็นดังนี้

src\main\java\com\codesanook\HomeController.java

package com.codesanook;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@SpringBootApplication
public class HomeController {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(HomeController.class, args);
    }

    @Autowired
    private MailSender mailSender;

    @RequestMapping("/")
    @ResponseBody
    public String home() {

        try {

            SimpleMailMessage message = new SimpleMailMessage();
            String from = "from@gmail.com";
            String to = "to@gmail.com";
            String subject = "hello world";
            String body = "Hello world theeranitp";
            message.setFrom(from);
            message.setTo(to);
            message.setSubject(subject);
            message.setText(body);
            mailSender.send(message);
            return "email sent";

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "error";
    }


}

  • MailSender mailSender เป็น bean ที่มีชื่อว่า mailSender ที่ Spring Boot เตรียมมาให้เราแล้ว เราเพียงใช้ @Autowired กำกับไว้ mailSender จะถูก Assign ค่าให้อัตโนมัติ inject
  • SimpleMailMessage class สำหรับเก็บข้อมูลต่างๆ ของ email เช่น ผู้รับ ผู้ส่ง ชื่อเรื่อง เนื้อหาของ email
  • เราใช้ mailSender ส่ง SimpleMailMessage object เพื่อส่ง email
  • สังเกตว่าค่า config ต่างๆ นัน Spring Boot จะนำจาก application.properties ไปใช้งานโดยอัตโนมัติและสร้างเป็น mailSender object ให้เราใช้งานเลย

ทดสอบการทำงานของ application

เมื่อ run Spring Boot application แล้วใช้ browser เปิด URL หากการทำงานทำงานทุกอย่างถูกต้อง username password ถูกต้อง email ที่ส่ง และรับ ถูกต้อง ที่ web browser ก็จะมีข้อความ email sent แสดงออกมา

image 1

ถ้าเข้าไปที่ inbox ของ to email ก็จะเจอ email hello world ที่ส่งเข้ามาครับ

สำคัญมาก

หากผู้อ่านท่านใดมีปัญหา ไม่สารถส่ง email ได้ และมี error ที่ตอบกลับมาจากทาง Gmail ให้ลองเปิดสิทธิ์ให้ App สามารถใช้งาน gmail ได้

โดยค้นหา Less secure apps setting

สำหรับ user ทั่วไป สามารถเข้าไปตาม link นี้ได้เลย https://www.google.com/settings/security/lesssecureapps

image 1

แต่ถ้าผู้อ่านใช้บริการ Google Apps for Work เช่นเดียวกับ codesanook.com ที่ใช้ Gmail เป็น backend ของ admin contract

ตรงนี้ต้องเข้าไปลึกหน่อย โดยเข้าไปที่ admin console https://admin.google.com ถ้ายังไม่ได้ login ก็ให้ทำการ login ให้เรียบร้อย แล้วระบบจะนำเราไปยังหน้าแรกของ admin console

แล้วเลือก menu Security

ถ้าไม่เจอก็ให้เลือกหาจาก more control ครับ ปุ่ม menu Security อาจซ่อนอยู่ในนั้น

image 2

จากนั้นให้เข้าไปที่ Basic Settings > Less secure apps > Go to settings for less secure apps แล้วเลือกตัวเลือกตามรูปได้เลย

สังเกตว่า Google ไม่แนะนำวิธีการที่เราทำ คือการเปิดสิทธิ์ให้ app ที่เราเขียนเข้ามาใช้งาน Gmail ได้เนื่องจากมีความเสี่ยงที่จะโดน hacked เพราะ username และ password ของเราแนบไปกับ email เพื่อใช้ authentication อีกทั้ง username และ password ก็เก็บลงใน application Google ต้องการให้เราติดต่อ Gmail ด้วย OAuth 2.0 ครับ

ดังนั้น ถ้าเราไม่ต้องการเปิด less secure app แบบนี้ เราต้องต้องติดต่อ Gmail โดยใช้ OAuth 2.0 โดยจะมีตัวอย่างการใช้งานในบทความต่อไป

ข้อมูลเพิ่มเติมเกี่ยวกับความหมายของ Less secure apps จาก Google

...beginning in the second half of 2014, we'll start gradually increasing the security checks performed when users log in to Google. These additional checks will ensure that only the intended user has access to their account, whether through a browser, device or application. These changes will affect any application that sends a username and/or password to Google.

To better protect your users, we recommend you upgrade all of your applications to OAuth 2.0. If you choose not to do so, your users will be required to take extra steps in order to keep accessing your applications.

ดังนั้นเพื่อความปลอดภัย แนะนำให้เปลี่ยนกลับแบบเดิมครับ แต่สิ่งที่เราได้เรียนรู้เพื่อ prove concept เข้าใจ flow การทำงาน การส่ง email ด้วย Spring Boot ที่แทบไม่ต้อง config หรือเขียน code มากมาย เพราะ Spring Boot ได้เตรียมมาให้เราแล้ว

ขอบคุณครับ

download source code

https://github.com/codesanook/spring-boot-gmail