How to send email using Angular and Node server? - node.js

I am able to send emails with nodejs using nodemailer but my project is in angular 6. I don't know how to integrate that nodejs code into my angular.I just want it for my website contact us forum. Thank you in advance.

You'd need to create a way of allowing your Angular code to talk to your Node.js code, typically you'd use a REST API using Http or Express.
For example, using Express:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 8081;
app.use(bodyParser.json());
// Allow callers to send an email message
app.post('/send_email', function(req, res){
console.log('send_email body: ', req.body);
sendEmail(req.body);
res.status(201).json({status: 'success' });
});
app.listen(port);
function sendEmail(emailObj) {
// Send the mail
}
In Angular you can use the HttpClient module to call this, for example:
// Replace the url root as necessary
this.httpClient.post("http://127.0.0.1:8081/send_email",
{
"email": "user1#example.com",
"message": "Test message"
})
.subscribe(
data => {
console.log("POST Request is successful ", data);
},
error => {
console.log("Error", error);
}
);
It's worth noting that you will need to provide some authorization mechanism in the REST endpoint (e.g. POST send_email), since you don't want any old client sending mails.

Related

Node JS post API endpoint not recognized in front end

I'm trying to make a post request using appwrite SDK in Node JS express and Vue JS. The SDK requires me to create an api post request to create new storage bucket in appwrite. The DOCs for this particular request isn't explaining really how to create the api in node JS express. I'm really new to Node JS and I already succeeded at creating get request but whenever I create the post request I get 404 not found error.
Node JS express file (server.js):
In this file there is get users request API which works perfectly fine.
And there is create bucket post request which when being called in frontend it comes back with a 404
const express = require("express");
const path = require("path");
const app = express(),
bodyParser = require("body-parser");
port = 3080;
// Init SDK
const sdk = require("node-appwrite");
let client = new sdk.Client();
let users = new sdk.Users(client);
let storage = new sdk.Storage(client);
client
.setEndpoint("http://localhost/v1") // Your API Endpoint
.setProject("tailwinder") // Your project ID
.setKey(
"Secrer Key!"
); // Your secret API key
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "../appwrite-app/build")));
//This get request works fine
//get user by ID
app.get("/v1/users/:id", (req, res) => {
let promise = users.get(req.params.id);
promise.then(
function (response) {
res.json(response);
},
function (error) {
console.log(error);
}
);
});
//This one isn't recognised in frontend
app.post("/v1/storage/buckets", function (req, res) {
let promise = storage.createBucket("bucket_id", "bucket_name", "file");
promise.then(
function (response) {
res.json(response);
},
function (error) {
console.log(error);
}
);
});
app.listen(port, () => {
console.log(`Server listening on the port::${port}`);
});
bucketsServices.js:
Here I'm using fetch post request to the api endpoint but it's not working.
export async function createBucket() {
const response = await fetch("/v1/storage/buckets", {
method: "POST",
});
return await response.json();
}
Addcomponent.vue:
Here I'm calling out the createBucket function from vue js file
bucketTesting() {
createBucket().then((response) => {
console.log(response);
});
},
The error which I assume it means that it's not reading my node js express post API:
bucketsService.js?993b:2 POST http://localhost:8080/v1/storage/buckets 404 (Not Found)
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
A screenshot of the same error:
Something is missing here and I can't really figure it out.
You are making request to localhost:8080 meanwhile your server is running at localhost:3080
I believe your vue is running at port 8080 that's why /v1/storage/buckets gets prefixed by localhost:8080
Try to provide full URL while making request
export async function createBucket() {
const response = await fetch("localhost:3080/v1/storage/buckets", {
method: "POST",
});
return await response.json();
}
Better way might be to add proxy to automatically redirect request to correct URL, but this should work for now. This article might help with how to setup proxy in vue

Send Grid API in Node.js

I am trying to get the contact list and check if the email recipient opened the email or not.
I found this code and tried but got 401.
import config from "#server/config"
sgClient.setApiKey(config.sendgridKey)
const headers = {
"on-behalf-of": "my account user name" // I put my account user name here
}
const request = {
url: `/v3/subusers`,
method: "GET"
} as any
const list = await sgClient
.request(request)
.then()
.catch((err) => {
console.log("list", err.response.body)
})
What do I need to put for the header 'on-behalf-of'? What does the subuser's user name?
And is there any example to get the 'email opened' event?
I am using Node.js.
Thank you!
Twilio SendGrid developer evangelist here.
The API you are trying to use there is the subuser API, not the contacts API. The subuser API is for managing subusers, which are accounts you can apply credit to and send emails from. Subusers are only available on Pro or Premier email accounts or Advanced Marketing Campaign accounts.
However, even if you were to use the Contacts API to get a list of your contacts, that's not the way to see if they have opened an email.
You should instead register for the Event Webhook. With the Event Webhook, SendGrid will send you webhook requests about events that occur as SendGrid processes your emails. These events include "processed", "delivered", "opened", and "clicked" and there are more in the documentation.
To handle the Event Webhook you need to create yourself an endpoint that can receive incoming HTTP requests. Here is an example from the documentation using Express.
const express = require('express');
const app = express();
app.use(express.json());
app.configure(function(){
app.set('port', process.env.PORT || 3000);
});
app.post('/event', function (req, res) {
const events = req.body;
events.forEach(function (event) {
// Here, you now have each event and can process them how you like
processEvent(event);
});
});
var server = app.listen(app.get('port'), function() {
console.log('Listening on port %d', server.address().port);
});

