Merge pull request #2502 from appwrite/feat-resend-adapter

This commit is contained in:
Darshan
2025-10-25 19:20:05 +05:30
committed by GitHub
17 changed files with 158 additions and 25 deletions
+1 -1
View File
@@ -22,7 +22,7 @@
},
"dependencies": {
"@ai-sdk/svelte": "^1.1.24",
"@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@3996505",
"@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e",
"@appwrite.io/pink-icons": "0.25.0",
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@50b60cc",
"@appwrite.io/pink-legacy": "^1.0.3",
+22 -22
View File
@@ -12,8 +12,8 @@ importers:
specifier: ^1.1.24
version: 1.1.24(svelte@5.25.3)(zod@3.24.3)
'@appwrite.io/console':
specifier: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@3996505
version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@3996505
specifier: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e
version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e
'@appwrite.io/pink-icons':
specifier: 0.25.0
version: 0.25.0
@@ -260,8 +260,8 @@ packages:
'@analytics/type-utils@0.6.2':
resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==}
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@3996505':
resolution: {tarball: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@3996505}
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e':
resolution: {tarball: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e}
version: 1.10.0
'@appwrite.io/pink-icons-svelte@2.0.0-RC.1':
@@ -335,8 +335,8 @@ packages:
resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-identifier@7.27.1':
resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
'@babel/helper-validator-identifier@7.28.5':
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-option@7.25.9':
@@ -352,8 +352,8 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
'@babel/parser@7.28.4':
resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==}
'@babel/parser@7.28.5':
resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==}
engines: {node: '>=6.0.0'}
hasBin: true
@@ -373,8 +373,8 @@ packages:
resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==}
engines: {node: '>=6.9.0'}
'@babel/types@7.28.4':
resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==}
'@babel/types@7.28.5':
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
engines: {node: '>=6.9.0'}
'@csstools/color-helpers@5.0.2':
@@ -2607,8 +2607,8 @@ packages:
magic-string@0.30.18:
resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==}
magic-string@0.30.19:
resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==}
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
magic-string@0.30.7:
resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==}
@@ -3703,7 +3703,7 @@ snapshots:
'@analytics/type-utils@0.6.2': {}
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@3996505': {}
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e': {}
'@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)':
dependencies:
@@ -3812,7 +3812,7 @@ snapshots:
'@babel/helper-validator-identifier@7.25.9': {}
'@babel/helper-validator-identifier@7.27.1': {}
'@babel/helper-validator-identifier@7.28.5': {}
'@babel/helper-validator-option@7.25.9': {}
@@ -3825,9 +3825,9 @@ snapshots:
dependencies:
'@babel/types': 7.27.0
'@babel/parser@7.28.4':
'@babel/parser@7.28.5':
dependencies:
'@babel/types': 7.28.4
'@babel/types': 7.28.5
'@babel/runtime@7.27.0':
dependencies:
@@ -3856,10 +3856,10 @@ snapshots:
'@babel/helper-string-parser': 7.25.9
'@babel/helper-validator-identifier': 7.25.9
'@babel/types@7.28.4':
'@babel/types@7.28.5':
dependencies:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
'@csstools/color-helpers@5.0.2': {}
@@ -5124,7 +5124,7 @@ snapshots:
'@vue/compiler-core@3.5.13':
dependencies:
'@babel/parser': 7.28.4
'@babel/parser': 7.28.5
'@vue/shared': 3.5.13
entities: 4.5.0
estree-walker: 2.0.2
@@ -5137,13 +5137,13 @@ snapshots:
'@vue/compiler-sfc@3.5.13':
dependencies:
'@babel/parser': 7.28.4
'@babel/parser': 7.28.5
'@vue/compiler-core': 3.5.13
'@vue/compiler-dom': 3.5.13
'@vue/compiler-ssr': 3.5.13
'@vue/shared': 3.5.13
estree-walker: 2.0.2
magic-string: 0.30.19
magic-string: 0.30.21
postcss: 8.5.6
source-map-js: 1.2.1
@@ -6285,7 +6285,7 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
magic-string@0.30.19:
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -1,6 +1,7 @@
<script lang="ts">
import Button from '$lib/elements/forms/button.svelte';
import type { Models } from '@appwrite.io/console';
import { ExecutionStatus } from '@appwrite.io/console';
import { IconChevronDown, IconChevronUp } from '@appwrite.io/pink-icons-svelte';
import { calculateTime } from '$lib/helpers/timeConversion';
import {
@@ -112,7 +113,7 @@
<Tooltip
disabled={!selectedLog?.scheduledAt ||
selectedLog.status !== 'scheduled'}
selectedLog.status !== ExecutionStatus.Scheduled}
maxWidth="400px">
<div>
<Status
@@ -3,6 +3,7 @@
import { toLocaleDateTime } from '$lib/helpers/date';
import type { Column } from '$lib/helpers/types';
import type { Models } from '@appwrite.io/console';
import { ExecutionStatus } from '@appwrite.io/console';
import {
Badge,
FloatingActionBar,
@@ -109,7 +110,7 @@
{:else if column.id === 'status'}
{@const status = log.status}
<Tooltip
disabled={!log?.scheduledAt || status !== 'scheduled'}
disabled={!log?.scheduledAt || status !== ExecutionStatus.Scheduled}
maxWidth="400px">
<div>
<Status
@@ -7,6 +7,7 @@
Vonage = 'vonage',
Mailgun = 'mailgun',
Sendgrid = 'sendgrid',
Resend = 'resend',
SMTP = 'smtp',
FCM = 'fcm',
APNS = 'apns'
@@ -31,6 +32,9 @@
case Providers.Mailgun:
icon = 'mailgun';
break;
case Providers.Resend:
icon = 'resend';
break;
case Providers.SMTP:
icon = 'smtp';
displayName = 'SMTP';
@@ -2,6 +2,7 @@ export { default as IconApple } from './apple.svelte';
export { default as IconFirebase } from './firebase.svelte';
export { default as IconMailgun } from './mailgun.svelte';
export { default as IconSendgrid } from './sendgrid.svelte';
export { default as IconResend } from './resend.svelte';
export { default as IconTwilio } from './twilio.svelte';
export { default as IconMsg91 } from './msg91.svelte';
export { default as IconTelesign } from './telesign.svelte';
@@ -0,0 +1,5 @@
<script lang="ts">
import { SvgIcon } from '$lib/components';
</script>
<SvgIcon name="resend" type="color" />
@@ -118,6 +118,20 @@
enabled: $providerParams[$provider].enabled
});
break;
case Providers.Resend:
response = await sdk
.forProject(page.params.region, page.params.project)
.messaging.createResendProvider({
providerId,
name: $providerParams[$provider].name,
apiKey: $providerParams[$provider].apiKey,
fromName: $providerParams[$provider].fromName || undefined,
fromEmail: $providerParams[$provider].fromEmail,
replyToName: $providerParams[$provider].replyToName || undefined,
replyToEmail: $providerParams[$provider].replyToEmail || undefined,
enabled: $providerParams[$provider].enabled
});
break;
case Providers.SMTP:
response = await sdk
.forProject(page.params.region, page.params.project)
@@ -99,6 +99,18 @@
replyToName: $providerData.options['replyToName']
};
break;
case Providers.Resend:
params = {
providerId: $providerData.$id,
name: $providerData.name,
enabled: $providerData.enabled,
apiKey: $providerData.credentials['apiKey'],
fromEmail: $providerData.options['fromEmail'],
fromName: $providerData.options['fromName'],
replyToEmail: $providerData.options['replyToEmail'],
replyToName: $providerData.options['replyToName']
};
break;
case Providers.SMTP:
params = {
providerId: $providerData.$id,
@@ -158,6 +158,18 @@
replyToEmail: formValues['replyToEmail'] || undefined
});
break;
case Providers.Resend:
response = await sdk
.forProject(page.params.region, page.params.project)
.messaging.updateResendProvider({
providerId,
apiKey: formValues['apiKey'],
fromName: formValues['fromName'] || undefined,
fromEmail: formValues['fromEmail'],
replyToName: formValues['replyToName'] || undefined,
replyToEmail: formValues['replyToEmail'] || undefined
});
break;
case Providers.SMTP:
response = await sdk
.forProject(page.params.region, page.params.project)
@@ -19,6 +19,7 @@
VonageProviderParams,
MailgunProviderParams,
SendgridProviderParams,
ResendProviderParams,
SMTPProviderParams,
FCMProviderParams,
APNSProviderParams
@@ -39,6 +40,7 @@
| VonageProviderParams
| MailgunProviderParams
| SendgridProviderParams
| ResendProviderParams
| SMTPProviderParams
| FCMProviderParams
| APNSProviderParams
@@ -9,6 +9,7 @@
VonageProviderParams,
MailgunProviderParams,
SendgridProviderParams,
ResendProviderParams,
SMTPProviderParams,
FCMProviderParams,
APNSProviderParams
@@ -24,6 +25,7 @@
| VonageProviderParams
| MailgunProviderParams
| SendgridProviderParams
| ResendProviderParams
| SMTPProviderParams
| FCMProviderParams
| APNSProviderParams
@@ -10,6 +10,7 @@ import {
IconFirebase,
IconMailgun,
IconMsg91,
IconResend,
IconSendgrid,
IconTelesign,
IconTextMagic,
@@ -318,6 +319,55 @@ export const providers: ProvidersMap = {
]
]
},
[Providers.Resend]: {
imageIcon: IconResend,
title: 'Resend',
description: '',
configure: [
{
label: 'API key',
name: 'apiKey',
type: 'password',
placeholder: 'Enter API key',
popover: [
'<b>How to get the API key?</b>',
'Create an account in <a class="link" href="https://resend.com/signup" target="_blank" rel="noopener noreferrer">Resend</a>.',
'Head to <b>API Keys -> Create API Key.</b>'
]
},
[
{
label: 'Sender email',
name: 'fromEmail',
type: 'email',
placeholder: 'Enter email'
},
{
label: 'Sender name',
name: 'fromName',
type: 'text',
optional: true,
placeholder: 'Enter name'
}
],
[
{
label: 'Reply-to email',
name: 'replyToEmail',
type: 'email',
optional: true,
placeholder: 'Enter email'
},
{
label: 'Reply-to name',
name: 'replyToName',
type: 'text',
optional: true,
placeholder: 'Enter name'
}
]
]
},
[Providers.SMTP]: {
classIcon: IconMail,
title: 'SMTP',
@@ -655,6 +705,14 @@ export type SendgridProviderParams = ProviderParams & {
apiKey: string;
};
export type ResendProviderParams = ProviderParams & {
fromEmail: string;
fromName: string;
replyToEmail: string;
replyToName: string;
apiKey: string;
};
export type SMTPProviderParams = ProviderParams & {
fromEmail: string;
fromName: string;
@@ -99,6 +99,18 @@
replyToName: ''
};
break;
case Providers.Resend:
$providerParams[$provider] = {
providerId: id,
name: name,
enabled: true,
apiKey: '',
fromEmail: '',
fromName: '',
replyToEmail: '',
replyToName: ''
};
break;
case Providers.SMTP:
$providerParams[$provider] = {
providerId: id,
@@ -6,6 +6,7 @@ import type {
FCMProviderParams,
MailgunProviderParams,
Msg91ProviderParams,
ResendProviderParams,
SMTPProviderParams,
SendgridProviderParams,
TelesignProviderParams,
@@ -24,6 +25,7 @@ export const providerParams = writable<{
vonage: Partial<VonageProviderParams>;
mailgun: Partial<MailgunProviderParams>;
sendgrid: Partial<SendgridProviderParams>;
resend: Partial<ResendProviderParams>;
smtp: Partial<SMTPProviderParams>;
fcm: Partial<FCMProviderParams>;
apns: Partial<APNSProviderParams>;
@@ -35,6 +37,7 @@ export const providerParams = writable<{
vonage: null,
mailgun: null,
sendgrid: null,
resend: null,
smtp: null,
fcm: null,
apns: null
+3
View File
@@ -0,0 +1,3 @@
<svg width="1800" height="1800" viewBox="0 0 1800 1800" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1000.46 450C1174.77 450 1278.43 553.669 1278.43 691.282C1278.43 828.896 1174.77 932.563 1000.46 932.563H912.382L1350 1350H1040.82L707.794 1033.48C683.944 1011.47 672.936 985.781 672.935 963.765C672.935 932.572 694.959 905.049 737.161 893.122L908.712 847.244C973.85 829.812 1018.81 779.353 1018.81 713.298C1018.8 632.567 952.745 585.78 871.095 585.78H450V450H1000.46Z" fill="#FDFDFD"/>
</svg>

After

Width:  |  Height:  |  Size: 506 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="1800" height="1800" viewBox="0 0 1800 1800" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1000.46 450C1174.77 450 1278.43 553.669 1278.43 691.282C1278.43 828.896 1174.77 932.563 1000.46 932.563H912.382L1350 1350H1040.82L707.794 1033.48C683.944 1011.47 672.936 985.781 672.935 963.765C672.935 932.572 694.959 905.049 737.161 893.122L908.712 847.244C973.85 829.812 1018.81 779.353 1018.81 713.298C1018.8 632.567 952.745 585.78 871.095 585.78H450V450H1000.46Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 504 B