byeokim / gmailpush Goto Github PK
View Code? Open in Web Editor NEWGmail API push notification handler for Node.js
License: MIT License
Gmail API push notification handler for Node.js
License: MIT License
Hi, if you have time, can you make a video for this :( This too hard to use for me, I think.
I've recently installed Gmailpush API and so far I'm unable to get email push notifications. The code is very identical to the request sample code from your readme section:
require('dotenv').config();
const jsonToken = require('./token.json');
const Gmailpush = require('gmailpush');
const express = require('express');
const app = express();
// Initialize with OAuth2 config and Pub/Sub topic
const gmailpush = new Gmailpush({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
pubsubTopic: process.env.TOPIC_URL
});
const users = [
{
email: process.env.EMAIL,
token: {
access_token: jsonToken.access_token,
refresh_token: jsonToken.refresh_token,
scope: jsonToken.scope,
token_type: jsonToken.token_type,
expiry_date: jsonToken.expiry_date
}
}
];
app.post(
// Use URL set as Pub/Sub Subscription endpoint
'/pubsub',
// Parse JSON request payload
express.json(),
(req, res) => {
// Acknowledge Gmail push notification webhook
res.sendStatus(200); // added .end()
console.log('request', req.body); // added this
// Get Email address contained in the push notification
const email = gmailpush.getEmailAddress(req.body);
console.log('email', email); //added this
// Get access token for the Email address
const token = users.find((user) => user.email === email).token;
gmailpush
.getMessages({
notification: req.body,
token,
withLabelIds: ['UNREAD']
})
.then((messages) => {
console.log('messages', messages);
fs.readFile('./gmailpush_history.json')
.then((result) => {
const prevHistories = JSON.parse(result);
const prevHistory = prevHistories.find((prevHistory) => prevHistory.emailAddress === email);
schedule.scheduleJob(new Date(prevHistory.watchExpiration - 1000 * 60 * 30), async () => {
prevHistory.watchExpiration = await gmailpush._refreshWatch();
fs.writeFile('./gmailpush_history.json', JSON.stringify(prevHistories));
});
});
})
.catch((err) => {
console.log(err);
});
}
);
app.listen(3002, () => {
console.log('Server listening on port 3002...');
});
I tried sending a test email from my dashboard (https://console.cloud.google.com/cloudpubsub/topic/) and noticed the following errors in my nodejs server console log:
It seems these errors are caused by: const email = gmailpush.getEmailAddress(req.body);
ubuntu@vps1:~/gmailpush$ node index.js
Server listening on port 3002...
request {
message: {
data: 'SGVsbG8gV09STEQ=',
messageId: '6340826340304395',
message_id: '6340826340304395',
publishTime: '2022-11-22T14:55:21.828Z',
publish_time: '2022-11-22T14:55:21.828Z'
},
subscription: 'projects/{hidden}/subscriptions/GmailAPIPush-sub'
}
SyntaxError: Unexpected token H in JSON at position 0
at JSON.parse (<anonymous>)
at Gmailpush._parseNotificationPayload (/home/ubuntu/gmailpush/node_modules/gmailpush/lib/gmailpush.js:43:17)
at Gmailpush.getEmailAddress (/home/ubuntu/gmailpush/node_modules/gmailpush/lib/gmailpush.js:59:17)
at /home/ubuntu/gmailpush/index.js:39:29
at Layer.handle [as handle_request] (/home/ubuntu/gmailpush/node_modules/express/lib/router/layer.js:95:5)
at next (/home/ubuntu/gmailpush/node_modules/express/lib/router/route.js:144:13)
at /home/ubuntu/gmailpush/node_modules/body-parser/lib/read.js:137:5
at AsyncResource.runInAsyncScope (node:async_hooks:203:9)
at invokeCallback (/home/ubuntu/gmailpush/node_modules/raw-body/index.js:231:16)
at done (/home/ubuntu/gmailpush/node_modules/raw-body/index.js:220:7)
I followed the example code provided line for line, but it didn't seem like the topic was ever getting watched (and no history file was created). I debugged a little bit, and I don't think this._initialize()
is being called using the setup that was provided in the readme. I'm sure I'm missing something simple, but any help on this?
From poking around the source code, I noticed that the initialize function takes in a notification, but I'm still not sure when it's meant to be called
Hi I getting this, I don't understand why :( Can you give me an idea?
{"data":"[{\"emailAddress\":\"[email protected]\",\"prevHistoryId\":60039,\"watchExpiration\":null},{\"emailAddress\":\"[email protected]\",\"prevHistoryId\":60134,\"watchExpiration\":null},{\"emailAddress\":\"[email protected]\",\"prevHistoryId\":60143,\"watchExpiration\":null} // but this not, i dont understand why,{\"emailAddress\":\"[email protected]\",\"prevHistoryId\":6141093,\"watchExpiration\":1607275262534}]"} // this work fine
Hi, is there a way to mark processed email as read, when this email has been forwarded to the google pub/sub? to avoid re-reading the email & re-processing the same email twice? thanks.
Hi did you see this error?
at Gmailpush._initialize (D:\Job\MyApp\node_modules\gmailpush\lib\gmailpush.js:114:33)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async Gmailpush.getMessagesWithoutAttachment (D:\Job\Sell-theme\node_modules\gmailpush\lib\gmailpush.js:476:27)
at async Gmailpush.getMessages (D:\Job\Sell-theme\node_modules\gmailpush\lib\gmailpush.js:546:22)
at async Array.<anonymous> (D:\Job\Sell-theme\.next\server\static\development\pages\api\google\pubsub-push.js:1366:3)
I managed to get this set up using the example code you provided almost-exactly, but for some reason, whenever there's a new email, the getMessages
call consistently errors out with the message Requested entity was not found.
If I open the message on the gmail interface (and consequently mark it as read), I get another notification and this one goes through and returns an array of length 1 with the message as expected.
Any idea why this is happening?
My application has a status of 'Testing' and the consent screen is configured for an external user type, causing the token to expire in 7 days.
How to automatically refresh the access token on the next API call after it expires?
Currently, I'm manually generating the access token with the following code:
require('dotenv').config();
const readline = require('readline');
const {google} = require('googleapis');
function getToken() {
const auth = new google.auth.OAuth2(
process.env.CLIENT_ID,
process.env.CLIENT_SECRET,
'urn:ietf:wg:oauth:2.0:oob'
);
const authUrl = auth.generateAuthUrl({
access_type: 'offline',
scope: ['https://www.googleapis.com/auth/gmail.readonly'],
});
console.log('Authorize this app by visiting this url:');
console.log(authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (authCode) => {
rl.close();
auth.getToken(authCode, (err, token) => {
if (err) {
return console.log('Error retrieving access token', err);
}
console.log('Token:');
console.log(token);
});
});
}
getToken();
Can you please advice? thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.