MailGun: Add data variables to email - javascript

Im sending emails through Node.js using MailGun. I want to add custom data variables that contain data from database send it as part of email body. Based on my research I need to use recipient-variables. But the problem is that recipient-variables require the email of recipient as the key of the object like so:
{
"user1#example.com" : {"unique_id": "ABC123456789"},
"user2#example.com" : {"unique_id": "ZXY987654321"}
}
Now the data I'm getting from my database is this:
{ email: 'myemail#something.com', projects: [ 'aqeqw weqw ', 'title here' ]}
Whereas MailGun requires this (which seems weird to me):
{'myemail#something.com': { email: 'myemail#something.com', projects: [ 'aqeqw weqw ', 'title here' ]}}
How can I set the key of object I'm receiving from the database as the email?
FYI my code for MailGun:
let data = {
from: 'My App <donotreply#myapp.com>',
to: data.email,
subject: 'Reminder Email',
'recipient-variables': {data},
html: '<html style="color: red; font-size: 20px; background-color: aqua">Inline image here:<p style="">Your project list and your name is %recipient.projects%</p></html>',
};
mailgun.messages().send(data, function(error, body) {
console.log(body);
});

You can just do it like this, with an intermediate object:
let obj = {
email: 'myemail#something.com',
projects: [ 'aqeqw weqw ', 'title here' ]
}
let final = {}
final[obj.email] = obj
console.log(final)
/* {
'myemail#something.com':
{
email: 'myemail#something.com',
projects: [ 'aqeqw weqw ', 'title here' ]
}
}
*/

Related

Discord.js converting Javascript with console into embeds for discord

So I'm working on a bot right now and when looking at the api I get this as the example of how it'll work.
(async () => {
console.log(await bookwebsite.getHomepage(1))
})()
{
results: [ { bookId: 'web id',
thumbnail: 'thumbnail link',
title: 'book title' },
{ bookId: 'web id',
thumbnail: 'thumbnail link',
title: 'book title' },
{ bookId: 'web id',
thumbnail: 'thumbnail link',
title: 'book title' },
...
],
}
Can anyone lead me in the right direction on how to translate this from a console log script to running it within discord embeds? API WARNING NSFW
I'm not extremely sure what you're meaning as of translating console into embeds but I'm guessing you're trying to format the data returned in the api in to a embed in Discord.
const bookwebsite = require('nhentai-js');
(async () => {
var data = await bookwebsite.getHomepage(1);
data = data.results.slice(0, 25);
if(!data) return message.channel.send('Failed to retrieve data from api. ')
// slices to avoid discord embeds going beyond 25 fields
var embed = new Discord.MessageEmbed()
.setTitle('Results found');
// For each the data that's received(after its trimmed)
data.forEach(d=>{
// For every object inside of data, it takes the name and sets it as a field title and sets the description of the field as the id and thumbnail link.
embed.addField(`Name: ${d.title}`, `ID: ${d.bookId}\nThumbnail: ${d.thumbnail}`)
})
// Embeds done, now need to send into the channel
message.channel.send(embed)
})()
If you need any help further on, please comment below.

Batch emailing with Mailgun and Node.js

