Add subscriber to my mailchimp subscriber list - node.js

I am new to backend web development and trying to create subscriber through a sign up page and add them to my Mailchimp through API but I am not been able to create subscriber (subscribers are not adding in my Mailchimp audience list). Below is my code.
const port = 3000;
const https = require('node:https');
const express = require('express');
const app = express();
app.use(express.static("public"));
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
extended: true
}));
app.get('/', (req, res) => {
res.sendFile(__dirname + "/signup.html")
});
app.post('/', (req, res) => {
const email = req.body.emailId;
const firstName = req.body.firstName;
const lastName = req.body.lastName;
var data = {
members: [{
email_address: email,
status: "Subscribed",
merge_fields: {
FNAME: firstName,
LNAME: lastName
}
}]
};
const jsonData = JSON.stringify(data);
const url = "https://us11.api.mailchimp.com/3.0/lists/"list_id"/";
const options = {
method: "POST",
auth: "dALamyan:apiKey"
};
const request = https.request(url, options, (response) => {
response.on("data", (data) => {
console.log(JSON.parse(data));
});
});
request.write(jsonData);
request.end;
});
app.listen(port, () => {
console.log("app listening on port 3000.");
});

You can try my code below. It's working fine for me.
Change X in the API endpoint, listID and apiKey as per your account settings.
Cheers.
const express = require("express");
const bodyParser = require("body-parser");
const request = require("request");
const https = require("https");
const app = express();
app.use(express.static("public"));
app.use(bodyParser.urlencoded({ extended: true }));
app.get("/", (req, res) => {
res.sendFile(__dirname + "/signup.html");
});
app.post("/", (req, res) => {
const firstName = req.body.firstname;
const lastName = req.body.lastname;
const email = req.body.email;
const data = {
members: [{
email_address: email,
status: "subscribed",
merge_fields: {
FNAME: firstName,
LNAME: lastName
}
}]
};
const jsonData = JSON.stringify(data);
const url = "https://usX.api.mailchimp.com/3.0/lists/" + listID;
const options = {
method: "POST",
auth: "archit:apiKey"
}
const request = https.request(url, options, (response) => {
response.on("data", (data) => {
console.log(JSON.parse(data));
});
});
request.write(jsonData);
request.end();
});
app.listen("3000", (req, res) => {
console.log("Server is running on port 3000.");
});

Related

XHR POST 404 error when using fetch api with NodeJS and Express

