Skip to content

Instantly share code, notes, and snippets.

@faceyspacey
Last active June 10, 2019 17:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save faceyspacey/9cdaee9b041fbe55868ad686a13ef3a4 to your computer and use it in GitHub Desktop.
Save faceyspacey/9cdaee9b041fbe55868ad686a13ef3a4 to your computer and use it in GitHub Desktop.
meteor-accounts-twitter-auth
const Twit = Meteor.npmRequire('twit');
Accounts.registerLoginHandler('twitter', function(params) {
const data = params.twitter;
// If this isn't twitter login then we don't care about it. No need to proceed.
if (!data) {
return undefined;
}
let {authToken, authTokenSecret} = data;
const fields = ['id', 'email', 'screen_name', 'name', 'location', 'verified', 'lang', 'description', 'utc_offset', 'time_zone', 'followers_count', 'profile_image_url', 'profile_image_url_https', 'profile_background_url', 'profile_background_url_https'];
// Get our user's identifying information. This also checks if the accessToken
// is valid. If not it will error out.
const identity = getIdentity(authToken, authTokenSecret, fields);
// Search for an existing user with that facebook id
const existingUser = Meteor.users.findOne({ 'services.twitter.id': identity.id });
let userId;
if (existingUser) {
userId = existingUser._id;
// Update our data to be in line with the latest from Twitter
const prefixedData = {};
_.each(fields, (val, key) => {
prefixedData[`services.twitter.${key}`] = val;
});
let modifier = {$set: prefixedData};
if(identity.email) { //email is only supplied by Twitter API if your app has received approval to retreive emails
modifier.$addToSet = { emails: { address: identity.email, verified: true } };
}
Meteor.users.update(userId, modifier);
} else {
// Create our user
let doc = {
services: {
twitter: identity
},
profile: { name: identity.name },
}
if(identity.email) {
doc.emails = [{
address: identity.email,
verified: true
}];
}
if(Accounts._onCreateUserHook) {
doc = Accounts._onCreateUserHook(params, doc);
}
userId = Meteor.users.insert(doc);
}
return { userId: userId };
});
const getIdentity = (authToken, authTokenSecret, fields) => {
let twitter = new Twit({
consumer_key: Meteor.settings.twitter.consumerKey,
consumer_secret: Meteor.settings.twitter.secret,
access_token: authToken,
access_token_secret: authTokenSecret,
timeout_ms: 30*1000, //optional HTTP request timeout to apply to all requests.
});
try {
let getSync = Meteor.wrapAsync(twitter.get.bind(twitter));
let res = getSync('account/verify_credentials', {include_email: true, skip_status: true});
return fields.reduce((identity, field) => {
identity[field] = res[field];
return identity;
}, {authToken, authTokenSecret});
} catch (err) {
throw new Error("Failed to fetch identity from Twitter. " + err.message);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment