はじめに
はじめまして。原です。
会社で働いていると、運営しているサイトのユーザに告知をしたり、社員全体に業務連絡をしたり、大勢の人にメールを送ることがよくあります。
手元に配信したい内容とその送り先のメールアドレスがあっても、一度に大勢の人に送るとなるといくつか注意点があります。
- 到達率
- 送ったメールが迷惑メールに分類されてしまう
- 配信速度
- 配信対象が多いと配信に数時間かかってしまう
- 効果測定
- 業務によってはメールを送っただけでは意味がない
- 送ったメールが開封されているかリンクがクリックされているかも知りたい
- 可用性
- 常にメール配信ができるように配信システムの監視が必要
メールを送りたいだけなのに、これらの問題点をいちいち考慮するのは避けたいものです。
Synergy! メールAPI を使用してみる
シナジーマーケティングはメール配信用の Web API である「Synergy! メールAPI」(以下 メールAPI)を提供しております。
メールAPI を利用すれば、弊社の製品である Synergy! が使用している配信システムを使ってメール配信できます。
実績のある配信システムなので、先程触れたような懸念点を考慮することなく大量のメールを配信し、その開封率やクリック率を取得できます。
本記事では、メールAPI を使用してメール配信を行い、その結果を取得するコードを書いてみます。
メールAPI を使用するイメージを持っていただけたらと思います。
メールAPI のインターフェースは OpenAPI Specification
のフォーマットでウェブに公開されています。
せっかくなので openapi-generator-cli
を使ってインターフェースの定義ファイルからクライアントコードを自動生成してみたいと思います。
試した環境は下記のようになります。
1 2 3 4 5 6 7 |
$ java -version java version "1.8.0_191" Java(TM) SE Runtime Environment (build 1.8.0_191-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode) $ openapi-generator-cli version 4.1.2 |
アクセストークンの取得
メールAPI を利用するには、利用者ごとに用意された CLIENT_ID
と CLIENT_SECRET
を使って取得したアクセストークンが必要となります。
メールAPI のドキュメントに記載された方法でアクセストークンを取得します。詳細はそちらをご覧ください。base64 のオプションなど、環境によって差異があると思いますのでご注意ください。
1 2 3 4 5 6 7 8 9 |
$ CLIENT_ID={YOUR CLIENT ID} $ CLIENT_SECRET={YOUR CLIENT SECRET} $ AUTH_HEADER=`echo -n ${CLIENT_ID}:${CLIENT_SECRET} | base64` $ curl -i -X POST \ -H "Authorization: Basic ${AUTH_HEADER}" \ -H "Content-Type: application/x-www-form-urlencoded" \ https://auth.paas.crmstyle.com/oauth2/token \ -d "grant_type=client_credentials&scope=mail:send mail:result&audience=https://mail.paas.crmstyle.com" {"access_token": "","expires_in": 3599,"scope": "mail:send mail:result","token_type": "bearer"} |
レスポンスの JSON に含まれる access_token
の値がアクセストークンとなります。
クライアントコードの生成
メールAPI のインターフェースはウェブで公開されているので、openapi-generator-cli
を使用すればローカルにファイルをダウンロードすることなくクライアントコードの生成ができます。
今回は Java
のクライアントコードを生成してみます。
クライアントコードを作りたいディレクトリで下記のコマンドを実行します。
1 |
$ openapi-generator-cli generate -i https://form.synergy-marketing.co.jp/mailapi_v1/openapi3.yml -g java -o ./sample_client |
コマンドを実行すると、カレントディレクトリに sample_client
プロジェクトが生成されます。
生成されたプロジェクトにはメールAPI のクライアントクラスが定義されており、各 API へのリクエスト用のメソッドを持っています。
プロジェクトの README
にサンプルコードが記載されていたので、そのサンプルコードを使って API リクエストを送ってみます。
私が実行した時点 (2019/11/15 現在) でのサンプルコードは、下記のようなコードでした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// Import classes: import org.openapitools.client.ApiClient; import org.openapitools.client.ApiException; import org.openapitools.client.Configuration; import org.openapitools.client.auth.*; import org.openapitools.client.models.*; import org.openapitools.client.api.DefaultApi; public class Example { public static void main(String[] args) { ApiClient defaultClient = Configuration.getDefaultApiClient(); defaultClient.setBasePath("https://mail.paas.crmstyle.com/e"); // Configure OAuth2 access token for authorization: mail_oauth OAuth mail_oauth = (OAuth) defaultClient.getAuthentication("mail_oauth"); mail_oauth.setAccessToken("YOUR ACCESS TOKEN"); DefaultApi apiInstance = new DefaultApi(defaultClient); String user = "user_example"; // String | user name Long taskId = 56L; // Long | delivery task id try { File result = apiInstance.getDeliveryMailClickResults(user, taskId); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling DefaultApi#getDeliveryMailClickResults"); System.err.println("Status code: " + e.getCode()); System.err.println("Reason: " + e.getResponseBody()); System.err.println("Response headers: " + e.getResponseHeaders()); e.printStackTrace(); } } } |
メール配信
まずはじめにメールを配信してみます。
メールAPI のドキュメントに記載されたサンプルと同じ設定でメールを配信してみます。
今回実際に配信してみたコードです。メールアドレスや URL は に置き換えておりますので、適宜補ってください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
package org.openapitools; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.openapitools.client.ApiClient; import org.openapitools.client.ApiException; import org.openapitools.client.Configuration; import org.openapitools.client.api.DefaultApi; import org.openapitools.client.auth.OAuth; import org.openapitools.client.model.DeliveryRequest; import org.openapitools.client.model.DeliveryRequest.EncodeEnum; import org.openapitools.client.model.DeliveryResponse; public class ExampleClient { public static void main(String[] args) { ApiClient defaultClient = Configuration.getDefaultApiClient(); defaultClient.setBasePath("https://mail.paas.crmstyle.com/e"); // Configure OAuth2 access token for authorization: mail_oauth OAuth mail_oauth = (OAuth) defaultClient.getAuthentication("mail_oauth"); String mailApiAccessToken = System.getenv("MAIL_API_ACCESS_TOKEN"); mail_oauth.setAccessToken(mailApiAccessToken); DefaultApi apiInstance = new DefaultApi(defaultClient); String user = System.getenv("MAIL_API_USER"); List<Map<String, String>> deliveryData = new ArrayList<>(); deliveryData.add(new HashMap<String, String>() { {put("Customer.synergyid", "1");} {put("Customer.mailaddress", "");} {put("Customer.name", "山田");} }); deliveryData.add(new HashMap<String, String>() { {put("Customer.synergyid", "2");} {put("Customer.mailaddress", "");} {put("Customer.name", "佐藤");} }); DeliveryRequest deliveryRequest = new DeliveryRequest() .test(false) .encode(EncodeEnum.UTF_8) .fromAddress("") .fromName("カスタマーサポート") .replyAddress("") .subject("こんにちは($db.Customer.name$)さん") .count(2) .deliveryMailAddressPropertyName("Customer.mailaddress") .bodyText("お問い合わせは次のURLから ") .bodyHtml("お問い合わせは次のURLから<a href="<xxxxxxxxxx>">フォーム</a>") .deliveryData(deliveryData); try { DeliveryResponse response = apiInstance.startMailDelivery(user, deliveryRequest); System.out.println(response.toString()); } catch (Exception e) { e.printStackTrace(); } } } |
差出人のメールアドレスや配信内容などの必須項目の他にも、差出人の名前や返信先のアドレスなども設定できます。
サンプルコードでは使用していない項目もありますので、詳細はドキュメントをご覧ください。
メールAPI の使用時に必要なユーザ名とアクセストークンは環境変数を使って渡すようにしています。
bodyText
と bodyHtml
はメール本文を設定する項目です。少なくとも 1 つは必須となります。
URL を挿入する際に、特定のフォーマットで挿入すればクリックフィードバックを取得できます。
今回の例では、HTML メールのリンクにクリックフィードバックを設定しております。詳細はメールAPI のドキュメントをご覧ください。
配信対象のリスト ( deliveryData
サンプルコートの 30 ~ 40 行目) にはキーバリューのリストを渡します。
各配信対象を特定するための Customer.synergyid
は必須項目です。配信結果を取得した際にメールを開封した人や配信エラーで送れなかった人などを特定する際に使います。
配信するメールアドレスは、deliveryMailAddressPropertyName
にて指定した項目になります。今回の場合は Customer.mailaddress
を指定しています。この項目も必須です。
それ以外の項目は任意の項目ですが、Customer.
から始まる項目を使うことでメールのタイトルや本文に埋め込むことができます。
例えば今回の場合だと、Cutomer.name
をメールのタイトルに埋め込んでいます。
実行
openapi-generator-cli
で生成されたプロジェクトには gradle
や maven
の設定ファイルが用意されています。
先程作成した ExampleClient
を sample_client/main/java/org/openapitools/ExampleClient.java
として配置し、gradle
を使って実行可能な jar
ファイルを作りましょう。
build.gradle
に下記の設定を追記して、ビルドすれば build
ディレクトリ以下に作成されるはずです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
group = 'org.openapitools' version = '1.0.0' // 追記ここから jar { manifest { attributes 'Main-Class': 'org.openapitools.ExampleClient' } from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } } // 追記ここまで |
設定を追記した状態で ./gradlew build
を実行して実行可能な jar
ファイルを作成します。
1 2 |
$ cd sample_client $ ./gradlew build |
無事 build/libs/openapi-java-client-1.0.0.jar
が作成されました。
作成した jar
ファイルを実行してみます。
正常に配信されれば、配信の ID である deliveryTaskId
と配信内容から抽出されたクリックフィードバックの情報が返されます。
1 2 3 4 5 6 7 8 9 |
$ java -jar build/libs/openapi-java-client-1.0.0.jar class DeliveryResponse { deliveryTaskId: 1 textClickFeedbacks: null htmlClickFeedbacks: [class ClickFeedback { id: 1 url: }] } |
この deliveryTaskId
を使って、配信したメールの開封数やクリック数を取得したり、配信に失敗した配信対象とエラー内容を取得したりできます。
配信結果取得
先程実行した API のレスポンスに含まれている deliveryTaskId
を使用して、先程の配信の配信結果を取得してみます。
ExampleClient
を配信の開封数を取得するように修正します。
今回は deliveryTaskId
を実行時の引数に取るようにしました。
今回実際に結果を取得してみたコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
package org.openapitools; import java.io.File; import java.nio.file.Files; import java.security.MessageDigest; import javax.xml.bind.DatatypeConverter; import org.openapitools.client.ApiClient; import org.openapitools.client.ApiResponse; import org.openapitools.client.Configuration; import org.openapitools.client.api.DefaultApi; import org.openapitools.client.auth.OAuth; public class ExampleClient { public static void main(String[] args) { ApiClient defaultClient = Configuration.getDefaultApiClient(); defaultClient.setBasePath("https://mail.paas.crmstyle.com/e"); // Configure OAuth2 access token for authorization: mail_oauth OAuth mail_oauth = (OAuth) defaultClient.getAuthentication("mail_oauth"); String mailApiAccessToken = System.getenv("MAIL_API_ACCESS_TOKEN"); mail_oauth.setAccessToken(mailApiAccessToken); DefaultApi apiInstance = new DefaultApi(defaultClient); String user = System.getenv("MAIL_API_USER"); Long deliveryTaskId = Long.valueOf(args[0]); try { ApiResponse result = apiInstance.getDeliveryMailOpenResultsWithHttpInfo(user, deliveryTaskId); String md5checksum = result.getHeaders().get("Content-MD5").get(0); File responseCsv = result.getData(); byte[] content = Files.readAllBytes(responseCsv.toPath()); MessageDigest md = MessageDigest.getInstance("MD5"); md.update(content); byte[] digest = md.digest(); if (DatatypeConverter.printBase64Binary(digest).toUpperCase().equals(md5checksum.toUpperCase())) { System.out.println(new String(content)); } else { System.err.println("Message Digest does not much!!"); System.exit(1); } } catch (Exception e) { e.printStackTrace(); } } } |
配信結果を取得する API は 3 つ用意されており、開封数、クリック数、配信エラー数が取得できます。
openapi-generator-cli
にて生成したコードでは、それぞれの API 呼び出しについて複数のメソッドが用意されています。
最も単純なメソッドだと、API のレスポンスである CSV ファイルを返り値として返します(例:開封数の取得であれば getDeliveryMailOpenResult
)。
ただ、このメソッドはなるべく呼ばないようにします。
というのも、メールAPI のドキュメントにもあるように配信結果の取得時はレスポンスの CSV が正常に取得できているかチェックする必要があるのですが、このメソッドの返りではチェックができないからです。
メールAPI ではレスポンスデータの整合性チェックを推奨していますが、これはネットワークトラブルなどにより、API のレスポンスとして取得した CSV が不完全な場合があるためです。
データの整合性をチェックするためには、API のレスポンスヘッダに含まれる Content-MD5
の値を使用します。
そのため、API の呼び出しにはレスポンスヘッダが返り値に含まれるメソッドを使用します(例:開封数の取得であれば getDeliveryMailOpenResultWithHttpInfo
)。
Content-MD5
にチェックサム値を Base64 エンコードしたものが含まれていますので、レスポンスのファイルのチェックサム値と比較します(サンプルコートの 36 ~ 40 行目)。
今回のサンプルのように配信対象が 2, 3 人ぐらいの少人数である場合、開封数やクリック数も 10 件ほどに収まる可能性が高いです。
しかしながら、100 万人を対象にした配信を行う場合は、たとえ開封率が 1% だったとしても開封数のデータが 1 万件になってしまいます。
配信数が多くなれば多くなるほど、レスポンスデータの整合性のチェックが重要になりますので注意してください。
実行
修正した内容で再び jar
ファイルをビルド、実行してみます。
1 2 3 4 5 6 |
$ cd sample_client $ ./gradlew build $ java -jar build/libs/openapi-java-client-1.0.0.jar "Synergy!ID","開封日時" "2","2019-11-15 10:34:57" "1","2019-11-15 10:31:36" |
API のレスポンスである CSV ファイルの中身が表示されました。
Synergy!ID
の値が配信時に付与した Customer.synergyid
になります。
おわりに
今回は Synergy! メールAPI を自動生成したクライアントコードから利用してみました。
実際の業務で使用する場合は、データベースや CSV から配信対象を生成することになるかと思いますが、
それ以外のコードは openapi-generator-cli
で自動生成したコードを利用すれば簡単にメール配信が行えるかと思います。
メールAPI を使えば Synergy! の基盤を利用して手軽にメール配信が行えますので、興味のある方は下記のサイトもご覧いただければと思います。