I am currently learning how to use the fetch api for my front-end. I continue to get the XHR 404 POST error.
//Backend file
const express = require("express");
const app = express();
require("dotenv");
const Port = process.env.PORT || 5000;
app.use(express.static("public"));
app.use(express.json());
app.use(
express.urlencoded({
extended: false,
})
);
const nodemailer = require("nodemailer");
const Mail = require("nodemailer/lib/mailer");
require("nodemailer-mailgun-transport");
app.use(express.json());
app.get("/", (req, res) => {
res.sendFile("/public");
res.sendFile("/public/js/mail.js");
});
app.listen(Port, (req, res) => {
console.log(`listening on port ${Port}`);
});
app.post("/email"),
(req, res) => {
FromMailjs = req.body;
console.log(FromMailjs);
const transporter = nodemailer.createTransport({
auth: {
user: process.env.Email,
pass: process.env.Pass,
},
});
const MailOptions = {
from: req.body.Email,
to: process.env.MyEmail,
text: `${req.body.FirstName}, ${req.body.LastName}
, ${req.body.PhoneNumber}, ${req.body.Email}`,
};
transporter.sendMail(MailOptions, (error, info) => {
if (error) {
console.log(error);
res.send("error");
} else {
console.log("Email sent");
res.send("success");
}
});
};
//Frontend file
const ContactForm = document.querySelector(".contact-form");
ContactForm.addEventListener("submit", (e) => {
e.preventDefault();
let FirstName = document.getElementById("Fname");
let LastName = document.getElementById("Lname");
let PhoneNumber = document.getElementById("PhoneNumber");
let Email = document.getElementById("Email");
const FormData = {
FirstName: FirstName.value,
LastName: LastName.value,
PhoneNumber: PhoneNumber.value,
Email: Email.value,
};
const PostOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(FormData),
};
console.log(FormData);
fetch("/email", PostOptions);
});
XHRPOSThttp://localhost:5000/email
[HTTP/1.1 404 Not Found 27ms]
I have tried changing the routes hoping that it was just a routing issue and I still get the same error. I was using XHR before fetch and I got the same 404 error. My front-end is receiving the correct information but I can't get my backend to receive the information.
You have a typo. Please use:
app.post("/email", (req, res) => {
Instead of:
app.post("/email"),
(req, res) => {

Mailchimp: The resource submitted could not be validated. For field-specific details, see the 'errors' array

Trying to add a member to a list but I keep getting this error: The resource submitted could not be validated. For field-specific details, see the 'errors' array.
Here is the complete output-
Server is running on port 3000
John Doe johndoe123#gmail.com
{
type: 'https://mailchimp.com/developer/marketing/docs/errors/',
title: 'Invalid Resource',
status: 400,
detail: "The resource submitted could not be validated. For field-specific details, see the 'errors' array.",
instance: 'd2186fc0-10d0-22af-ac4b-b04d7c6a61b7',
errors: [
{
field: 'email_address',
message: 'This value should not be blank.'
}
]
}
Here is the app.js file-
const express = require("express");
const app = express();
app.use(express.static("public"));
const mailchimp = require("#mailchimp/mailchimp_marketing");
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
const request = require("request");
const https = require("https");
const axios = require("axios");
const { response } = require("express");
const port = 3000;
app.get("/", (req, res) => {
res.sendFile(__dirname + "/signup.html");
mailchimp.setConfig({
apiKey: 'rupak:ec9e6dcf527*****8655da1b-us13',
server: "us13"
});
});
app.post("/", function(req, res){
const firstName = req.body.firstName;
const lastName = req.body.secondName;
const email = req.body.email;
console.log(firstName, lastName, email);
const data = {
members: [
{
email_address: email,
status: "subscribed",
merge_fields: {
FNAME: firstName,
LNAME: lastName
}
}
]
}
const jsonData = JSON.stringify(data);
let url = 'https://us13.api.mailchimp.com/3.0/lists/20b****bce/members' ;
const options = {
method: "POST",
auth: "rupak:ec9e6dcf527*****8655da1b-us13"
}
const request = https.request(url, options, (response) => {
response.on("data", (data) => {
console.log(JSON.parse(data));
})
})
request.write(jsonData);
request.end();
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
As far as I know, the email_address field is not empty since I have logged the output of email and I can see the email that I entered being displayed.
**** EDIT ****
I tried another method but now I get this long error message that I don't understand at all
Here's a very small part of it
Error: Bad Request
at Request.callback (C:\Users\Rupak\Desktop\Projects\Web Development\Newsletter-Signup\node_modules\superagent\lib\node\index.js:699:13)
at C:\Users\Rupak\Desktop\Projects\Web Development\Newsletter-Signup\node_modules\superagent\lib\node\index.js:903:18
at Stream.<anonymous> (C:\Users\Rupak\Desktop\Projects\Web Development\Newsletter-Signup\node_modules\superagent\lib\node\parsers\json.js:19:7)
at Stream.emit (node:events:390:28)
at Unzip.<anonymous> (C:\Users\Rupak\Desktop\Projects\Web Development\Newsletter-Signup\node_modules\superagent\lib\node\unzip.js:55:12)
at Unzip.emit (node:events:390:28)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
And here's the updates app.js file
//jshint esversion: 6
const express = require('express');
const bodyParser = require('body-parser');
const mailchimp = require('#mailchimp/mailchimp_marketing');
const app = express();
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static("public"));
app.get("/", function(req, res) {
res.sendFile(__dirname + "/signup.html");
//setup mailchimp
mailchimp.setConfig({
apiKey: "ec9e6dcf527*****8655da1b-us13",
server: "us13"
})
});
app.post("/", function(req, res) {
var firstName = req.body.firstName;
var lastName = req.body.secondName;
var email = req.body.email;
console.log(`${firstName} ${lastName} ${email}`);
const run = async () => {
//testing if server is working fine
// const response = await mailchimp.ping.get();
// console.log(response);
//add member to list
const response = await mailchimp.lists.addListMember("20b****bce", {
email_address: req.body.email,
status: "subscribed",
merge_fields: {
FNAME: req.body.firstName,
LNAME: req.body.secondName
}
})
console.log(response);
}
run();
});
app.listen(3000, function() {
console.log("Server is running");
});
Any help would be appreciated
I think the problem is that you have a members array, while the api you are using is only accepting one member at a time. It will probably work if you change it to:
const data = {
email_address: email,
status: "subscribed",
merge_fields: {
FNAME: firstName,
LNAME: lastName
}
}
Also, I think you can simply your call by using the #mailchimp/mailchimp_marketing module the way you find in node.js example in the Mailchimp
documentation. And you are importing Axios, but you are using request for the call. That package seems to be deprecated.
Hope this helps.
I found the error. Apparently I can't do this directly
email_address: req.body.email,
status: "subscribed",
merge_fields: {
FNAME: req.body.firstName,
LNAME: req.body.secondName
}
I need to create an object of the user and store the values in it. Then I have to access the values from the object while adding a member to the list. Here's how I did it
email_address: subscribingUsers.email_address,
status: "subscribed",
merge_fields: {
FNAME: subscribingUsers.firstname,
LNAME: subscribingUsers.lastname,
}
I would appreciate it if someone told me why this is. Do we need a key-value pair while posting any data to the server? And if so, why doesn't it work by directly getting the values from the request?

Active Campaign - Newsletter using NodeJs

I am getting an error when submitting my newsletter app using NodeJs. I can't even add the dummy data. I am still learning and appreciate if you can send any reference for my concern.
Please see code below
const express = require("express");
const request = require("request");
const bodyParser = require("body-parser");
const https = require("https");
const path = require("path");
const sdk = require('api')('#activecampaign/v3#19qi536gl58csf5q');
const app = express();
const port = process.env.PORT || 3000;
//BodyParser MiddleWare
app.use(bodyParser.urlencoded({ extended:true}));
//Static Folder
app.use(express.static(path.join(__dirname, "public")));
//sending the signup.html file to the browser as soon as a request is made on localhost port#
app.get("/", (req,res)=>{
res.sendFile(__dirname + "/signup.html");
});
app.post("/", (req,res) => {
const firstName = req.body.fName;
const lastName = req.body.lName;
const email = req.body.email;
const baseUrl = "https://radmik1435080.api-us1.com/api/3/contacts";
const apiKey = "x";
const sdk = require('api')('#activecampaign/v3#19qi536gl58csf5q');
const data = sdk['create-a-new-contact']({
contact: {
email: 'johndoe#example.com',
firstName: 'John',
lastName: 'Doe',
phone: '7223224241',
fieldValues: [
{
field: '1',
value: 'The Value for First Field'
},
{field: '6', value: '2008-01-20'}
]
}
}, {
'Api-Token': 'x'
})
.then(res => console.log(res))
.catch(err => console.error(err));
});
app.post("/err", (req,res) => {
res.redirect("/");
})
app.listen(port, ()=>{
console.log(`Server running on port ${port} `);
});
This is the error message
https://pastebin.com/yAHk6Qsp
Thanks in advance.

keep getting 401 using request package

My code is not working, I can't figure out why and it keeps giving me a 401 meaning the API key is missing so I don't know how this is happening and I would like to figure out what my problem is on this piece of code?
const express = require("express");
const bodyParser = require("body-parser");
const request = require("request");
const app = express();
app.use(express.static("public"));
app.use(bodyParser.urlencoded({extended: true}));
app.get("/", function(req, res){
res.sendFile(__dirname + "/signup.html");
});
app.post("/", function(req, res){
var firstName = req.body.firstName;
var lastName = req.body.lastName;
var email = req.body.email;
var data = {
members: [
{
email_address: email,
status: "subscribed"
}
]
};
var jsonData = JSON.stringify(data);
var options = {
url: "https://us20.api.mailchimp.com/3.0/lists/listId"
method: "POST",
headers: {
"Authorization": "mkouk24 Api Key"
},
body: jsonData
};
request(options, function(error,response,body){
if (error) {
console.log(error);
} else {
console.log(response.statusCode);
}
});
});
app.listen(3000, function() {
console.log("Server is running on port 3000!");
});
First of all, according to the documentation, I think you need to use app.use(bodyParser.json()) in order to pass parameters in post request.
Second, you should generate an API token from MailChimp and add it here Authorization": "mkouk24 Api Key"
More on that on this link: https://mailchimp.com/help/about-api-keys/

Mongo/express cannot load route (Unexpected '<' in postman)

Been trying to get user user object by id from parameters, using User.findById and cannot access this route.
Postman response: Cannot GET /users/get/ with status 404 (not found) which is wierd.
Postman JSON response:
Unexpected '<'
Been using express-promise-router but also tried with default express.Router();
Here is my code:
routes/users.js
const express = require('express');
const router = require('express-promise-router')();
const passport = require('passport');
const router1 = express.Router();
require('../passport');
const { validateBody, schemas } = require('../helpers/routeHelpers');
const UsersController = require('../controllers/users');
const passportSignIn = passport.authenticate('local', { session: false });
const passportJWT = passport.authenticate('jwt', { session: false });
router.route('/signup')
.post(validateBody(schemas.authSchema), UsersController.signUp);
router.route('/signin')
.post(validateBody(schemas.authSchema), passportSignIn, UsersController.signIn);
router.route('/get/:id')
.get(UsersController.getUser);
router.route('/secret')
.get(passportJWT, UsersController.secret);
controllers/users
module.exports = router;
const JWT = require('jsonwebtoken');
const User = require('../models/user');
const { JWT_SECRET } = require('../configuration');
const signToken = (user) => {
return JWT.sign({
iss: 'CodeWorkr',
sub: user.id,
iat: new Date().getTime(), // current time
exp: new Date().setDate(new Date().getDate() + 1) // current time + 1 day ahead
}, JWT_SECRET);
};
module.exports = {
signUp: async (req, res) => {
const { email, password } = req.value.body;
// Check if there is a user with the same email
const foundUser = await User.findOne({ 'local.email': email });
if (foundUser) {
return res.status(403).json({ error: 'Email is already in use' });
}
// Create a new user
const newUser = new User({
method: 'local',
local: {
email: email,
password: password
}
});
await newUser.save();
// Generate the token
const token = signToken(newUser);
// Respond with token
return res.status(200).json({ token });
},
signIn: async (req, res) => {
// Generate token
const token = signToken(req.user);
res.status(200).json({ token });
},
getUser: async (req, res) => {
User.findById(req.params.id)
.then((user) => {
res.status(200).json({ user });
console.log('test');
});
},
secret: async (req, res) => {
console.log('I managed to get here!');
res.json({ secret: 'resource' });
}
};
server.js
const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const passport = require('passport');
const db = require('./configuration/config').mongoURI;
const dbTest = require('./configuration/config').mongoURITest;
mongoose.Promise = global.Promise;
if (process.env.NODE_ENV === 'test') {
mongoose.connect(dbTest, { useMongoClient: true });
} else {
mongoose.connect(db, { useMongoClient: true });
}
const app = express();
app.use(cors());
app.use(passport.initialize());
app.use(passport.session());
// Middlewares moved morgan into if for clear tests
if (!process.env.NODE_ENV === 'test') {
app.use(morgan('dev'));
}
app.use(bodyParser.json());
// Routes
app.use('/users', require('./routes/users'));
// Start the server
const port = process.env.PORT || 3001;
app.listen(port);
console.log(`Server listening at ${port}`);
Other post routes works fine,

Resources