[Gmail API] Javaでメッセージ本文を作成する

Gmail APIで共通して使用する
com.google.api.services.gmail.model.Messageクラス
についてご紹介します。

Gmail APIを使用する上でMessageクラスはよく出てくるクラスですので、
メッセージ本文の生成の方法を記事にまとめました。

:::note info
Gmail APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Gmail API] JavaでGmail APIを使う](https://qiita.com/doran/items/a078e966bfd93c4b19c2)
を参照ください。
:::

|No||目次|
|---|---|---|
|1||[jakarta.mailライブラリの使用](#1-jakartamailライブラリの使用)|
|2||[MimeMessageインスタンス生成](#2-mimemessageインスタンス生成)
||1|[添付ファイルがない場合](#21-添付ファイルがない場合)|
||2|[添付ファイルがある場合](#22-添付ファイルがある場合)|
|3||[MimeMessageクラスのメソッド](#3-mimemessageクラスのメソッド)|
||1|[メールヘッダ](#31-メールヘッダ)|
||2|[メッセージボディ](#32-メッセージボディ)|
|4||[Messageインスタンスの取得](#4-messageインスタンスの取得)|

## 1. jakarta.mailライブラリの使用
メッセージを生成する際、jakarta.mailライブラリのMimeMessageクラスを使います。

```xml
<dependency>
    <groupId>org.eclipse.angus</groupId>
    <artifactId>jakarta.mail</artifactId>
    <version>1.0.0</version>
</dependency>
```
        
## 2. MimeMessageインスタンス生成
サンプルでは最小限のコードをご紹介しています。

これにヘッダを追加したい場合は、
[3.1. メールヘッダ](#31-メールヘッダ)を参考にしてください。

プレーンテキスト以外の本文を指定したい場合(例えばHTML)は、
[3.2. メッセージボディ](#32-メッセージボディ)を参考にしてください。

#### 2.1. 添付ファイルがない場合
サンプルでは、TO,件名,本文(テキスト)を指定して
MimeMessageインスタンスを生成しています。

```java
public static MimeMessage createMimeMessage(String to,String subject,String body) throws Exception {
    Session session = Session.getDefaultInstance(new Properties());
    MimeMessage email = new MimeMessage(session);

    email.setRecipient(jakarta.mail.Message.RecipientType.TO,new InternetAddress(to));
    email.setSubject(subject);
    email.setText(bodyText);
    
    return email;
}
```

#### 2.2. 添付ファイルがある場合
サンプルでは、TO,件名,本文(テキスト),添付ファイル(ファイルパス)を指定して
MimeMessageインスタンスを生成しています。
引数のfilesは、key:ファイル名、value:ファイルパスのMapです。
```java
public static MimeMessage createMimeMessage(String to,String subject,String body,Map<String,String> files) throws Exception {
    Session session = Session.getDefaultInstance(new Properties());
    MimeMessage email = new MimeMessage(session);

    email.setRecipient(jakarta.mail.Message.RecipientType.TO,new InternetAddress(to));
    email.setSubject(subject);

    //メッセージボディの設定は「MimeMultipart」を使用します
    MimeMultipart multipart = new MimeMultipart();
    MimeBodyPart text = new MimeBodyPart();
    text.setText(body);
    multipart.addBodyPart(text);
    
    for(Map.Entry<String,String> file : files.entrySet()) {
        MimeBodyPart part = new MimeBodyPart();
        part.setDataHandler(new DataHandler(new FileDataSource(file.getValue())));
        part.setFileName(file.getKey());
        multipart.addBodyPart(part);
    }
    email.setContent(multipart);
    
    return email;
}
```

## 3. MimeMessageクラスのメソッド
MimeMessageのsetメソッドをメールヘッダとメッセージボディ、
それぞれに一覧を用意しました。

### 3.1. メールヘッダ
|ヘッダ|概要|メソッド|
|---|---|---|
|From|差出人アドレス|addFrom(Address[] addresses)|
|||setFrom(Address address)|
|||setFrom(String address)|
|Sender|実際の差出人アドレス|setSender(Address address)|
|To|宛先アドレス|addRecipients(Message.RecipientType type, Address[] addresses)|
|||addRecipients(Message.RecipientType type, String addresses)|
|||addRecipient(Message.RecipientType type, Address addresses)|
|||setRecipients(Message.RecipientType type, Address[] addresses)|
|||setRecipients(Message.RecipientType type, String addresses)|
|||setRecipient(Message.RecipientType type, Address addresses)|
|||typeにMessage.RecipientType.TO指定|
|cc|CCアドレス|Toと同じ<br>typeにMessage.RecipientType.CC指定|
|bcc|BCCアドレス|Toと同じ<br>typeにMessage.RecipientType.BCC指定|
|Subject|メール件名|setSubject(String subject)|
|||setSubject(String subject, String charset)|
|Date|メールの作成日時|setSentDate(Date d)|
|filename|メールに添付されるファイル名|setFileName(String filename)|
|Content-ID|コンテンツ識別子<br>(Message-IDと同じ)|setContentID(String cid)|
|Content-Description|注釈|setDescription(String description)|
|||setDescription(String description, String charset)|
|Content-Disposition|ファイルの扱いを指定<br>inline：WEBで表示<br>attachment：ダウンロード|setDisposition(String disposition)|
|Content-Language|言語コード|setContentLanguage(String[] languages)|
|Content-MD5|MD5ハッシュ値<br>メッセージボディの変更保証に使用|setContentMD5(String md5)|
|その他|上記にないヘッダ|addHeaderLine(String line)|
|||addHeader(String name, String value)|
|||setHeader(String name, String value)|

### 3.2. メッセージボディ

|種類|メソッド|
|---|---|
|プレーンテキスト|setText(String text)|
||setText(String text, String charset)|
||setText(String text, String charset, String subtype)|
|プレーンテキスト以外|setContent(Multipart mp)|
||setContent(Object o, String type)|

## 4. Messageインスタンスの取得
[2. MimeMessageインスタンス生成](#2-mimemessageインスタンス生成)で取得したインスタンスを渡して
Messageインスタンスを生成します。

Base64クラスは、「org.apache.commons.codec.binary」のクラスです。
```java
public static Message createMessage(MimeMessage email) throws IOException, MessagingException {
    byte[] bytes = null;
    try(ByteArrayOutputStream buffer = new ByteArrayOutputStream()){
        email.writeTo(buffer);	//メッセージをストリームへ出力
        bytes = buffer.toByteArray();
    }
    String encodedEmail = Base64.encodeBase64URLSafeString(bytes);
    
    Message message = new Message();
    message.setRaw(encodedEmail);
    
    return message;
}
```

#### Message

|メソッド|引数|説明|
|---|---|---|
|setId|String|メッセージID|
|setThreadId|String|メッセージが属するスレッドID|
|setLabelIds|List\<String\>|このメッセージに適用されるラベルIDリスト|
|setSnippet|String|メッセージテキストのスナップショット|
|setHistoryId|String|このメッセージを変更した最後の履歴レコードID|
|setInternalDate|Long|内部メッセージ作成タイムスタンプ(エポックミリ秒)|
|setPayload|[MessagePart](#messagepart)|メッセージ部分の解析された内容|
|setSizeEstimate|Integer|メッセージの推定サイズ(バイト単位)|
|setRaw|String|Base64 URLエンコードされたメッセージ|

#### MessagePart

|メソッド|引数|説明|
|---|---|---|
|setPartId|String|メッセージ部分ID|
|setMimeType|String|メッセージ部分のMIMEタイプ|
|setFilename|String|添付ファイルのファイル名
|setHeaders|List\<[Header](#header)\>|メッセージ部分のヘッダーリスト|
|setBody|[MessagePartBody](#messagepartbody)|メッセージ部分の本文|
|setParts|List\<[MessagePart](#messagepart)\>|子のMIMEメッセージ部分|

#### Header

|メソッド|引数|説明|
|---|---|---|
|setName|String|セパレータの前のヘッダーの名前。例："To"|
|setValue|String|区切り文字の後のヘッダー値|

#### MessagePartBody

|メソッド|引数|説明|
|---|---|---|
|setAttachmentId|String|添付ファイルID|
|setSize|Integer|メッセージ部分データのバイト数|
|setData|String|Base64 URLエンコードされたメッセージ部分の本体データ|
<br>
<br>
おしまい。。