Skip to content

Commit

Permalink
3 send email (#5)
Browse files Browse the repository at this point in the history
* add schotsl/mailgun

* remove pragma

* fmt

* check response

* info@mg.swanfactory.online

* exclude node_modules

* only build manifest?

---------

Co-authored-by: Dr. Ernie Prabhakar <19791+drernie@users.noreply.github.com>
  • Loading branch information
drernie and drernie authored Jan 27, 2025
1 parent 3f1ec5e commit 34c0426
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 6 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ jobs:
with:
deno-version: v2.x

- name: Build step
run: "deno task build"
- name: Build manifest
run: "deno task manifest"

- name: Upload to Deno Deploy
uses: denoland/deployctl@v1
Expand Down
6 changes: 4 additions & 2 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
"lock": false,
"tasks": {
"t": "deno test --allow-read --unstable-kv --coverage=cov/ --trace-leaks",
"check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx",
"cli": "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable -A -",
"check": "deno fmt && deno lint && deno check **/*.ts -- --exclude node_modules && deno check **/*.tsx ",

"cli": "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable-kv -A -",
"manifest": "deno task cli manifest $(pwd)",
"start": "deno run -A --unstable-kv --watch=static/,routes/ dev.ts",
"build": "deno run -A dev.ts build",
Expand All @@ -23,6 +24,7 @@
],
"imports": {
"$fresh/": "https://deno.land/x/fresh@1.7.3/",
"@schotsl/mailgun": "jsr:@schotsl/mailgun@^1.3.0",
"@std/assert": "jsr:@std/assert@^1.0.8",
"@std/testing": "jsr:@std/testing@^1.0.5",
"preact": "https://esm.sh/preact@10.22.0",
Expand Down
8 changes: 6 additions & 2 deletions fresh.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@

import * as $_404 from "./routes/_404.tsx";
import * as $_app from "./routes/_app.tsx";
import * as $api_send_email from "./routes/api/send-email.ts";
import * as $index from "./routes/index.tsx";

import * as $EmailButton from "./islands/EmailButton.tsx";
import type { Manifest } from "$fresh/server.ts";

const manifest = {
routes: {
"./routes/_404.tsx": $_404,
"./routes/_app.tsx": $_app,
"./routes/api/send-email.ts": $api_send_email,
"./routes/index.tsx": $index,
},
islands: {},
islands: {
"./islands/EmailButton.tsx": $EmailButton,
},
baseUrl: import.meta.url,
} satisfies Manifest;

Expand Down
41 changes: 41 additions & 0 deletions islands/EmailButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useState } from "preact/hooks";

export default function SendEmailButton() {
const [status, setStatus] = useState<string | null>(null);

const handleClick = async () => {
setStatus("Sending...");
try {
const response = await fetch("/api/send-email", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
to: "ernest@drernie.com",
subject: "Hello from Deno Fresh",
text: "This is a test email sent from a Deno Fresh application.",
}),
});

if (response.ok) {
setStatus("Email sent successfully!");
} else {
setStatus("Failed to send email.");
}
} catch (error) {
console.error("Error sending email:", error);
setStatus("An error occurred.");
}
};

return (
<div>
<button
onClick={handleClick}
class="px-4 py-2 bg-blue-500 text-white rounded"
>
Send Email
</button>
{status && <p>{status}</p>}
</div>
);
}
14 changes: 14 additions & 0 deletions routes/api/send-email.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Handlers } from "$fresh/server.ts";
import { sendEmail } from "../../utils/mail.ts";

export const handler: Handlers = {
async POST(req) {
const { to, subject, text } = await req.json();
const status = await sendEmail(to, subject, text);
if (status < 300) {
return new Response("Email sent successfully", { status: status });
} else {
return new Response("Failed to send email", { status: status });
}
},
};
6 changes: 6 additions & 0 deletions routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import SendEmailButton from "../islands/EmailButton.tsx";

export default function Home() {
return (
<div>
Expand Down Expand Up @@ -26,6 +28,10 @@ export default function Home() {
>
Read the Polygogy Manyfesto
</a>
<div class="p-4 mx-auto max-w-screen-md">
<h3 class="text-2xl font-bold">Testing Email</h3>
<SendEmailButton />
</div>
<p className="text-lg text-gray-750">
Coming soon: subscribe to our mailing list.
</p>
Expand Down
40 changes: 40 additions & 0 deletions utils/mail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Mailgun from "@schotsl/mailgun";

const apiKey = Deno.env.get("MAILGUN_API_KEY");
const domain = Deno.env.get("MAILGUN_DOMAIN");

if (!apiKey || !domain) {
throw new Error(
"MAILGUN_API_KEY and MAILGUN_DOMAIN environment variables must be set",
);
}

console.log("Mailgun API key:", apiKey);
console.log("Mailgun domain:", domain);

const mailgun = new Mailgun({
key: apiKey,
domain: domain,
region: "us", // or "eu" based on your Mailgun account
});

console.log("Mailgun client:", mailgun);

export async function sendEmail(
to: string,
subject: string,
text: string,
from: string = "info@mg.swanfactory.online",
) {
console.log(`Sending email to ${to}...`);
const response = await mailgun.send({ to, from, subject, text });
if (response.ok) {
console.log(`Email sent to ${to}`, response);
} else {
console.error(
`Error[${response.status}]: ${response.statusText}`,
response,
);
}
return response.status;
}

0 comments on commit 34c0426

Please sign in to comment.