Skip to content

Commit 31bffb9

Browse files
committed
feat(email): Handle webhooks received from Resend
1 parent e7e0c35 commit 31bffb9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+11359
-8
lines changed

README.md

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
# Resend with Example
1+
# Resend with Symfony
22

3-
This example shows how to use Resend with [Example](https://example.com).
3+
This example shows how to use Resend with [Symfony](https://symfony.com).
4+
5+
> [!NOTE]
6+
> This application uses Symfony 7.1 RC1. It will be updated to the stable version once it's released.
47
58
## Prerequisites
69

@@ -11,20 +14,38 @@ To get the most out of this guide, you’ll need to:
1114

1215
## Instructions
1316

14-
1. Replace `re_123456789` on `example.ts` with your API key.
17+
1. Go to `./application` directory
18+
19+
2. Create a `.env.local` file and paste `MAILER_DSN=resend+api://API_KEY@default` then replace `API_KEY` with your API key.
1520

16-
2. Install dependencies:
21+
3. Install dependencies:
1722

1823
```sh
19-
TBD
24+
composer install
2025
```
2126

22-
3. Execute the following command:
27+
4. Start the server:
2328

2429
```sh
25-
TBD
30+
symfony serve -d
2631
```
2732

33+
5. Open your browser and go to `https://127.0.0.1:8000/`
34+
35+
6. Click on the button to send an email.
36+
37+
## Instruction for webhook
38+
39+
1. Expose your local server to the internet using [expose.dev](https://expose.dev).
40+
41+
2. Register your webhook URL (`{EXPOSE_URL}/webhook/mailer_resend`) in [Resend settings](https://resend.com/webhooks). Check the wanted events.
42+
43+
3. Paste `MAILER_RESEND_SECRET=SECRET_KEY` on `.env.local` and replace `SECRET_KEY` with your webhook signing secret you get after registering the webhook in Resend.
44+
45+
4. Click on the button to send an email.
46+
47+
5. Go to `https://127.0.0.1:8000/email-statuses` to see received events (stored in `var/emails.json`)
48+
2849
## License
2950

30-
MIT License
51+
MIT License

application/.env

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# In all environments, the following files are loaded if they exist,
2+
# the latter taking precedence over the former:
3+
#
4+
# * .env contains default values for the environment variables needed by the app
5+
# * .env.local uncommitted file with local overrides
6+
# * .env.$APP_ENV committed environment-specific defaults
7+
# * .env.$APP_ENV.local uncommitted environment-specific overrides
8+
#
9+
# Real environment variables win over .env files.
10+
#
11+
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
12+
# https://symfony.com/doc/current/configuration/secrets.html
13+
#
14+
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
15+
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
16+
17+
###> symfony/framework-bundle ###
18+
APP_ENV=dev
19+
APP_SECRET=a0afac6902adc3c7456d6b5535403dc6
20+
###< symfony/framework-bundle ###
21+
22+
###> doctrine/doctrine-bundle ###
23+
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
24+
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
25+
#
26+
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
27+
# DATABASE_URL="mysql://app:[email protected]:3306/app?serverVersion=8.0.32&charset=utf8mb4"
28+
# DATABASE_URL="mysql://app:[email protected]:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
29+
DATABASE_URL="postgresql://app:[email protected]:5432/app?serverVersion=16&charset=utf8"
30+
###< doctrine/doctrine-bundle ###
31+
32+
###> symfony/messenger ###
33+
# Choose one of the transports below
34+
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
35+
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
36+
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
37+
###< symfony/messenger ###
38+
39+
###> symfony/resend-mailer ###
40+
MAILER_DSN=resend+api://API_KEY@default
41+
###< symfony/resend-mailer ###
42+
43+
MAILER_RESEND_SECRET=SECRET_KEY

application/.env.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# define your env variables for the test env here
2+
KERNEL_CLASS='App\Kernel'
3+
APP_SECRET='$ecretf0rt3st'
4+
SYMFONY_DEPRECATIONS_HELPER=999999
5+
PANTHER_APP_ENV=panther
6+
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots

application/.gitignore

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
###> symfony/framework-bundle ###
3+
/.env.local
4+
/.env.local.php
5+
/.env.*.local
6+
/config/secrets/prod/prod.decrypt.private.php
7+
/public/bundles/
8+
/var/
9+
/vendor/
10+
###< symfony/framework-bundle ###
11+
12+
###> phpunit/phpunit ###
13+
/phpunit.xml
14+
.phpunit.result.cache
15+
###< phpunit/phpunit ###
16+
17+
###> symfony/phpunit-bridge ###
18+
.phpunit.result.cache
19+
/phpunit.xml
20+
###< symfony/phpunit-bridge ###
21+
22+
###> symfony/asset-mapper ###
23+
/public/assets/
24+
/assets/vendor/
25+
###< symfony/asset-mapper ###

application/assets/app.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import './bootstrap.js';
2+
/*
3+
* Welcome to your app's main JavaScript file!
4+
*
5+
* This file will be included onto the page via the importmap() Twig function,
6+
* which should already be in your base.html.twig.
7+
*/
8+
import './styles/app.css';
9+
10+
console.log('This log comes from assets/app.js - welcome to AssetMapper! 🎉');

application/assets/bootstrap.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { startStimulusApp } from '@symfony/stimulus-bundle';
2+
3+
const app = startStimulusApp();
4+
// register any custom, 3rd party controllers here
5+
// app.register('some_controller_name', SomeImportedController);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"controllers": {
3+
"@symfony/ux-turbo": {
4+
"turbo-core": {
5+
"enabled": true,
6+
"fetch": "eager"
7+
},
8+
"mercure-turbo-stream": {
9+
"enabled": false,
10+
"fetch": "eager"
11+
}
12+
}
13+
},
14+
"entrypoints": []
15+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Controller } from '@hotwired/stimulus';
2+
3+
/*
4+
* This is an example Stimulus controller!
5+
*
6+
* Any element with a data-controller="hello" attribute will cause
7+
* this controller to be executed. The name "hello" comes from the filename:
8+
* hello_controller.js -> "hello"
9+
*
10+
* Delete this file or adapt it for your use!
11+
*/
12+
export default class extends Controller {
13+
connect() {
14+
this.element.textContent = 'Hello Stimulus! Edit me in assets/controllers/hello_controller.js';
15+
}
16+
}

application/assets/styles/app.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
body {
2+
color: whitesmoke;
3+
background-color: black;
4+
}

application/bin/console

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
use App\Kernel;
5+
use Symfony\Bundle\FrameworkBundle\Console\Application;
6+
7+
if (!is_dir(dirname(__DIR__).'/vendor')) {
8+
throw new LogicException('Dependencies are missing. Try running "composer install".');
9+
}
10+
11+
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
12+
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
13+
}
14+
15+
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
16+
17+
return function (array $context) {
18+
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
19+
20+
return new Application($kernel);
21+
};

0 commit comments

Comments
 (0)