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()
を書かなくて良いので、そちらを用いています。