简体   繁体   中英

Strapi - Sendgrid send emails

I'm building an app in NextJS and Strapi I have Strapi Version: │ 3.0.1 (node v10.16.2).

I'm using Sendgrid to send emails, but I'm having a lot of trouble getting the back end connected to my form and then the emails to send.

I feel like I'm close but I'm missing something.

Here is my file structure for my email type: email file structure

plugin:

module.exports = ({ env }) => ({  
email: {    
provider: 'sendgrid',    
providerOptions: {      
apiKey: env('SENDGRID_API_KEY'),    
},    
settings: {      
defaultFrom: env('SENDGRID_DEFAULT_FROM'),      
defaultReplyTo: env('SENDGRID_DEFAULT_REPLY_TO'),    },  },})

controller:

module.exports = {

  send: async (ctx) => {
    let options = ctx.request.body;

    try {
      //Send email to the user
      await strapi.plugins['email'].services.email.send({
        to: options.to,
        from: 'info@example.com',
        subject: options.subject,
        html: options.html
      });
      ctx.send({ok: true})
    } catch (err) {
      return ctx.badRequest(null, err);
      
    }
    
  }
}

services:

module.exports = {  
sendEmail: async (to, subject, html) => {    
strapi.log.info("services.email.sendEmail Sending email")    
strapi.plugins['email'].services.email.send({      
to,      
from: DEFAULT_FROM,      
replyTo: DEFAULT_REPLY_TO,      
subject,      
text,      
html,    
});    
strapi.log.info("services.email.sendEmail Email sent")    
return {message: 'Email Sent'}  }};

routes:

{  "routes": [{      
"method": "POST",      
"path": "/email-send",      
"handler": "email.send",      
"config": {        
"policies": []      
}    
}]}

My form:


import React, { useState } from 'react';

export default function corporate() {

return (

<form>
        <h3>Complete the form below.</h3>
        {/* <input type="text" id="name" class="fadeIn first" name="name" placeholder="First and Last Name"> */}
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>First Name**</p>
        <input type="text" id="name" className="fadeIn first" name="name" placeholder="Full Name" />
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Email**</p>
        <input type="email" id="email" className="fadeIn second" name="email" placeholder="Email" />
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Phone Number</p>
        <input type="text" id="phone" className="fadeIn third" name="phone" placeholder="Phone Number" />
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Number of People</p>
        <input type="text" id="people" className="fadeIn third" name="people" placeholder="Number of People" />
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Rental Request Start Date</p>
        <input type="date" name="date" id="date" />
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Rental Request End Date</p>
        <input type="date" name="enddate" id="enddate" />
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Time Requested</p>
        <input type="time" id="time" name="time" />
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Recurring Rental?</p>
        <select name="repeat" className="custom-select" id="inlineFormCustomSelectPref" style={{width: '85%'}}>
          <option selected>Choose...</option>
          <option name="opt" value="One Time Rental">One Time Rental</option>
          <option name="opt" value="Daily">Daily</option>
          <option name="opt" value="Weekly">Weekly</option>
          <option name="opt" value="Monthly">Monthly</option>
        </select>
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Room Setup Required?</p>
        <select name="roomsetup" className="custom-select" id="inlineFormCustomSelectPref" style={{width: '85%'}}>
          <option selected>Choose...</option>
          <option name="opt" value="None">None</option>
          <option name="opt" value="Information table(s) only">Information table(s) only</option>
          <option name="opt" value="Breakfast/Lunch/Dinner buffet">Breakfast/Lunch/Dinner buffet</option>
          <option name="opt" value="Theatre style">Theatre style</option>
          <option name="opt" value="Board meeting">Board meeting</option>
          <option name="opt" value="Conference">Conference</option>
          <option name="opt" value="Trade Show">Trade Show</option>
        </select>
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Select a Space</p>
        <select name="selectopt" className="custom-select" id="inlineFormCustomSelectPref" style={{width: '85%'}}>
          <option selected>Choose...</option>
          <option name="opt" value="Rec Centre Gym only(225 person max)">Rec Centre Gym only (225 person max)</option>
          <option name="opt" value="Rec Centre Meeting Room (80 person max)">Rec Centre Meeting Room (80 person max)</option>
          <option name="opt" value="Rec Centre Upper Mezzanine">Rec Centre Upper Mezzanine</option>
          <option name="opt" value="Health Centre Meeting Room (50 person max)">Health Centre Meeting Room (50 person max)</option>
          <option name="opt" value="School Gym">School Gym</option>
        </select>
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Additional Details</p>
        <textarea name="content" className="fadeIn fourth" id="content" cols={95} rows={10} defaultValue={"\n        "} />
        <input type="submit" className="fadeIn fifth" defaultValue="Submit" />
      </form>
)
}

When I use postman to make a POST request, I do in fact receive an email to my inbox. So I feel I'm close! Postman request

I've been searching high and low and I'd appreciate so much if someone could help with this.

Much appreciated!

EDIT :

So I added the following code to my form page after the component name and before 'return' so it looks like this:

import React, { useState } from 'react';

export default function corporate() {

  const { API_URL } = process.env


const [state, setState] = useState({ name: '', to: '' });
    const handleChange = event => {
      const { name, value } = event.target;
      setState({
        ...state,
        [name]: value
      });
    }
    const handlePress = () => {
      fetch(`${API_URL}/email-send`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: state.name, to: state.to })
      });
    }

<form>
        <h3>Complete the form below.</h3>
       
        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>First Name**</p>

        <input type="text" id="name" className="fadeIn first" name="name" placeholder="Full Name" onChange={handleChange} />

        <p className="my-1" style={{textAlign: 'left', marginLeft: '10%'}}>Email**</p>
        <input type="email" id="to" className="fadeIn second" name="to" placeholder="Email" onChange={handleChange} />
        
        <input onClick={handlePress} type="submit" className="fadeIn fifth" defaultValue="Submit" />
      </form>
)
}

However now I'm getting the following error when submitting my form:

[2020-06-23T21:02:57.777Z] error Error: Bad Request
    at Request.http [as _callback] (node_modules/@sendgrid/client/src/classes/client.js:124:25)
    at Request.self.callback (node_modules/request/request.js:185:22)
    at Request.emit (events.js:198:13)
    at Request.<anonymous> (node_modules/request/request.js:1154:10)
    at Request.emit (events.js:198:13)
    at IncomingMessage.<anonymous> (node_modules/request/request.js:1076:12)
    at Object.onceWrapper (events.js:286:20)
    at IncomingMessage.emit (events.js:203:15)
    at endReadableNT (_stream_readable.js:1145:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
[2020-06-23T21:02:57.777Z] debug POST /email (452 ms) 500

You created a route named /email-send in your backend. And it's this route that send the email.

BUT in your frontend application - you are calling /send.

So I think you have to update the route you are calling in your frontend application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM