I've updated my meteor to 1.2, and I'm now trying to use the email attachment feature, but not sure how to.
Meteor's guide says refer to this, but it's not very helpful..
if(true == true){
var dataAttachments = attachment;
var dataText =
"Client Name: " + name +
"\rEmail: " + email +
"\rPhone: " + phone +
"\rCompany: " + company +
"\rDeliverables: " + deliverables +
"\rCopywriting: " + copywriting +
"\rPrint Services: " + print +
"\rIllustration: " + illustration +
"\rphotography: " + photography +
"\rTimelines: " + timelines +
"\rBudget: " + budget +
"\rDescription: " + description;
Meteor.call('sendEmail', dataText, dataAttachment);
//throwAlert is my helper method which creates popup with message
alert('Email sent');
}else{
alert('An error occurred. Sorry');
return false;
}
}
});
and
Meteor.methods({
sendEmail: function (text) {
check([text], [String]);
this.unblock();
Email.send({
to: 'jaeeun#antarcti.cc',
from: 'contact#myClientProject.com',
subject: 'New message from contact form',
text: text
});
Email.send().addAttachment(attachment);
}
});
I would suggest installing this package: https://atmospherejs.com/ashutosh/email-att
Then do:
var attachments = [];
attachments.push({filename: "xxx", filePath: "xxx"});
var email = {
from: "test#gmail.com",
to: "test2#gmail.com",
subject: "Test!",
text: "Text!"
attachmentOptions: attachments
};
Meteor.call('send_one_email_with_attachments', email, function(){});
Meteor.methods({
send_one_email_with_attachments: function(email){
this.unblock();
EmailAtt.send(email);
};
});
This made my life a lot easier after I fought Meteor's built-in email for a while. It even works side-by-side, so you can still use your old non-attachment email functions!
Related
window.onload = function () {
const user_name =
NAME_ARRAY[Math.round(Math.random() * NAME_ARRAY.length)];
document.getElementById("userName_profile").innerHTML = user_name;
document.getElementById("userName").innerHTML = user_name;
const btn = document.querySelector("#sendMessage");
const textfield = document.querySelector("#messageInput");
const log = document.querySelector("#messageArea");
// +++++++++++++++ For chat messaging system ++++++++++++
NAF.connection.subscribeToDataChannel(
"chat",
(senderId, dataType, data, targetId) => {
console.log("msg", data, "from", senderId, targetId);
messageArea.innerHTML += senderId + ": " + data.txt + "<br>";
}
);
btn.addEventListener("click", (evt) => {
NAF.clientId = user_name;
messageArea.innerHTML +=
NAF.clientId + ": " + textfield.value + "<br>";
NAF.connection.broadcastData("chat", { txt: textfield.value });
document.getElementById("messageInput").value = "";
// NAF.easy = user_name;
});
}
When I've made chat system and working fine. The only, issue is that I want a user name rather than a client id. Please, help with this.
I am working on Casper JS web scraping, for now I have scraped the title from a site. I am making ajax request to the php file where I am collecting the data through post, but the data is not being sent through it while the response status is 200 and OK I don't know what is causing the problem.
The rest of the data is inserted successfully into the table, but not the title.
var casper = require('casper').create();
casper.start("https://www.google.com/");
casper.then(function(){
var data = this.evaluate(function(){
var title = document.getElementsByTagName('title')[0].textContent;
return title;
})
console.log(data);
casper.thenOpen("http://localhost/fiverr/Crawl%20The%20Jobs/modal_scripts.php",{method:"POST",data:data+"&crawled_jobs=true"}).then(function(res){
console.log(res.status);
})
})
casper.run();
The PHP script, I am collecting data in :
if (isset($_POST["crawled_jobs"])) {
$title = $_POST["data"];
$jobs_list_insert = "INSERT INTO jobs VALUES(null,'$title','nady','ahmad','kahn','yess','yesss')";
$con->query($jobs_list_insert);
}
Found a solution :
var i = 0;
console.log("Data Length : " + d.length);
function sendData(i) {
console.log("Posting Data...");
casper.thenOpen("http://localhost/fiverr/Crawl%20The%20Jobs/modal_scripts.php", {
method: "POST",
data: "title=" + d[i].title + "&loc=" + d[i].loc + "&day=" + d[i].day + "&salary=" + d[i].salary + "&link=" + d[i].link + "&logo=" + d[i].compLogo + "&crawled_jobs=true",
async: false
}).then(function(res) {
console.log(res.status);
sendData(i + 1);
})
}
sendData(i);
I currently have a Page Fragment with the following code that creates an entry for a datasource and sends out an email (code below) notifying everyone.
Button:
newSalesEmailMessage(widget);
widget.datasource.createItem();
app.closeDialog();
Client Script Email notification code:
/**
* Calls a server method to send an email.
* #param {Widget} sendButton - widget that triggered the action.
*/
function newSalesEmailMessage(sendButton) {
var pageWidgets = sendButton.root.descendants;
var fullName = app.datasources.Directory.item.FullName;
var htmlbody = '<b><font size="3">' + fullName + '</font></b>' + ' has created a new sales entry for: ' +
'<h1><span style="color:#2196F3">' +pageWidgets.ProjectName.value + '</h1>' +
'<p>Contact: <b>' + pageWidgets.Contact.value + '</b>' +
'<p>Sales Person: <b>' + pageWidgets.SalesPerson.value + '</b>' +
'<p>Notes: <b>' + pageWidgets.Notes.value + '</b>';
google.script.run
.withSuccessHandler(function() {
})
.withFailureHandler(function(err) {
console.error(JSON.stringify(err));
})
.sendEmailCreate(
'test#email.com',
'New Sales Entry for: ' + pageWidgets.ProjectName.value,
htmlbody);
}
onCreate code for the Model:
// onCreate
var email = Session.getActiveUser().getEmail();
var directoryQuery = app.models.Directory.newQuery();
directoryQuery.filters.PrimaryEmail._equals = email;
var reporter = directoryQuery.run()[0];
record.reported_by = email;
record.reported_full_name = reporter.FullName;
record.Date = new Date();
Everything works except for the fullName option. It keeps pulling my name even when another user creates an entry (maybe because I am an admin?). I have a Directory Model setup and that seems to work for when I am displaying the full name for a users's comments.
I would like to have fullName = the name of the person currently creating the entry.
Thank you for your help!
App Startup Script:
// App startup script
// CurrentUser - assuming that it is Directory model's datasource
// configured to load record for current user.
loader.suspendLoad();
app.datasources.Directory.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
You need to filter your Directory model datasource. If you are planning to use it for different purposes, then I'll recommend to create dedicated datasource for current user. You can filter it on server (preferable) or client side:
Filter on server, load on client:
// Directory model's Server Script for Current User datasource
var query = app.models.Directory.newQuery();
query.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
return query.run();
// ------------------------
// Your startup script will remain almost the same:
loader.suspendLoad();
app.datasources.CurrentUser.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
Client-only:
var currentUserDs = app.datasources.CurrentUser;
currentUserDs.query.filters.PrimaryEmail._equals = app.user.email;
loader.suspendLoad();
currentUserDs.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
Thank you to Pavel. Everything worked, but it took me a few to understand exactly what I needed to do. For those who want to try and replicate what I did here were the steps.
First I had to create a Directory Model.
Then under the App Settings section for the app itself (click the gear) I put the following code under the App Startup Script - Client Script section:
loader.suspendLoad();
app.datasources.CurrentUser.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
Next I went under the Datasources section for the Directory model and added a datasource called CurrentUser.
In the Query - Server Script section I put:
var query = app.models.Directory.newQuery();
query.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
return query.run();
This filters the datasource so that the only entry in there is the current user. Then I adjusted my "var fullName" in the email Client Script to point to the new datasource:
/**
* Calls a server method to send an email.
* #param {Widget} sendButton - widget that triggered the action.
*/
function newSalesEmailMessage(sendButton) {
var pageWidgets = sendButton.root.descendants;
var fullName = app.datasources.CurrentUser.item.FullName;
var htmlbody = '<b><font size="3">' + fullName + '</font></b>' + ' has created a new sales entry for: ' +
'<h1><span style="color:#2196F3">' +pageWidgets.ProjectName.value + '</h1>' +
'<p>Contact: <b>' + pageWidgets.Contact.value + '</b>' +
'<p>Sales Person: <b>' + pageWidgets.SalesPerson.value + '</b>' +
'<p>Notes: <b>' + pageWidgets.Notes.value + '</b>';
google.script.run
.withSuccessHandler(function() {
})
.withFailureHandler(function(err) {
console.error(JSON.stringify(err));
})
.sendEmailCreate(
'test#email.com',
'New Sales Entry for: ' + pageWidgets.ProjectName.value,
htmlbody);
}
startup.js
smtp = {
username: 'xxxx#gmail.com',
password: 'alpha123e',
server: 'smtp.gmail.com',
port: 465
}
process.env.MAIL_URL = 'smtp://' + encodeURIComponent(smtp.username) + ':' + encodeURIComponent(smtp.password) + '#' + encodeURIComponent(smtp.server) + ':' + smtp.port;
Meteor method
Meteor.methods({ sendEmail: function (to, from, subject, text) {
check([to, from, subject, text], [String]);
this.unblock();
Email.send({
to: to,
from: from,
subject: subject,
text: text
});
}
});
If you want to use a templated design in your email then you'll want to set the html property of the email, not just the text.
Email.send({
to: to,
from: from,
subject: subject,
html: "<h1>Hello World</h1>",
text: "Hello World"
});
You will find the meteorhacks:ssr package very useful for rendering templates server-side.
I have added grunt jshint task to my grunt. I created custom reporter to send out jsHint output as email. My custom reporter function is invoked. But no emails are coming through. There are no errors in the code.
Grunt version: "grunt": "^0.4.5",
"nodemailer": "^1.11.0",
"nodemailer-sendmail-transport": "^1.0.0"
Here is the sample code:
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');
var async = require('async');
module.exports = {
reporter: function (errors) {
var len = errors.length,
str = '';
var items = [1];
errors.forEach(function (r) {
var file = r.file,
err = r.error;
str += file + ": line " + err.line + ", col " +
err.character + ", " + err.reason + "\n";
});
if (str) {
str += "\n" + len + " error" + ((len === 1) ? "" : "s") + "\n";
}
var transporter = nodemailer.createTransport( smtpTransport( {
service: "gmail",
secureConnection: false, // use SSL
port: 587, // port for secure SMTP
auth: {
user: "<my gmail username>",
pass: "<gmail account password>"
},
tls:{
ciphers:'SSLv3'
},
logger: true, // log to console
debug: true // include SMTP traffic in the logs
}));
// setup e-mail data with unicode symbols
var mailOptions = {
from: '<sender address>',
to: '<recipient address>',
subject: 'Hello', // Subject line
text: "why are you not working"
/* text: str */// plaintext body
/*html: '<b>Hello world</b>' // html body*/
};
async.eachSeries(items, function (item, next) {
transporter.sendMail(mailOptions, function(error, response){
// THIS CALLBACK IS NOT CALLED AT ALL
if(error){
console.log(error);
}else{
console.log("Message sent");
}
next(null);
});
}, function(err){
// All tasks are done now
console.log('All tasks are done now');
});
}
};
with async or without async doesn't matter. No emails are coming. I tried bye turning on the "Receive emails from unsecured apps" by following another stackoverflow post. That also did not help.
I would like to know is this correct approach or not? Any help/input is appreicated.