Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
npm install nylas
A small example Express app is included in the example
directory. you can run the sample app to see how an authentication flow might be implemented:
cd example
npm install
DEBUG=example:* ./bin/www
Note that you'll need to replace the Nylas App ID and Secret in app.js
with your application's credentials.
Every resource is accessed via an instance of Nylas
. Before making any requests, be sure to call config
and initialize the Nylas
with your App ID
and App Secret
.
var Nylas = require('nylas').config({
appId: 'c96gge1jo29pl2rebcb7utsbp',
appSecret: 'l2rebcb7utsbpc96gge1jo29p'
});
Every resource method accepts an optional callback as the last argument:
Nylas.with(accessToken).threads.list({}, function(err, threads){
console.log(threads.length);
});
Additionally, every resource method returns a promise, so you don't have to use callbacks if the rest of your code is promise-friendly:
Nylas.with(accessToken).threads.list({}).then(function(threads){
console.log(threads.length);
});
The Nylas REST API uses server-side (three-legged) OAuth, and the Node.js bindings provide convenience methods that simplifiy the OAuth process. For more information about authenticating users with Nylas, visit the Developer Documentation
Step 1: Redirect the user to Nylas:
var Nylas = require('nylas').config({
appId: 'c96gge1jo29pl2rebcb7utsbp',
appSecret: 'l2rebcb7utsbpc96gge1jo29p'
});
router.get('/connect', function(req, res, next) {
options = {
redirectURI: 'http://localhost:3000/oauth/callback',
trial: false
}
res.redirect(Nylas.urlForAuthentication(options));
});
Step 2: Handle the Authentication Response:
router.get('/oauth/callback', function (req, res, next) {
if (req.query.code) {
Nylas.exchangeCodeForToken(req.query.code).then(function(token) {
// save the token to the current session, save it to the user model, etc.
});
} else if (req.query.error) {
res.render('error', {
message: req.query.reason,
error: {
status: 'Please try authenticating again or use a different email account.',
stack: ''
}
});
}
});
The Javascript SDK exposes API resources as attributes of the nylas
object. You can query these resources in several ways. Available filters can be found in the API Documentation
var nylas = Nylas.with(accessToken);
// Find the first thread matching the filter criteria
nylas.threads.first({from: 'ben@nylas.com'}).then(function(thread) {
console.log(thread.subject);
console.log(thread.snippet);
})
// Count threads with the inbox tag
nylas.threads.count({tag: 'inbox'}).then(function(count) {
console.log('There are ' + count + 'threads in your Nylas.');
})
// Fetch a single thread
nylas.threads.find('c96gge1jo29pl2rebcb7utsbp').then(function(thread) {
console.log(thread.subject);
}).catch(function(err) {
console.log('Thread not found! Error: ' + err.toString());
});
// Fetch a single thread (using optional callback instead of promise)
nylas.threads.find('c96gge1jo29pl2rebcb7utsbp', function(err, thread) {
if (err) {
console.log('Thread not found! Error: ' + err.toString());
return;
}
console.log(thread.subject);
});
// Iterate over every matching thread. Automatically paginates the underlying API
// as necessary and calls the provided block as threads are received. Calls the final
// block upon an error, or when processing is finished.
nylas.threads.forEach({tag: 'unread', from: 'no-reply@sentry.com'}, function(err, thread) {
console.log(thread.subject);
}, function (err) {
console.log('finished iterating through threads');
});
// Returns an array of all matching threads, paginating the underlying API as necessary.
// May take a long time and return many, many objects if used with a broad filter.
nylas.threads.list({tag: 'inbox'}).then(function(threads) {
});
The new folders and labels API replaces the now deprecated Tags API. It allows you to apply Gmail labels to whole threads or individual messages and, for providers other than Gmail, to move threads and messages between folders.
var nylas = Nylas.with(accessToken);
// List the labels for this account
nylas.labels.list({}).then(function(labels) {
console.log(label.displayName);
console.log(label.id);
})
// The same, with folders.
nylas.folders.list({}).then(function(folders) {
console.log(folder.displayName);
console.log(folder.id);
})
// Create a folder
fld = nylas.folders.build({ displayName: 'Reminders'});
fld.save();
// Add the 'Junk Email' label to a thread.
var label = undefined;
nylas.labels.list({}).then(function(labels) {
for(var i = 0; i < labels.length; i++) {
label = labels[i];
if (label.displayName == 'Junk Email') {
break;
}
}
nylas.threads.list({}, function(err, threads) {
var thread = threads[0];
thread.labels.push(label);
thread.save();
})
// Note that Folders and Labels are absolutely identical from the standpoint of the SDK.
// The only difference is that a message can have many labels but only a single folder.
var nylas = Nylas.with(accessToken);
// to get the metadata of a particular file
var f = nylas.files.build({
id: fileId
});
f.metadata(function(err, data) {
// On success, data looks like:
// {
// "content_type": "application/msword",
// "filename": "Reinstatement of Corporation.doc",
// "id": "9tm2n206vdj29wrhcxfvmvo4o",
// "message_ids": [
// "93mtrpk4uo3wsvwcpb5yh57kp"
// ],
// "account_id": "6aakaxzi4j5gn6f7kbb9e0fxs",
// "object": "file",
// "size": 100864
// }
console.log(data)
});
// for an array of file metadata, build a dummy file with no id
f = nylas.files.build();
f.metadata(function(err, dataArray){
console.log(dataArray);
});
var nylas = Nylas.with(accessToken);
var fs = require('fs');
// Because of a bug in the library we use to issue http requests,
// we can't pass a stream to the file upload function, which is
// why we read the file directly.
fs.readFile(filePath, 'utf8', function (err, data) {
f = nylas.files.build({
filename: filePath,
data: data,
contentType: 'text/plain'
});
f.upload(function(err, file) {
// Create a draft and attach the file to it.
var draft = nylas.drafts.build({
subject: 'Ice-cream',
to: [{email: 'helena@nylas.com'}],
body: 'Hey, find the file attached.',
});
draft.files = [file];
draft.send().then(function(draft) {
console.log(draft.id + ' was sent');
});
});
});
var nylas = Nylas.with(accessToken);
var fs = require('fs');
var f = nylas.files.build({
id: fileId
});
f.download(function(err, file) {
// file contains some headers like 'content-disposition',
// the data is stored in 'body'
fs.writeFile('/tmp/' + file.filename, file.body);
});
var nylas = Nylas.with(accessToken);
var draft = nylas.drafts.build({
subject: 'My New Draft',
to: [{email: 'ben@nylas.com'}]
replyToMessageId: "8i4u7sid2ygvfso9gomu9rcw3" // id of the message we're replying to. When set,
// the Nylas sending API will set specific email
// headers to mark your message as a reply to `message_id`.
});
// Sending the Draft
draft.send().then(function(draft) {
console.log(draft.id + ' was sent');
});
// Saving a Draft
draft.save().then(function(draft) {
console.log(draft.id + ' was saved');
});
// Retrieving and sending a saved draft
var savedId = '1234';
nylas.drafts.find(savedId).then(draft) {
draft.send().then(function (draft) {
console.log('sent!');
});
});
var DELTA_EXCLUDE_TYPES = ['contact', 'calendar', 'event', 'file', 'tag'];
var nylas = Nylas.with(accessToken);
nylas.deltas.latestCursor(function(error, cursor) {
// Save inital cursor.
persistCursor(cursor);
// Start the stream and add event handlers.
var stream = nylas.deltas.startStream(cursor, DELTA_EXCLUDE_TYPES);
stream.on('delta', function(delta) {
// Handle the new delta here.
console.log('Received delta:', delta);
// Save new cursor so this delta doesn't need to be re-fetched for future streams.
persistCursor(delta.cursor);
}).on('error', function(err) {
// Handle errors here, such as by restarting the stream at the last cursor.
console.error('Delta streaming error:', err);
});
// Closing the stream explicitly, if needed
stopButton.addEventListener('click', function() {
stream.close();
});
})
// Create an event and send an invite.
// The Nylas API supports sending invites/updates to the event's participants.
// To do this we need to set the 'notify_participants' parameter to true.
var nylas = Nylas.with(accessToken);
var ev = nylas.events.build({
title: 'Out of time',
calendarId: 'c4y597l3adg8mskfqxxns8hsj',
when: {'start_time': 1437500000, 'end_time': 1437501600},
participants: [{email: 'karim@nylas.com', name: "Karim Hamidou"}]
});
ev.save({'sendNotifications': true}, function(err, event) {
console.log('Sent an invite to the participants');
});
// RSVP to an invite. Note that you can only RSVP to invites found in the
// "Emailed events" calendar.
nylas.events.find('30xunbe3033d44kip9bnau5ph').then(function(ev) {
ev.rsvp('maybe', 'I may attend this event').then(function(ev) {
console.log('RSVP sent!');
});
});
It's possible to get details about the account you're accessing by using the account
method:
var nylas = Nylas.with(accessToken);
nylas.account.get().then(function(model) {
console.log(model);
});
You can also access the billing status for the accounts in your app by using the accounts
method:
Nylas.accounts.list().then(function(accounts) {
console.log(accounts.length);
for(var i = 0; i < accounts.length; i++) {
console.log(accounts[i].id, accounts[i].billingState, accounts[i].syncState);
}
});
The Nylas Sync Engine is open source, and you can also use the Node SDK with the open source API. Since the open source API provides no authentication or security, connecting to it is simple.
/* This example shows how to fetch messages from the first account
using a version of the Nylas sync engine running locally.
*/
Nylas = require('nylas').config({
appId: 'appId---doesnt matter when running locally',
appSecret: 'appSecret---same',
apiServer: 'http://localhost:5555'
});
/* The open source version of the engine requires us to "auth" to it by
passing the account id as an auth token. Get the account id of the
first account.
*/
Nylas.accounts.first({}, function(err, account) {
var nylas = Nylas.with(account.id).messages.list({limit: 20}, function(err, messages) {
for(var i = 0; i < messages.length; i++) {
console.log(messages[i].subject);
}
});
});
We'd love your help making the Nylas Node.js bindings better. Join the Google Group for project updates and feature discussion. We also hang out on the Nylas community Slack channel, or you can email support@nylas.com.
Please sign the Contributor License Agreement before submitting pull requests. (It's similar to other projects, like NodeJS or Meteor.)
Tests can be run with:
npm test
FAQs
A NodeJS wrapper for the Nylas REST API for email, contacts, and calendar.
The npm package nylas receives a total of 29,177 weekly downloads. As such, nylas popularity was classified as popular.
We found that nylas demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.