EmailJSの準備
以下を参考にアカウントを作成し、mail serviceとmail templateを設定します。
今回はemail_templateを
{{message}}
{{user_name}} ({{user_email}})
としています。
npmパッケージのインストール
npm create rescript-app@latest
cd emailjs-test
npm install --save-dev @emailjs/browser
ReScriptをインストールするときのプロジェクト名をemailjs-testにしたので、そのディレクトリに移動してからEmailJSをインストールします。
作成するファイル
<!DOCTYPE html>
<html>
<head>
<title>Contact Form</title>
</head>
<body>
<form id="contact-form">
<label> 名 前 </label>
<input id="user_name" type="text" name="user_name">
<br><br>
<label> メール </label>
<input id="user_email" type="email" name="user_email">
<br><br>
<label>メッセージ</label>
<textarea id="message" name="message"></textarea>
<br><br>
<input type="submit" value=" 送 信 ">
</form>
<script type="module" src="EmailJsTest.res.mjs"></script>
</body>
</html>
type publicKey = { publicKey: string }
type sendObject = {
user_name: string,
user_email: string,
message: string
}
@module("@emailjs/browser") external init: publicKey => unit = "init"
@module("@emailjs/browser") external send: (string, string, sendObject) => promise<'a> = "send"
@send external getElementById: (Dom.document, string) => Dom.element = "getElementById"
@send external addEventListener: (Dom.element, string, Dom.event => unit) => unit = "addEventListener"
@get external getValue: Dom.element => string = "value"
@send external preventDefault: Dom.event => unit = "preventDefault"
let onBtnClick = (event) => {
event->preventDefault
let user_name = document->getElementById("user_name")->getValue
let user_email = document->getElementById("user_email")->getValue
let message = document->getElementById("message")->getValue
let send_object = {
user_name: user_name,
user_email: user_email,
message: message
}
// these IDs from the previous steps
send("service_id", "template_id", send_object)
->Promise.thenResolve(() => { Console.log("SUCCESS!") })
->Promise.catch((error) => {
Console.log2("FAILED...", error)
Promise.resolve()
}
)->ignore
}
// https://dashboard.emailjs.com/admin/account
init({ publicKey: "YOUR_PUBLIC_KEY" });
document->getElementById("contact-form")->addEventListener("submit", onBtnClick)
emailjs-test/
└── src/
├── emailjs_test.html
└── EmailJsTest.res
ビルドして実行
npm run res:build
ブラウザで確認するとエラーが出ます
TypeError: Failed to resolve module specifier "@rescript/core/src/Core__Promise.res.mjs". Relative references must start with either "/", "./", or "../".Understand this error
モジュールが見つけられないようです。
Parcelでバンドル
npm install --save-dev parcel
npx parcel build src/EmailJsTest.res.mjs
emailjs-test/
├── dist/
│ ├── EmailJsTest.res.mjs
│ └── EmailJsTest.res.mjs.map
└── src/
├── emailjs_test.html
├── EmailJsTest.res
└── EmailJsTest.res.mjs
再実行
読み込むJSファイルを変更します。
<script type="module" src="../dist/EmailJsTest.res.js"></script>
下のようなページが表示され、入力して「送信」を押すとメールが送られます。
See the Pen Untitled by sgigagaeru (@sgigagaeru) on CodePen.
EmailJsTest.resでやっていること
@emailjs/browswerのバインド
@emailjs/browserのinitとsendを用いたので、それをバインドします。
initはObjectを引数に取って、unitを返します。
ここではObjectは{ publicKey: "YOUR_PUBLIC_KEY" }に決まっているので、それを型にしました。
type publicKey = { publicKey: string }
@module("@emailjs/browser") external init: publicKey => unit = "init"
sendは(string, string, Object)を引数にとって、promiseを返します。
Objectはここでは固定なので型にしました。
type sendObject = {
user_name: string,
user_email: string,
message: string
}
@module("@emailjs/browser") external send: (string, string, sendObject) => promise<'a> = "send"
onBtnClickの処理
「送信」ボタンが押されるとonBtnClickが呼び出されます。
まずデフォルトの処理を無効化します。これでページの遷移も防がれます。
event->preventDefault
インプットフォームの値を読み取って、送信するオブジェクトを作ります。
let user_name = document->getElementById("user_name")->getValue
let user_email = document->getElementById("user_email")->getValue
let message = document->getElementById("message")->getValue
let send_object = {
user_name: user_name,
user_email: user_email,
message: message
}
sendで送ります。
send("service_id", "template_id", send_object)
->Promise.thenResolve(() => { Console.log("SUCCESS!") })
->Promise.catch((error) => {
Console.log2("FAILED...", error)
Promise.resolve()
}
)->ignore
ReScriptのPromise.catchはcatch(promise, errorCallback)の形になります。そしてerrorCallbackはcatchの第一引数と同じ型のpromiseを返さないといけません。なので最後にPromise.resolve()を付けてpromiseを返しています。
Promise.thenも同様で、then(promise, callback)の形で、callbackはpromiseを返します。なのでcallbackの最後にPromise.resolve()を付けます。
thenResolveを用いると余計なPromise.resolve()を書かなくて良いので、そちらを用いています。