> For the complete documentation index, see [llms.txt](https://tech.x2bee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tech.x2bee.com/dev-guide/dev-start/undefined/undefined-1.md).

# 메일 발송

이 문서는 메일전송 소스와 방법에 대해 다룹니다.

첫 번째로는 Config 설정 방법 및 확인에 대해 설명합니다.\
두 번째로 각 업무단 작성 방법을 설명합니다.

{% hint style="info" %}
\<update>

2023.08.03

* MailSendRequest siteNo 를 입력하지 않아도 자동으로 넘어가도록 수정했습니다.

2024.05.29

* sendTemplateMailBulk 추가
  {% endhint %}

***

## Config 설정

**application.yml**

```yaml
mail:
  smtp:
    host: smtp.office365.com
    port: 587
    userName: x2bee@plateer.com
    password: X2commerce!1
  fromMail: x2bee@plateer.com
  fromNameKo: 플래티어_X2BEE
  fromNameEn: PLATEER_X2BEE
```

## Sample 소스 및 설명

* [x2bee-api-sample-vanilla](https://gitlab.x2bee.com/x2bee-venus-beta/venus-x2bee-api-sample-vanilla) 프로젝트

**MailController 예시 (요약):**

```java
@Autowired
private MailSender mailSender;

@PostMapping("/send")
public ResponseEntity<Response> send() throws MessagingException, UnsupportedEncodingException {
    Map<String, Object> params = new HashMap<>();
    // 템플릿용 파라미터
    params.put("name","teset");

    // 단건 전송
    MailSendRequest request = MailSendRequest.builder()
        .siteNo("1") // null 일 경우 Cookie에서 자동입력됩니다.
        .mbrNo("100033")
        .emailGbCd("EMA-MA_11")
        .emailTitle("안녕하세요 이메일 전송 테스트입니다.")
        .emailConts("이메일 내용이 들어가는 곳입니다.") // 템플릿을 사용하는경우 삭제!
        .template("sample/sp1") // 템플릿을 사용하는 경우 ---(2)필독!
        .variables(params) // 템플릿용 파라미터
        .recvmnNm("테스트")
        .recvmnEmailAddr("emailtempid@naver.com")
        .build();

    // ----- API-COMMON 프로젝트에서 직접 호출시
    mailSender.send(request);

    // ----- API-COMMON 호출시
    // restApiUtil.post(
    //   this.commonApiUrl + "/api/common/interface/bizmessage/sendmail",
    //   request,
    //   new ParameterizedTypeReference<Response<Void>>() {}
    // ).getPayload();

    // 대량 전송 예시
    List<MailSendRequest> mailSendRequestList = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        mailSendRequestList.add(
            MailSendRequest.builder()
                .siteNo("1") // null 일 경우 Cookie에서 자동입력됩니다.
                .mbrNo("100033")
                .emailGbCd("EMA-MA_11")
                .emailTitle("안녕하세요 이메일 전송 테스트 : "+(i+1))
                .emailConts("이메일 내용이 들어가는 곳입니다. -- "+(i+1)) // 템플릿을 사용하는경우 삭제!
                .template("sample/sp1") // 템플릿을 사용하는 경우 ---(2)필독!
                .variables(params) // 템플릿용 파라미터
                .recvmnNm("테스트")
                .recvmnEmailAddr("emailtempid@naver.com")
                .build()
        );
    }

    // ----- API-COMMON 프로젝트에서 직접 호출시
    // mailSender.sendBulk(mailSendRequestList);

    // ----- API-COMMON 호출시
    // restApiUtil.post(
    //   this.commonApiUrl + "/api/common/interface/bizmessage/sendmailbulk",
    //   mailSendRequestList,
    //   new ParameterizedTypeReference<Response<Void>>() {}
    // ).getPayload();

    ...
}
```

<kbd>MailSendRequest</kbd> 를 생성하여 예제와 아래 테이블을 참조하여 파라미터를 입력합니다.

| 항목              | Mandatory       | Type   | 설명             | 비고                  |
| --------------- | --------------- | ------ | -------------- | ------------------- |
| siteNo          | NOT NULL (자동입력) | String | 사이트 번호         | null 로 작성시 쿠키값 자동입력 |
| mbrNo           | NOT NULL        | String | 회원 번호          |                     |
| emailGbCd       | NOT NULL        | String | 이메일구분코드(CM030) |                     |
| emailTitle      | NOT NULL        | String | 이메일 제목         |                     |
| emailConts      | NOT NULL        | String | 이메일 내용         |                     |
| recvmnNm        | NOT NULL        | String | 수신자 성명         |                     |
| recvmnEmailAddr | NOT NULL        | String | 수신자 이메일 주소     |                     |

**Builder 가 익숙치 않다면 Setter 도 사용 가능합니다:**

```java
MailSendRequest mailSendRequest = new MailSendRequest();
...
mailSendRequest.setEmailTitle("이메일 제목");
mailSendRequest.setEmailConts("이메일 내용");
mailSendRequest.setRecvmnEmailAddr("plateer@plateer.com");
...
mailSender.send(mailSendRequest);
```

### sendBulk 추가

* 대량의 메시지를 한번에 전송하는 sendBulk 메서드가 추가되었습니다.
* `X2BEE-COMMON 0.6.3` 이후 사용 가능
  * `MailSendRequest` 객체를 List로 받아 이메일 전송을 처리합니다.
  * Process : 메일전송 목록 INSERT (동기), 메일전송 처리 (비동기)
  * 테이블.컬럼명 : ST\_EMAIL\_SND\_HIST.email\_trns\_stat\_cd \
    (`CM029`) – 전송 성공 : 30 → <mark style="color:$success;">발송완료</mark>, 전송 실패 : 20 → <mark style="color:$danger;">발송ERROR</mark>

1. **다른 프로젝트에서 이메일 전송 시 (api-common 호출)**

* **`x2bee-api-common-vanilla` 가 아닌 다른 프로젝트에서 이메일을 전송하는 경우 api-common API를 호출합니다.**
* 예제 소스와 같이 `MailSendRequest` 객체에 필요 파라미터들을 담아 POST 방식으로 `/api/common/interface/bizmessage/sendmail` End Point를 호출합니다.
* `commonApiUrl` 은 application.yml 에 명시된 URL 입니다.

2. **템플릿을 사용하는 경우 (필독)**

* 기존 각 프로젝트에 있었던 MailSender 를 Common으로 옮기면서 각 프로젝트에 있던 타임리프 템플릿 들도 함께 `x2bee-api-common-vanilla` 으로 이동했습니다.
* 따라서 템플릿을 새로 생성할 때에는 각 프로젝트 폴더에 맞는 경로에 넣어주셔야 합니다.

<figure><img src="/files/5YtQ2bG57TJABfVapV1A" alt="" width="375"><figcaption></figcaption></figure>

* **템플릿 경로 (`email/apibo`, `email/apidisplay` 등) 는 각 프로젝트의 `application.yml` 에 명시되어 template 변수를 Builder 와 Setter 에서 문자열 앞에 자동으로 추가합니다.**
* 따라서 템플릿을 명시할 때에는 `email/apibo` 이후의 경로부터 입력합니다.

  * ex) x2bee-api-display-vanilla 프로젝트 내 application.yml
  *

  ```
  <div align="left"><img src="https://tech.x2bee.com/download/attachments/108003385/image-20230719-051634.png?version=1&#x26;modificationDate=1689743799588&#x26;cacheVersion=1&#x26;api=v2" alt="" width="375"></div>
  ```

***

### sendTemplateMailBulk 추가

* 기존 mail api와 달리 템플릿 데이터를 상위 파라미터로 받아 메일을 보내는 sendTemplateMailBulk가 추가되었습니다.
* `X2BEE-COMMON 0.9.71` 이후 사용 가능
* 기존과 같이 템플릿 파일 경로 넣어서 사용하거나 템플릿 데이터를 문자열로 보내 사용할 수 있습니다.

### Sample 소스 — sendTemplateMailBulk

템플릿 파일 경로를 사용할 경우 예시:

```java
MailSendTemplateRequest mailSendTemplateRequest = new MailSendTemplateRequest();
mailSendTemplateRequest.setTemplate("email/apimember/Join_ko");
mailSendTemplateRequest.setMailList(mailSendRequestList);

restApiUtil.post(
  this.commonApiUrl + "/api/common/interface/bizmessage/sendTemplateMailBulk",
  mailSendTemplateRequest,
  new ParameterizedTypeReference<Response<Void>>() {}
).getPayload();
```

템플릿 문자열로 사용할 경우 예시:

```java
MailSendTemplateRequest mailSendTemplateRequest = new MailSendTemplateRequest();
mailSendTemplateRequest.setTemplate("<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8' /><title>회원가입완료 안내</title></head><body><tbody><td>[<span th:text='${userName}'></span>]님, 안녕하세요.<br />[<span th:text='${userName}'></span>]님의 회원가입을 진심으로 감사드립니다.</td></tbody></table></body></html>");
mailSendTemplateRequest.setMailList(mailSendRequestList);

restApiUtil.post(
  this.commonApiUrl + "/api/common/interface/bizmessage/sendTemplateMailBulk",
  mailSendTemplateRequest,
  new ParameterizedTypeReference<Response<Void>>() {}
).getPayload();
```

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tech.x2bee.com/dev-guide/dev-start/undefined/undefined-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