node js function called from a JavaScript code

So I have a node js code that updates and modifies a file content but I would like the data being inserted to come from a JavaScript code. How do I connect the two? Basically how do I have a function in node js that can be called from JavaScript?
Considering there's not much information to go off in the question, I am going to make a the assumption that you're trying to pass information from JS in a web browser to a node application.
The easiest and best documented way to do this would be to set up a simple web server using a package like expressJS and send data as a POST request using the fetch command in the browser.
Install express on the node application using the getting started guide
Write a http path where you can process the data
Start the node app
Make a call to the path we just created
Example backend code:
const express = require('express')
var bodyParser = require('body-parser')
const app = express()
const port = 3000
app.use(bodyParser);
app.post('/mypath', (req, res) => {
const myInputData = req.body.data;
//Do whatever you want with the data
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
Example front-end code:
var data = new FormData();
data.append('data', YOUR_DATA_VAR_HERE)
var options = {
method: 'POST',
body: data
}
fetch('http://localhost:3000/mypath',options)
.then(function(response){ console.log("Data was sent successfully") })
.catch(function(error) { console.log("There was an error sending data") })

Twilio statusCallback implementation running into trouble

I am a beginner to Twilio. I understand that I can get the status of the SMS send by having a statusCallback, so that the POST will happen to the callbackurl with the status of the message. But I am having troubles in creating that particular POST endpoint.
Here is what I have :
// Twilio API CALL
client.sendMessage({
to:userId,
from: metadata.myTwilioNumber,
body: message,
StatusCallback:'POST URL'
}, function(err, responseData) {
if (!err) {
} else {
logger.info(err);
}
My POST endpoint is a simple node js (request, response) endpoint.
var server = http.createServer ( function(request,response){
response.writeHead(200,{"Content-Type":"text\plain"});
if(request.method == "GET")
{
response.end("received GET request.")
}
else if(request.method == "POST")
{
console.log(request.CallStatus);
console.log(response);
console.log('receivedRequest');
response.end("received POST request.");
}
else
{
response.end("Undefined request .");
}
});
server.listen(4445);
Can someone help me in getting the status and messageID of the response? Currently, the POST is getting invoked but i am unable to get the message details and status.
Twilio developer evangelist here.
You are using the basic Node.js standard library http module which is going to make it a lot of work to extract the information from the POST request. Can I recommend you try something like express with body-parser instead.
You can do so by installing the two modules with npm:
npm install express body-parser
Then you can rewrite your incoming message application like this:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/', (req, res) => {
console.log(req.body.CallStatus);
res.sendStatus(200);
});
app.listen(4445, () => {
console.log('Application running on localhost:4445');
});
All the parameters that Twilio sends will be available on the req.body object.
Check out this tutorial on receiving SMS messages with Twilio in Node for a bit more detail.

Mailgun webhook POST body seems empty

I'am trying to handle http post message from Mailgun bounce webhook. When sending it to Mailgun's Postbin service all data is found of course. But I'm now sending that POST to my localhost server for development purposes and all I get is empty json array. I use Test Webhook.
Intent is to keep this simple as possible besides our main service. That for I started using nodejs/expressjs to create stand alone webservice to work as relay to receive POST messages of email bounces from Mailgun and inform admins about bounced email addresses.
Now I can't figure why I don't get the same data as is visible in Postbin.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mailgun = require('mailgun-js')({apiKey: 'key-...', domain: 'mymailgundomain.com'});
app.use(bodyParser.urlencoded({
extended: true
}));
function router(app) {
app.post('/webhooks/*', function (req, res, next) {
var body = req.body;
if (!mailgun.validateWebhook(body.timestamp, body.token, body.signature)) {
console.error('Request came, but not from Mailgun');
res.send({ error: { message: 'Invalid signature. Are you even Mailgun?' } });
return;
}
next();
});
app.post('/webhooks/mailgun/', function (req, res) {
// actually handle request here
console.log("got post message");
res.send("ok 200");
});
}
app.listen(5000, function(){
router(app);
console.log("listening post in port 5000");
});
I'm running this from Mailgun's Test Webhook using url like http://mylocalhostwithpublicip.com:5000/webhooks/mailgun
Code structure is copied from https://github.com/1lobby/mailgun-js. Probably I'm missing something fundamental here as I can't figure it out myself.
The reason you're not seeing req.body populated is because the body-parser module does not support multipart/form-data requests. For those kinds of requests you need a different module such as multer, busboy/connect-busboy, multiparty, or formidable.
If your content-type (shown by logging console.dir(req.headers['content-type'])) is 'application/x-www-form-urlencoded', and you're using body-parser, try adding the following line:
bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }))
to make it work with multer, you can use .any() (version 1.1.0)
for me it worked like this: (assuming multer is included and declared as "multer")
post('/track', multer.any(),function(req, res){
//if body is a string, parse the json
var data=(typeof req.body=='string')?JSON.parse(req.body):req.body;
//if data is an object but you can't verify if a field exists with hasOwnProperty, force conversion with JSON
if(typeof data=='object' && typeof data.hasOwnProperty=='undefined')
data=JSON.parse(JSON.stringify(data));
//data is your object
});
var multer = require('multer');
var msg = multer();
post('/track', msg.any(), function(req, res){
console.log(req.body);
}
I make a custom parser for get data in req.body when the Content-type = 'multipart/alternative'
https://github.com/josemadev/Multiparser/

Resources