I'm using the Mailgun node.js module to send batch emails out.
According to the big yellow warning message in the official docs, specifying recipient vars should result in sending "each recipient an individual email with only their email in the to field."
However, my recipients can see all of the "to" addresses. I am successfully using recipient-vars to set the email subject for users, so it does appear that these are being read in correctly.
Note that I am sending an HTML email using MIME. I tried this with the more straight-forward plain text variation, and it did appear to work.
Is anyone able to help me understand why my recipients can see all other recipients? Am I doing something wrong, or does this functionality not work for Mailgun MIME emails?
// recipients
var recipients = ['email1#email1.com', 'email2#email2.com', 'email3#email3.com'];
var recipientVars = {
'email1#email1.com': {
id: 1,
subject: 'Subject 1'
},
'email2#email2.com': {
id: 2,
subject: 'Subject 2'
},
'email3#email3.com': {
id: 3,
subject: 'Subject 3'
}
};
// options
var options = {
from: 'Me <me#me.com>',
to: recipients,
'recipient-variables': recipientVars,
subject: '%recipient.subject%',
text: myMailText,
html: myMailHTML,
headers: {
'X-Mailgun-Recipient-Variables': JSON.stringify(recipientVars)
}
};
// create mail
var mail = new nodemailer(options);
// send mail
mail.compile().build((err, message) => {
var mailData = {
to: recipients,
message: message.toString('ascii'),
'recipient-variables': recipientVars
};
mailgun.messages().sendMime(mailData, (err, res) => {
console.log(res);
});
});
Seems this functionality doesn't work with sendMime() method, but it does with regular send() method even without any mail compilation. Here is working code snippet:
const mailgun = require('mailgun-js')({
apiKey: 'api_key',
domain: 'domain'
});
const recipients = ['email1#gmail.com', 'email2#gmail.com'];
const recipientVars = {
'email1#gmail.com': {
id: 1,
subject: 'Subject 1',
name: 'Name 1'
},
'email2#gmail.com': {
id: 2,
subject: 'Subject 2',
name: 'Name 2'
}
};
const envelope = {
from: 'Sender <sender#gmail.com>',
to: recipients,
subject: '%recipient.subject%',
html: 'Hey <strong>%recipient.name%<strong>',
'recipient-variables': recipientVars,
};
mailgun.messages().send(envelope, function (error, body) {
console.log(body);
});
As you would notice all placeholders are populated and <strong> tag properly rendered.

AMAZON SNS Push notification payload to android mobile using Node js

Implementation of Amazon SNS push notification to android device using aws-sdk package in NodeJS. I have few implementations mentioned below. Mobile device is displaying push notifications. I want to send data and notification object in payload.
let payload2 = JSON.stringify({
default: 'Naresh',
GCM: JSON.stringify({
notification : {
body : 'great match!',
title : 'Portugal vs. Denmark'
},
data:{
testdata: 'Check out these awesome deals!',
url: 'www.amazon.com'
}
})
});
It's not sending push notifications.
let payload1 = {
"GCM": "{
\"notification\": {
\"title\": \"this one last test in app\",
\"body\": \"mm hello tests\"
},
\"data\": {
\"turnclass\": \"efwfwe\",
\"flight\": \"truejet\"}
}"
};
It's sending push notifications.
sns.publish({ TargetArn: targetArn,
Message: payload1,
MessageStructure: 'json'
}, (error, data) => (error) ? reject(error) : resolve(data));
What is right format to send push notifications?
According to documentation:
When sending platform-specific payloads in messages using the Amazon
SNS console, the data must be key-value pair strings and formatted as
JSON with quotation marks escaped.
Example:
{
"GCM":"{
"data":{
"message":"Check out these awesome deals!",
"url":"www.amazon.com"
}
}"
}
What you are doing in the first payload produces the following output:
{"default":"Naresh","GCM":"{\"notification\":{\"body\":\"great match!\",\"title\":\"Portugal vs. Denmark\"},\"data\":{\"testdata\":\"Check out these awesome deals!\",\"url\":\"www.amazon.com\"}}"}
And that is not a valid format. That happens because you're double JSON.stringify a part of your object. So if you do:
let payload2 = JSON.stringify({
default: 'Naresh',
GCM: {
notification: {
body: 'great match!',
title: 'Portugal vs. Denmark'
},
data: {
testdata: 'Check out these awesome deals!',
url: 'www.amazon.com'
}
}
});
It will produce:
{"default":"Naresh","GCM":{"notification":{"body":"great match!","title":"Portugal vs. Denmark"},"data":{"testdata":"Check out these awesome deals!","url":"www.amazon.com"}}}
Which should work as expected.

Get message_id from Telegram message - node.js

