As with any kind of app, there are difficult issues to solve when we write Node apps. In this article, we’ll look at some solutions to common problems when writing Node apps.
Wait for an Element to be Visible with Puppeteer
To wait for an element to be visible, we can use the waitForSelector
method.
For example, we can write:
page.waitForSelector('#myId', { visible: true })
This waits for the element with the ID myId
to be in the DOM.
visible
is true
ensures that it’s visible before waiting stops.
Minimize or Close Window to the System Tray and Restore Window Back from Tray
To minimize the window to the system tray, we can write:
const BrowserWindow = require('browser-window'),
`
const mainWindow = new BrowserWindow({
width: 650,
height: 650,
title: "window",
icon:'./icon.png'
});
`
mainWindow.on('minimize',(event) => {
event.preventDefault();
mainWindow.hide();
});
`
mainWindow.on('close', (event) => {
if(!application.isQuiting){
event.preventDefault();
mainWindow.hide();
}
return false;
});
We call event.preventDefault
to prevent the default minimization action when we listen to the minimize
event. Then we call hide
to hide it in the tray.
We do the same thing when we listen to the close
event. If the app isn’t quitting, then we call preventDefault
to prevent it from quitting. Then we call mainWindow.hide()
to hide it instead. To restore from the tray, we add new menu entries that we can click to restore the window when we click.
For example, we write:
const contextMenu = Menu.buildFromTemplate([
{
label: 'restore app',
click(){
mainWindow.show();
}
},
{
label: 'exit',
click(){
application.isQuiting = true;
application.quit();
}
}
]);
We call buildFromTemplate
with an array to create a context menu.
It has one entry to call mainWindow.show()
to show the mainWindow
.
And we have an entry that we click to exit the app with application.quit()
.
OAuth Authentication with the Twitter API and Express
We can add Twitter authentication to our Express app by using the oauth
library with Express. First, we fill in the callback URL with the URL that we want to invoke when authentication is done. It should be set to /session/callback
if the example below is used.
Then we write:
const express = require('express');
const oauth = require('oauth');
const session = require('express-session');
const cookieParser = require('cookie-parser');
const app = express.createServer();
`
const twitterConsumerKey = "1";
const twitterConsumerSecret = "2";
const consumer = new oauth.OAuth(
"https://twitter.com/oauth/request_token",
"https://twitter.com/oauth/access_token",
twitterConsumerKey,
twitterConsumerSecret,
"1.0A",
"http://127.0.0.1:8080/sessions/callback",
"HMAC-SHA1"
);
`
app.use(cookieParser());
app.use(session({
secret: "very secret"
}));
`
app.use((req, res, next) => {
res.locals.user = req.session.user;
next();
});
`
app.get('/sessions/connect', (req, res) =>{
consumer.getOAuthRequestToken((error, oauthToken, oauthTokenSecret, results) => {
if (error) {
res.send(error, 500);
} else {
req.session.oauthRequestToken = oauthToken;
req.session.oauthRequestTokenSecret = oauthTokenSecret;
res.redirect(`https://twitter.com/oauth/authorize?oauth_token=${req.session.oauthRequestToken}`);
}
});
});
`
app.get('/sessions/callback', (req, res) => {
consumer.getOAuthAccessToken(
req.session.oauthRequestToken,
req.session.oauthRequestTokenSecret,
req.query.oauth_verifier,
(error, oauthAccessToken, oauthAccessTokenSecret, results) => {
if (error) {
res.send('Error', 500);
} else {
req.session.oauthAccessToken = oauthAccessToken;
req.session.oauthAccessTokenSecret = oauthAccessTokenSecret;
res.redirect('/home');
}
});
});
`
app.get('/home', (req, res) => {
consumer.get(
"http://twitter.com/account/verify_credentials.json",
req.session.oauthAccessToken,
req.session.oauthAccessTokenSecret,
(error, data, response) => {
if (error) {
res.redirect('/sessions/connect');
} else {
const parsedData = JSON.parse(data);
res.send(parsedData.screen_name);
}
});
});
`
app.get('*', (req, res) => {
res.redirect('/home');
});
`
app.listen(8080);
We use the oauth
package’s oauth.OAuth
constructor to set the keys and secrets required for Twitter OAuth. Those can be gotten from the Twitter developer website. The /sessions/connect
route is where we go to log in with Twitter. We call the getOAuthRequestToken
to get the OAuth request token. The callback in that method redirects us to the Twitter auth page.
Once we log in, then we’re redirected to the /session/callback
route if we set the callback URL to that. It sets the OAuth access token secret and the access token so that we can authenticate with the Twitter API.
Then we when go to the /home
route, we authenticate with the access token that we obtained since they’re set as the properties of req.session
in the /session/callback
route. We used Express session and Cookie Parser to manage the session.
Conclusion
We can do OAuth with Twitter by using the oauth
package. Also, we can wait for elements to appear with Puppeteer before proceeding. And we can minimize a window to the system tray and restore it.