Waiting for email to arrive using node-imap - node.js

I'm using node-imap as a mail solution, but I need a way of waiting until an email arrives. In this post, someone referenced using the IMAP IDLE command to do this. I was wondering if anybody has had success with this, and how you would suggest incorporating that into the example code provided in the node-imap readme?

I decided to go with the inbox module. This provides a clear and quick solution through use of the call, client.on("new", function(message){.

I think good starting point is to research how is this method created in https://www.npmjs.com/package/inbox#wait-for-new-messages module.
Looks like this code emits the event of new.
As far as i understood the code of this module, they call the fetch command with intervals

For node-imap, "mail" event will be emitted when new mail arrives in the currently open mailbox.
You can listen to new mail event like this:
imap.on('mail', function(numNewMsgs) {
// Fetch new mail
});

You need to open a mailbox, which you want to listen for new messages. Here an example:
function listerBox() {
imap.once("error", console.error);
imap.on("ready", () => {
imap.openBox("INBOX", true, (error, box) => {
if (error) throw error;
console.log('Connected!')
imap.on("mail", () => {
console.log("New one!")
})
});
});
imap.connect();
}
listerBox()

Related

How to send welcome message AND load a specific dialog automatically in Microsoft Bot Framework v.3 (Node.js)?

I'm trying both to show a welcome message when my bot starts up and also load a specific dialog. We are using version 3 in the company where I'm working (I know, it's old and not supported).
As far as the welcome message, https://learn.microsoft.com/en-us/azure/bot-service/nodejs/bot-builder-nodejs-handle-conversation-events?view=azure-bot-service-3.0 says to use on conversationUpdate, which works fine, but this seems to be contradicted by https://blog.botframework.com/2018/07/12/how-to-properly-send-a-greeting-message-and-common-issues-from-customers/, which suggests one should not use conversationUpdate, except when using DirectLine, but instead send an event. Is this the final word on the matter? Is there a better way?
I'd also like to load a dialog automatically after the welcome message. How do I do this? Can I access the session during the 'on conversationUpdate' event above and load the dialog directly there? Is there a better way?
Thanks for any help!
It is contradictory, but conversationUpdate is likely your best bet in most situations. However, because channels handle this differently, you should be aware that the result can vary. For direct line, it is a better option to utilize sending events.
An example, in case of need:
bot.on('conversationUpdate', function(message) {
if (message.membersAdded) {
message.membersAdded.forEach(function(identity) {
if (identity.id === message.address.bot.id) {
var reply = new builder.Message()
.address(message.address)
.text("Welcome");
bot.send(reply);
}
});
}
});
For immediately calling a specific dialog, do this:
bot.on('conversationUpdate', function (message) {
if (message.membersAdded) {
message.membersAdded.forEach(function (identity) {
if (identity.id === message.address.bot.id) {
bot.beginDialog(message.address, '/main');
}
});
}
});
bot.dialog('/main', [
function (session, args, next) {
session.send("Glad you could join.");
session.beginDialog('/next');
}
]);
Simply combine the two for sending the welcome message and starting up a dialog.
Hope of help!

node-imap : : How to directly fetch an email that has arrived instead of using a search filter

I have written a wrapper over node-imap(https://github.com/mscdex/node-imap). Currently I am using the since flag to search for emails that arrive in a particular Inbox. For each email that I listen I call upon a imap.search() method and then imap.fetch() method. Is it possible to directly fetch the emails without the imap.search() method.
Providing snippets from my current code.
self.imap.on("mail", function(id) {
self.parseUnreadEmails(time)
});
MailListener.prototype.parseUnreadEmails = function(time) {
var self = this;
self.imap.search([["SINCE", time]], function(error, searchResults) {
var fetch;
if (error) {
self.emit("error", error);
} else {
fetch = self.imap.fetch(searchResults, {
bodies: '',
markSeen: true
})
}
//do some action
}
}
If you are looking to monitor and fetch new mails arriving for a particular mailbox there are many ways you can do this, below are some ideas that are effective that can be used.
Using IDLE command - yes, using this command you can put a folder in idle state and watch for EXISTS/EXPUNGE responses whenever new mails arrive or if there are any flag changes. Do read this RFC . Once constraint using IDLE command is that you have to have a dedicated tcp connection for this for a particular folder, multiple folders can not be monitored in single IDLE command.
Polling STATUS (UIDNEXT MESSAGECOUNT) command frequently on reasonable interval. This will tell you the uidnext(if there is any change from previous value you should find the difference and fetch those mails).Before proceeding read the IMAP RFC carefully.

Chaining with Telegram Bot API (like TriviaBot)

I am creating a TriviaBot style bot for telegram and am using Node.js to do so. At the moment I am having trouble capturing the users response to my quiz to determine whether the user got the question right or wrong. Below is some code:
bot.onText(/\/quiz/, function (msg) {
var chatId = msg.chat.id;
var text = quizdata.one.msgtxt;
var opts = {
reply_to_message_id: msg.message_id,
reply_markup: JSON.stringify({
keyboard: quizdata.one.keyboard,
one_time_keyboard: true
})
};
bot.sendMessage(chatId, text, opts);
//NEED TO CAPTURE THE USER RESPONSE AND REPLY TO THEIR MESSAGE ACCORDINGLY
});
NOTE : Telegram would cut of any asynchronous function, you should make separated module for listening any incoming interaction with button. You could use global Array for to store small data to be able getting returned for other module you need.
Putting all of your command in the index js not good idea tho.
if you want to listen the from keyboard callback_data. Just create a new line to listen any incoming clicked button.
bot.on("callback_query", (msg) => {
if (msg.data === "your_keyboard_callback_data") {
// do whatever you want
}
})
For more clearance node telegram api
Sorry if my answer is too late for this but hope mine can help other people 🙂

How to get multiple socket attributes in socket.io?

I'm building a chat app on which, for every client connection, i need to set some attributes to every client instance using socket.io. When i save the attribute, i use:
client.set('name', name, function () {});
client.set('email', email, function () {});
....
and it runs fine.
When i need to get all the client properties, i have not found a better way than this:
client.get("name",function(err,name) {
client.get("email",function(err,email) {
.......
}
}
I need to nest all the "get" to asynchronously get data; but if i had 10 properties to get, do i need to nest all the 10 items? There must be a better way to do it, can anyone help me?
I don't attach attributes to the socket.
io.sockets.on('connection', function(socket) {
var username = "xx";
var email = "xx";
socket.on('doX', function(data) {
socket.emit('ackX', {username: username, email: email});
});
});
I don't know if it's the best solution, but I have seen many examples like that.
EDIT : socket.io - getting more than one field for a socket?
The correct answer may fit your needs

Reliable messaging over TCP in node.js

I'm starting a school project in node.js. It's a system that consists of couple of node.js servers connected via TCP sockets.
I tried some TCP libraries (Net module from node itself, nssocket from nodejitsu, now i'm experimenting with zeromq) but they don't seem to have one important feature: message delivery confirmation.
What I would like to have is some kind of library that allows to do something like this:
client.connect(server, port);
client.send(data, function callback(err, res) { ... });
The callback function would be called after the message is delivered or when something bad (timeout, network failure) happens during sending.
I was thinking I would write my own protocol over TCP but I would prefer somethink more robust and tested.
Thanks for any constructive answers :)
It's not really convenient, because what happens when you A->B goes fine, but the receive confirmation fails (B->A)? Anyhow, it's pretty easy to roll your own, something like (pseudo):
Sender
var callbacks = {};
function send (msg, callback) {
// assign unique request id
msg.msgId = uuid.v4();
msg.timestamp = new Date();
callbacks[msg.msgId] = callback;
// send over TCP
}
socket.on("confirmation", function (msg) {
callbacks[msg.msgId](null);
delete callbacks[msg.msgId];
});
// now you'll need some polling mechanism that checks for messages that take
// more than the timeout and clean them
Receiver
socket.on("message", function (msg) {
// send confirmation to sender
socket.emit("confirmation", { msgId: msg.msgId });
});

Resources