I have a problem concerning a Telegram bot I am currently working on. I get messages from users in the following format:
update { update_id: 82618016,
message:
{ message_id: 363,
from: { id: 22303518, first_name: 'Steve', language_code: 'de-DE' },
chat: { id: 22303518, first_name: 'Steve', type: 'private' },
date: 1501501753,
text: 'j' } }
When I want to access the id of the chat I can do this without any problems by using
$.message.chat.id
As soon as a want to get the message_id or first_name I only get "undefined".
$.message.chat.first_name
$.message.message_id
Can anyone help me here? As far as I see it I understood the structure of the message correctly so I don't really know what's the problem here.
Thank you very much in advance
EDIT: I am adding a bit more of my code here:
The main code for the bot (including the webhook) is this:
initializeBot();
function initializeBot(){
const Telegram = require('telegram-node-bot');
const PingController = require('./controllers/ping');
const OtherwiseController = require('./controllers/otherwise');
const tg = new Telegram.Telegram('MY_TOKEN_IS_HERE', {
webhook: {
url: 'https://xxx.herokuapp.com',
port: process.env.PORT || 443,
host: '0.0.0.0'
}
})
tg.router.when(new Telegram.TextCommand('/ping', 'pingCommand'), new PingController())
.otherwise (new OtherwiseController());
}
When the OtherwiseController gets called the following code is called (I reduced it to the essentials to clarify the problem.
class OtherwiseController extends Telegram.TelegramBaseController {
handle($){
console.log($.message.chat.first_name);
console.log($.message.text);
console.log($.message.chat.id);
console.log($.message.message_id);
}
}
The console output for this message
update { update_id: 82618020,
message:
{ message_id: 371,
from: { id: 22303518, first_name: 'Steve', language_code: 'de-DE' },
chat: { id: 22303518, first_name: 'Steve', type: 'private' },
date: 1501509762,
text: 'hello' } }
would be:
undefined
hello
22303518
undefined
Use the below method to extract the keys of your json object, then you can access with an appropriate key:
Object.keys($.message.chat);

How to search all keys inside MongoDB collection using only one keyword

Is there a way for MongoDB to search an entire collection's keys' contents using only a single search keyword?
Suppose I have the following collection (let's call it foodCollection):
{
name: "Chocolate Mousse Cake",
type: "Cake"
},
{
name: "Mother's Cookies",
type: "Cookies"
},
{
name: "Dark Bar",
type: "Chocolate"
}
I want my search to look for matches that contain "Chocolate", meaning it should return "Chocolate Mousse Cake" and "Dark Bar".
I'm trying to do this using the ff: code:
Client-side controller
// Search Products
$scope.searchProduct = function () {
$http.get('/api/products/search/' + $scope.searchKeyword).success(function(data){
console.log(data);
})
.error(function(err) {
console.log("Search error: " + err);
});
}
Express.js
app.get('/api/products/search/:param', productController.search); // Search for product
Server-side controller (I used this reference from the MongoDB docs):
// Search
module.exports.search = function(req, res) {
console.log("node search: " + req.body);
Product.find({ $or: [{productName: req.body},
{productType: req.body}]
}, function(err, results) {
res.json(results);
});
}
When I executed this, I got nothing. Am I missing something?
Any help would be greatly appreciated. Thank you.
UPDATE (FINAL)
Finally solved this thanks to Joydip's and digit's tips. Here's my solution in case somebody else gets the same problem as I did:
Client-side controller
$scope.searchProduct = function () {
if ($scope.searchKeyword == '') {
loadFromMongoDB(); // reloads original list if keyword is blank
}
else {
$http.get('/api/products/search/' + $scope.searchKeyword).success(function(data){
if (data.length === 0) {
$scope.showNoRec = true; // my flag that triggers "No record found" message in UI
}
else {
$scope.showNoRec = false;
$scope.productList = data; // passes JSON search results to UI
}
});
}
}
Express.js
app.get('/api/products/search/:keyword', productController.search); // Search for product
Mongoose schema
var mongoose = require('mongoose');
var schema = new mongoose.Schema({
productName: String,
productType: String,
productMaker: String,
productPrice: Number,
createDate: Date,
updateDate: Date
});
schema.index({productName: "text", productType: "text", productMaker: "text"});
Server-side controller
module.exports.search = function(req, res) {
Product.find({$text: {$search : req.params.keyword}}, function(err, results){
res.json(results);
})
}
Thank you everyone for your help. :)
You can try by creating an Index:
db.yourollection.createIndex({"productName":1,"productType":1})
And then by searching for the value, Example:
Product.find({$text:{$search: 'Chocolate'}},{productName:1, productType:1});
If you want to search all key, then you can use
db.foodCollection.createIndex( { name: "text", description: "text" } )
then search by
db.foodCollection.find({ $text: { $search: "choco" } })

Categories

Resources