[SOLVED] sendgrid email verify and password reset in self host server

Hello, I have a question about sendgrid to send emails through the cloud, I canโ€™t find documentation on this part, if you could help me or guide me please, I have the server config like this:

// @ts-ignore
import ParseServer from 'parse-server';
import config from './config';
import MoralisEthAdapter from './auth/MoralisEthAdapter';
// @ts-ignore
import sendGridAdapter from 'parse-server-sendgrid-email-adapter';

export const parseServer = new ParseServer({
  databaseURI: config.DATABASE_URI,
  cloud: config.CLOUD_PATH,
  serverURL: config.SERVER_URL,
  publicServerURL: config.SERVER_URL,
  appName: config.APP_NAME,
  appId: config.APPLICATION_ID,
  masterKey: config.MASTER_KEY,
  auth: {
    moralisEth: {
      module: MoralisEthAdapter,
    },
  },
  verifyUserEmails: true,
  emailVerifyTokenValidityDuration: 2 * 60 * 60,
  emailAdapter: sendGridAdapter({
    apiKey: config.APPLICATION_ID, 
    from: '[email protected]', 
    passwordResetTemplate : 'd-1f96ec531f544a12b52038da41b25a5e', 
    verificationEmailTemplate : 'd-14b1c0d89ea648dd8335d500fc189471'
  })
}); 

and the clouds like this:

Parse.Cloud.define("sendWelcomeEmail", (request) => {

  const { user } = request;

  const email = user?.get('email');

Moralis.Cloud.sendEmail ====> this is an example of moralis, but i dont see actually example from parse-server

  Parse.Cloud.sendEmail({


    to: email,

    templateId: "d-84e646524eb54d64944182a456f4c0e0",

    dynamic_template_data: {

      name: request.params.name,

    },

  });

});

How is it the correct way since it gives me a type error, from what I see this was an option of only Moralis.Parse.sendEmail, so with the mentioned configuration how should the cloud be? Thank you very much for the help.

You could try to ignore the type error.
What line gives the error?

I already omitted type errors, now when trying config server:

// @ts-ignore

import ParseServer from 'parse-server';

import config from './config';

import MoralisEthAdapter from './auth/MoralisEthAdapter';

// @ts-ignore

import sendGridAdapter from 'parse-server-sendgrid-email-adapter';

export const parseServer = new ParseServer({

  databaseURI: config.DATABASE_URI,

  cloud: config.CLOUD_PATH,

  serverURL: config.SERVER_URL,

  publicServerURL: config.SERVER_URL,

  appName: config.APP_NAME,

  appId: config.APPLICATION_ID,

  masterKey: config.MASTER_KEY,

  auth: {

    moralisEth: {

      module: MoralisEthAdapter,

    },

  },

  verifyUserEmails: true,

  emailVerifyTokenValidityDuration: 2 * 60 * 60,

  emailAdapter: sendGridAdapter({

    apiKey: config.SENDGRID_MAIL_API_KEY,

    from: 'Koolinart <[email protected]>',

    passwordResetEmailTemplate: 'd-1f96ec531f544a12b52038da41b25a5e',

    verificationEmailTemplate: 'd-14b1c0d89ea648dd8335d500fc189471'

  })

});

an clouds:

I get an error on the server:

/* eslint-disable @typescript-eslint/no-unused-vars */

/* eslint-disable @typescript-eslint/no-explicit-any */

/* eslint-disable complexity */

import  Parse  from 'parse/node';

// @ts-ignore

import { AppCache } from 'parse-server/lib/cache';

import config from '../config';

const SendgridAdapter = AppCache.get(config.APPLICATION_ID).userController.adapter;

Parse.Cloud.define("sendWelcomeEmail", (request) => {

  const { user } = request;

  const email = user?.get('email');

  SendgridAdapter.sendEmail({

    // Hardcoded from https://temp-mail.org/

    to: email,

    templateId: "d-84e646524eb54d64944182a456f4c0e0",

    dynamic_template_data: {

      name: request.params.name,

    },

  });

});

Parse.Cloud.define("sendEmailToUser", (request) => {

  SendgridAdapter.sendEmail({

    to: '[email protected]',

    subject: "Fundamentals",

    html: "Pampamentally it does make sense https://youtu.be/xXrkgWDcd7c",

  });

});

Parse.Cloud.define('sendVerificationEmail', async (request) => {

  const { user } = request.params;

  try {

    await user.fetch();

    if (!user.get('emailVerified')) {

      await user.sendVerificationEmail();

    }

    return { success: true };

  } catch (error) {

    throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Failed to send verification email.');

  }

});

Parse.Cloud.define('requestPasswordReset', async (request) => {

  const { email } = request.params;

  try {

    await Parse.User.requestPasswordReset(email);

    return { success: true };

  } catch (error) {

    throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Failed to request password reset.');

  }

});

error:

Failed running cloud function sendVerificationEmail for user undefined with:
   Input: {"user":"[email protected]"}
   Error: {"message":"Failed to send verification email.","code":1} {"error":{"code":1,"message":"Faailed to send verification email."},"functionName ":"sendVerificationEmail","params":{"user":"[email protected]"}}
error: Failed to send verification email. {"code":1,"stack":"Error: Failed to send verification email.\n at theFunction (C:\\Users\\david\\Documents\\Programming\\react\\Koolinart\\backend\\ src\\cloud\\sendingEmails.ts:50:11)\n at C:\\Users\\david\\Documents\\Programming\\react\\Koolinart\\backend\\node_modules\\parse-server\\ src\\Routers\\FunctionsRouter.js:179:18\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"}

I understand that I must bring the cloud object for the user, but the error is that it does not send the mail, and how do I call the different templates from the cloud? For example, if I have a welcome template in sendgrid, how do I call that template? Should I modify the parse-server-sendgrid-email-adapter file and add more functions? Specifically and in summary, how do I do it with the server configuration? What do I publish to send the mail from a cloud when I call the cloud to verify the mail and to reset the password?

if i try this:

Parse.Cloud.define('sendVerificationEmail', async (request) => {
  const { originalEmail } = request.params;
  const User = Parse.Object.extend('_User'); 

  try {
    const query = new Parse.Query(User);
    query.equalTo('email', originalEmail);

    const userObject = await query.first({ useMasterKey: true });

    if (userObject && !userObject.get('emailVerified')) {
      await Parse.User.requestEmailVerification(originalEmail); 
      return { success: true };
    } 
      throw new Parse.Error(Parse.Error.INVALID_EMAIL_ADDRESS, 'Invalid email address or already verified.');
    
  } catch (error) {
    throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Failed to send verification email.');
  }
});

server give me this error:

error: Failed running cloud function sendVerificationEmail for user undefined with:
  Input: {"currentUser":"[email protected]"}
  Error: {"message":"Failed to send verification email.","code":1} {"error":{"code":1,"message":"Failed to send verification email."},"functionName":"sendVerificationEmail","params":{"currentUser":"[email protected]"}}
error: Failed to send verification email. {"code":1,"stack":"Error: Failed to send verification email.\n    at C:\\Users\\david\\Documents\\Programacion\\react\\Koolinart\\backend\\src\\cloud\\sendingEmails.ts:56:11\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)"}

if you remove this catch then you have more info from where is the error?

you could implement different cloud functions that you could call instead of the functions specific to a user

try to send a simple email in a cloud functions to see if it works

thanks cryptokid it worked for me, the error was a dashboard configuration.

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.