So I am working on a wait list type application. When a user submits their information into the list (using autoform) they should be sent a messsage through the Twilio service.
I currently have a hard coded variable working with twilio
Method to send sms
Meteor.methods({
sendSMS: function (phoneNumber) {
var authToken = 'token value here';
var accountSid = 'sid value here';
twilio = Twilio(accountSid, authToken);
twilio.sendSms({
to: phoneNumber, // Any number Twilio can deliver to
from: '+18.....', // A number you bought from Twilio and can use for outbound communication
body: 'You have been added to the waitlist' // body of the SMS message
}, function (err, responseData) { //this function is executed when a response is received from Twilio
if (!err) { // "err" is an error received during the request, if any
// "responseData" is a JavaScript object containing data received from Twilio.
// A sample response from sending an SMS message is here (click "JSON" to see how the data appears in JavaScript):
// http://www.twilio.com/docs/api/rest/sending-sms#example-1
console.log(responseData.from); // outputs "+14506667788"
console.log(responseData.body); // outputs "word to your mother."
}
});
}
});
Here is the event I have working with hard coded number:
Template.home.events({
"submit #student-form": function(event) {
event.preventDefault();
var phoneNumber = '+18.....';
Meteor.call("sendSMS", phoneNumber);
// alert("You have been added to the WaitList");
swal("Success!", "You have been added to the WaitList", "success")
}
});
My quickform
{{>quickForm id="student-form" collection="Students" type="insert" template="bootstrap3-horizontal" label-class="col-sm-3" input-col-class="col-sm-9"}}
What I want to know is how do I get the phone number value that was just submitted into the mongodb collection so that I can send a message to that specific phone number with twilio?
OP found the answer here: Find Value in Meteor Mongo
If you are looking to retrieve a field out of the returned document,
you can specify as much using the fields option:
database.findOne({}, {sort: {'timeStamp' : -1}, limit:1, fields: {'myField': 1, _id: 0})
That will retrieve an object in format like this:
{'myField': 'value of myField'}
Related
I am building a program where the user can select a crypto currency, enter their email and basically it will remind them with an email when the crypto hits the user's selected price. (A price notifier by email). I have got email working and a crypto api to get the price data, but now i am just wondering how i am going to get the program to save the users data and every time i get the price data how am i going to send email to multiple users who have signed up for reminders. I hope this is making sense, i will post relevant code below.
Getting price data
async function getPriceData() {
try {
const response = await axios.get(
"https://api.coingecko.com/api/v3/coins/bitcoin",
{}
);
const data = response.data;
const price = data.market_data.current_price.usd;
return price;
} catch (error) {
throw error;
}
}
Email function that uses price data to send email. (Currently using setTimeout to keep checking price data but im not sure this is the best way to keep checking api).
I am using nodemailer for sending emails and all working fine.
Client data is posted to server and used in this function, all working fine.
const emailFunction = (price, recieverEmail) => {
getPriceData().then((response) => {
const btcPrice = response;
const selectedPrice = price;
if (btcPrice < selectedPrice) {
const transport = nodemailer.createTransport({
host: "smtp.sendgrid.net",
port: 587,
auth: {
user: "apikey",
pass: sendgridKey,
},
});
const message = {
from: senderEmail,
to: recieverEmail,
subject: `BTC PRICE BELOW ${selectedPrice}!`,
text: `Bitcoin price is below your selected price of ${selectedPrice}, and is currently ${btcPrice}. This presents a good buying opportunity.`,
};
transport.sendMail(message, (err, info) => {
if (err) {
console.log(err);
} else {
console.log(info);
}
});
}
setTimeout(emailFunction, 60000);
});
};
Currently i can only send emails for one user and i use the setTimeout to check the api to get price data every 60000ms. This works for now but the end product i would like the user to input email and price and the back end will continuously check api and if coin price has gone below the users price, the user will be alerted at that point. How does this scale to keep track of price and say email 50 people if needed?
Thanks for any input and help on this, much appreciated i am a Node noob.
So I'm trying to Create a reset page using restful API. I haven't found much info on the internet and I'm probably no using the best method. What I'm trying to do is send a code in the email of the user and then after the user typing the code will be decided if he can or cannot update the pass. I can't seem to find a way to pass the value of the code generated on the first request to the second to check if its correct. Any help is appreciated. Thanks in advance!
//ForgotPassword?
app.get('/forgotpassword/:username', function (_req, res) {
var seq = (Math.floor(Math.random() * 10000) + 10000).toString().substring(1);
console.log(seq);
mysqlConnection.connect(function () {
mysqlConnection.query('SELECT Email from Customer Where Username = ?', [_req.params.username], (err, results, _fields) => {
if (!err){
console.log(results[0].Email);
var mailOptions = {
from: 'myemail',
to: results[0].Email,
subject: "Password Reset Verification",
text: "If you did not request this, please ignore this email and your password will remain unchanged. CODE: " + seq,
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
//Handle error here
res.send('Please try again!');
} else {
console.log('Email sent: ' + info.response);
res.send('Sent!');
}
})
}
else
console.log(err);
})
})
});
//CodeRandomCodeFromResetPass
app.get('/reset', function (req, res) {
var code;
//if code typed is = to seq sent in the email
res.send("The code is correct");
});```
//then I'll create a post request that updates the password username from the first get request
The code sent in email should be store in a table or collection. So code will be store against the email and an expiry time of the code. So in the next phase when the code will pass with an email you can check that this(entered) email should belong to this(entered) code within this(expiry time of code) time frame, so if condition satisfied then requested user can reset/change the password.
I am trying to update the user account details in firebase but I have noticed that the input value for one of my fields keeps coming up as undefined even when I console.log it. I am working in two files one is a loginjs file in which I am defining the user input.
signUpForm.addEventListener('click', function (e) {
e.preventDefault();
isSigningUp = true;
var email = signUpEmailInput.value;
var password = signUpPasswordInput.value;
var displayNameUser = displayNameInput.value;
var userPrivateKey = signUpPrivateKey.value;
var user = firebase.auth().currentUser;
var photoURL = "https://www.gravatar.com/avatar/" + md5(email);
if (signUpPasswordInput.value !== signUpPasswordConfirmInput.value) {
setSignUpError('Passwords do not match!');
} else if (!displayNameUser) {
setSignUpError("Display Name is required!");
} else if (!userPrivateKey) {
setSignUpError('You need to set a Private Key!');
} else {
auth.createUserWithEmailAndPassword(email, password)
.then(function (user) {
user.updateProfile({
displayName: displayNameUser,
photoURL: photoURL,
privateKey: userPrivateKey
}).then(function () {
// Update successful.
window.location.href = 'chat.html';
}).catch(function (error) {
// An error happened.
window.alert("Some unexpected error happened!");
});
user.sendEmailVerification().then(function () {
// Email sent.
}).catch(function (error) {
// An error happened.
window.alert("Email was not able to send!");
});
})
.catch(function (error) {
// Display error messages
setSignUpError(error.message);
});
}});
The weird thing is that the user input for my displayname and photoURL are working just fine, but when it comes to my private key user input it registers the input when it goes to the chat page and I do a console.log(user.privatekey) It says it is undefined.
In my chatjs file, thats when I am pushing the all the user profile information. The chatjs file basically allows a user to send a message, the message and all the user profile information gets stored onto the firebase database.
messages.push({
displayName: displayName,
userId: userId,
pic: userPic,
text: myString.toString(),
privatekey: user.privatekey,
timestamp: new Date().getTime() // unix timestamp in milliseconds
})
.then(function () {
messageStuff.value = "";
})
.catch(function (error) {
windows.alert("Your message was not sent!");
messageStuff;
});
The thing again is that the privatekey does not get stored at all, which is what I am not understanding, since it is registering user input in the loginjs file but when I go to the chatjs file it keeps saying the value is undefiend. I have googled everywhere and I still haven't found a solution to it. Any help would be greatly appricated!
It's because the Firebase user object you receive from Firebase is not customizable. When you call the createUserWithEmailAndPassword(email, password) method, it returns a specifically defined user object back to you - check out the docs for the properties of this object.
The properties displayName and photoURL both work because they are already properties of the user returned. privateKey is not an existing property of the Firebase user object, and Firebase doesn't know how to handle an update call for a property that isn't defined. Check out this question & answer where Frank explains that Users in Firebase aren't customizable - you need to store any extra info separately.
I have implemented quickblox chat in my web application. Now I want to show status of my messages as delivered in case when they are just sent to user and as read when they have seen the message.
In your Javascript SDK I have found two functions QB.chat.sendDeliveredMessage and QB.chat.sendReadMessage but every time I call this function as :
QB.chat.sendDeliveredMessage(
QBChatHelpers.getJID(chatUser.id),
"5600f885a28f9ac7e801048c" //this is just a sample msg-id
);
It calls ajax with POST request over url http://chat.quickblox.com:8080/ while chat is running over http://chat.quickblox.com:5280/.
Also within library, I changed the port to 5280 in place of 8080 so that it can call url with port 8080 and it calls http://chat.quickblox.com:5280/ which then gives error code 405: Invalid Hostname.
Please let me know what's wrong am I doing while calling this function. If further information is required then do let me know.
We are working on this feature, in the new version of QuickBlox JS SDK messages will be sent with the markable status.
sendDeliveredStatus(params)-will be sent automatically after receiving a message with markable status, which will signalize via the function of Listener QB.chat.onDeliveredStatusListener(messageId, dialogId, userId);
sendReadStatus(params)-will be possible to send it according to an event (for example, you set up a processor, which will notice that a message has already appeared on yours monitor, after receiving a message with markable status, which will signalize via the function of Listener QB.chat.onReadStatusListener(messageId, dialogId, userId);)
parameters for status sending:
params = {
messageId: messageId,
userId: userId,
dialogId: dialogId
};
Thanks guys, this page helped me a lot.
When a message is sent could be 2 options:
A. You are the sender and another user is the addressee: YOU --> ANOTHER-USER
B. You are the addressee and another user is the sender: ANOTHER-USER --> YOU
OPTION A:
Send your message to the addressee with "markable=1" flag.
For example:
var params = {
chat_dialog_id: "56b20540f583bb7bcb00rrr6",
message: msg),
send_to_chat: 1,
markable: 1,
extension: {
save_to_history: 1
}
};
// SEND THE MESSAGE
QB.chat.message.create(params, function (err, res) {});
Add QB listener to be trigger after the addressee user had read the message:
QB.chat.onReadStatusListener = updateReadersList;
And then add such a function with this signature:
function updateReadersList(messageId, dialogId, userId){
console.log('userId has read your messageId that in dialogId');
}
OPTION B:
Add QB listener to handle new incoming messages:
QB.chat.onMessageListener = showMessage;
Add such a listener function with this signature:
In that listener you can notify the sender that his message was recived an d read (by you):
function showMessage(userId, msg) {
console.log('userId sent you this msg');
//notify sender: message was read:
if(userId != "MY-USER") {
sendReadSignalToSender(msg, userId);
console.log("You notified userId that his msg was read.");
}
}
Adding a simple function for just passing params to QB.chat.sendReadStatus function:
function sendReadSignalToSender(dialogMsg, senderId){
var params = {
messageId: (dialogMsg.id || dialogMsg._id),
userId: senderId,
dialogId: (dialogMsg.dialog_id || dialogMsg.chat_dialog_id)
};
QB.chat.sendReadStatus(params);
console.log("senderId was notified that his dialogMsg was read.");
}
I have two channels for my subscribers: Broadcast and Unique channel. On the Broadcast channel I have all the Subscribers listening to. The Unique channel is for One-To-One communication between the Publisher and the Subscriber.
I need to achieve the following solution: If the Subscriber goes offline/loses connection, after he comes back online he needs to poll the two channels for the single latest message on each of them and determine if the message is still valid based on the property in the message object:
//HERE IS THE MESSAGE OBJECT THAT THE PUBLISHER SENDS ON THE BROADCAST AND THE UNIQUE
//CHANNELS TO THE SUBSCRIBERS.
message = {
alarm: null, //BOOLEAN: DESIGNATES IF THE ALARM IS ON/OFF
body: null, //STRING: SOME MESSAGE/ALARM TEXT
image: null, //STRING: SOME IMAGE IF YOU WANT TO APPEAR WITH THE ALARM TEXT
createdAt: null, //UNIX TIMESTAMP OF WHEN THE MESSAGE WAS CREATED/SENT
validUntil: null //UNIX TIMESTAMP - AFTER THIS PERIOD THE MESSAGE IS CONSIDERED INACTIVE AND THE SUBSCRIBER SHOULD IGNORE THIS MESSAGE ON RECONNECT
};
Here is my sample code for the Subscriber(The problem is marked in the comments in the code):
$(document).ready(function(){
var uuid = PUBNUB.uuid(),
id = 'vlatkorun-' + uuid,
controlChannel = 'vlatkorun-control',
broadcastChannel = 'vlatkorun-broadcast',
uniqueChannel = 'vlatkorun-unique-';
var state = {
id: id,
uniqueChannel: uniqueChannel
};
//INIT PUBNUB
var pubnub = PUBNUB.init({
subscribe_key : 'YYY',
keepalive: 30
});
//SUBSCRIBE TO THE CONTROL CHANNEL FIRST
//THE CONTROL CHANNEL IS FOR MAINTENANCE BETWEEN PUBLISHER
//AND THE SUBSCRIBERS
pubnub.subscribe ({
channel: controlChannel,
message: function(m){console.log(m)},
state: state,
heartbeat: 30,
connect: function(m){/*console.log(JSON.stringify(m))*/},
reconnect: function(m){console.log(JSON.stringify(m))}
});
//NOW SUBSCRIBE TO THE BROADCAST AND THE UNIQUE CHANNELS
pubnub.subscribe ({
channel: [broadcastChannel, uniqueChannel],
state: state,
message: function(data){
//SHOW THE ALARM IN THE BROWSER WHEN MESSAGE ARRIVES
//OUTPUT OMMITED
},
connect: function(m){
//THIS ARRAY IS GOING TO HOLD THE LATEST MESSAGES FROT THE BOTH CHANNELS
var channelLatestMessages = [];
//GET THE MOST RECENT MESSAGE ON THE BROACAST CHANNEL
pubnub.history({
channel: broadcastChannel,
count: 1,
callback: function (m) {
if(m[0].length > 0)
{
//GO OVER THE RETURNED MESSAGES AND PUT THEM IN THE ARRAY FOR COMPARING LATER
$.each(m[0], function(index, value){
channelLatestMessages.push(value);
});
}
//I HAVE THE VARIABLE POPULATED WITH THE MESSAGES FROM THE CHANNEL IN THE CALLBACK
console.info(channelLatestMessages);
},
});
//GET THE MOST RECENT MESSAGE ON THE UNIQUE CHANNEL
pubnub.history({
channel: uniqueChannel,
count: 1,
callback: function (m) {
if(m[0].length > 0)
{
//GO OVER THE RETURNED MESSAGES AND PUT THEM IN THE ARRAY FOR COMPARING LATER
$.each(m[0], function(index, value){
channelLatestMessages.push(value);
});
}
//I HAVE THE VARIABLE POPULATED WITH THE MESSAGES FROM THE CHANNEL IN THE CALLBACK
console.info(channelLatestMessages);
},
});
//I HAVE THE VARIABLE POPULATED WITH THE MESSAGES FROM THE CHANNEL IN THE CALLBACK, BUT HERE THE ARRAY IS EMPTY BECAUSE THE CALLBACKS ARENT
//FISHED.
//HERE IS MY QUESTION: HOW CAN I WAIT FOR THE CALLBACKS TO FINISH SO I CAN CONTINUE WITH MY CODE BELLOW???
console.info(channelLatestMessages);
//IF THERE ARE NO MESSAGES DO NOTHING
if(channelLatestMessages.length == 0) return;
//ASSUME THAT THE FIRST MESSAGE IN THE ARRAY IS THE MOST RECENT
latestMessage = channelLatestMessages[0];
//NOW FIGURE OUT THE MOST RECENT MESSAGE
$.each(channelLatestMessages, function(index, message){
if(latestMessage.createdAt < message.createdAt)
{
latestMessage = message;
}
});
//GET THE CURRENT DATE IN UNIX TIMESTAMP
var currentDate = parseInt(moment().format('X'));
//CHECK IF THE MESSAGE VALIDITY IS EXPIRED
if(currentDate > latestMessage.validUntil) return;
//HERE WE CAN SHOW THE LATEST MESSAGE IN THE BROWSER
//OUTPUT OMMITED
},
reconnect: function(m){//THE SAME LOGIN LIKE IN THE CONNECT METHOD APPLIES HERE}
});
});
How to wait for the callbacks to finish so I can have the channelLatestMessages filled with the latest messages from the Broadcast and Unique channels so I can further determine which message is more recent and if the more recent message is still active?
Can your logic run like this:
historyCall-1's callback calls historyCall-2.
historyCall-2's callback calls "Message Age Detection" logic.
This way, we make the async act synchronously, and the only way "Message Age Detection" logic runs is if we know for a fact that history calls 1 and 2 are complete.
?
geremy