Commit 06383dfd authored by Iván Sánchez Ortega's avatar Iván Sánchez Ortega

Added twitter auth mechanism

parent 973661ae
......@@ -15,6 +15,7 @@
"mastodon-api": "^1.1.1",
"oauth": "^0.9.15",
"striptags": "^3.0.1",
"twitter": "^1.7.0",
"vorpal": "^1.11.4"
},
"scripts": {
......
......@@ -5,5 +5,8 @@ export { clock };
import * as mastodon from './mastodon';
export { mastodon };
import * as twitter from './twitter';
export { twitter };
import Account from '../abstracts/account';
import inquirer from 'inquirer';
import { OAuth } from 'oauth';
import chalk from 'chalk256';
import Twitter from 'twitter';
import striptags from 'striptags';
import he from 'he';
const soclialConsumerKey = 'xiUNN9g7K8it8QIXcA';
const soclialConsumerSecret = 'qsFwbc6gXtcHAplAXjfoKXu96hVXz82W7sEbzuLR2U';
// 🍂class TwitterAccount
// 🍂inherits Account
// Support for the Mastodon microblogging federated network.
class TwitterAccount extends Account {
constructor(callback, vorpal, opts) {
// this._timers = {};
this._opts = Object.assign({
// colour: 'grey'
}, opts);
this._tw = new Twitter({
consumer_key: soclialConsumerKey,
consumer_secret: soclialConsumerSecret,
access_token_key: opts.clientId,
access_token_secret: opts.clientSecret
});
this._vorpal = vorpal;
this._tw.get('account/verify_credentials', {}, (err, json)=>{
vorpal.log(json);
vorpal.log(
chalk.purple('You are logged in the Twitter platform as '),
chalk.cyan(json.screen_name),
// chalk.purple(' in server '),
// chalk.cyan(opts.api_url.replace(/.*:\/\//,'').replace(/\/.*/, '')),
chalk.purple(', account badge is '),
chalk.cyan(opts.badge)
);
});
/*.then(response=>response.json()).*/
// .then(json=> {
// console.log(chalk.purple('>>> Mastodon account credentials: '), json);
// // Hackishly listen to the public timeline
// let userListener = this._tw.stream('streaming/user');
// userListener.on('message', this._getOnStreamMessage('user'));
// userListener.on('error', err => {
// vorpal.log(chalk.red.bold(err));
// });
//
// this._tw.get('statuses/user_timeline', (err, msgs, response) =>{
// for (let i=msgs.length-1; i>=0; i--) {
// this._normalizeAndEmitUpdate('home', msgs[i]);
// // vorpal.log('statuses/user_timeline', msgs);
// }
// });
//
// this._tw.get('notifications', (err, msgs, response) =>{
// // vorpal.log('notifications', err, msgs/*, response*/);
// // vorpal.log(response.toJSON());
//
// for (let i=msgs.length-1; i>=0; i--) {
// this._normalizeAndEmitNotification('notifications', msgs[i]);
// // vorpal.log('timelines/notifications', msgs);
// }
// });
// let publicListener = this._tw.stream('streaming/public');
// publicListener.on('message', this._getOnStreamMessage('public'));
// publicListener.on('error', err => {
// vorpal.log(chalk.red.bold(err));
// });
/* A update msg looks like:
{ event: 'update',
data:
{ id: 2133504,
created_at: '2017-04-10T08:36:36.000Z',
in_reply_to_id: null,
in_reply_to_account_id: null,
sensitive: false,
spoiler_text: '',
visibility: 'public',
application: null,
account:
{ id: 52132,
username: 'Milady_Oscar',
acct: 'Milady_Oscar@oc.todon.fr',
display_name: 'Lady Oscar ',
locked: false,
created_at: '2017-04-05T15:18:04.424Z',
note: 'Un peu de vous et beaucoup de n\'importe moi, des trucs de filles, des blagues de mecs, et des fraises tagada.\nSur Twitter avec le même @ ',
url: 'https://oc.todon.fr/@Milady_Oscar',
avatar: 'https://files.mastodon.social/accounts/avatars/000/052/132/original/5d55de1a7e19b927.PNG?1491405483',
header: 'https://files.mastodon.social/accounts/headers/000/052/132/original/6e2afd6a5009629b.PNG?1491405483',
followers_count: 22,
following_count: 15,
statuses_count: 686
},
media_attachments: [],
mentions: [],
tags: [],
uri: 'tag:oc.todon.fr,2017-04-10:objectId=160722:objectType=Status',
content: '<p>Je sens bien le barbecue aujourd\'hui. Mais j\'ai pas acheté de charbon de bois. J\'ai envie de prendre Marine Le Pen à la place.</p>',
url: 'https://oc.todon.fr/users/Milady_Oscar/updates/11367',
reblogs_count: 0,
favourites_count: 0,
reblog: null
}
}
*/
// });
return super.constructor(callback, opts);
}
listen(channel) {
/*
this._timers[ channel ] = setTimeout(()=>{
}, delay - msSinceLastTick);
*/
}
unlisten(channel) {
// channel = Number(channel);
// if (channel <= 0) return;
//
// delete this._timers[ channel ];
//
// return this;
}
listChannels() {
// return ['home', 'notifications', 'public'];
}
getLastUpdateTimestamp() {
// return Date.now();
}
_cleanString(str) {
return striptags( he.decode( str.replace('</p><p>', ' // ') ) );
}
// Given a stream descriptor, return a function that handles messages from the stream
_getOnStreamMessage(stream) {
return (msg)=>{
// this._vorpal.log(chalk.green(msg));
if (msg.event === 'update') {
this._normalizeAndEmitUpdate(stream, msg.data);
} else if (msg.event === 'notification') {
this._normalizeAndEmitNotification(stream, msg.data);
} else {
this._vorpal.log(chalk.green(msg));
}
}
}
// Get a Mastodon update, normalizes some stuff (to make different platforms
// see the same data from different platforms), and emits the update.
_normalizeAndEmitUpdate(channel, msg) {
// console.log('normalizing: ', msg);
this.emit({
sender: msg.account.acct,
str: this._cleanString(msg.content),
channel: channel,
// realtime: true,
media: msg.media_attachments.map(i=>i.text_url || i.remote_url),
timestamp: Date.parse(msg.created_at)
}, msg);
// if (msg.mentions) {
// vorpal.log('Mentions: ', msg.mentions);
// }
// if (msg.media_attachments.length) {
// this._vorpal.log('Media: ', msg.media_attachments);
// }
// if (msg.tags) {
// vorpal.log('Tags: ', msg.tags);
// }
/// FIXME!!!
if (msg.spoiler_text) {
this._vorpal.log('Spoiler: ', msg.spoiler_text);
}
if (msg.reblog) {
this._vorpal.log('FIXME: This is a RT/echo of another status');
this._normalizeAndEmitUpdate(channel, msg.reblog);
}
}
_normalizeAndEmitNotification(channel, msg) {
if (msg.type === 'follow') {
this.emit({
str: chalk.bold(msg.account.acct) + ' started following you.',
channel: channel,
timestamp: Date.parse(msg.created_at)
});
} else if (msg.type === 'reblog') {
this.emit({
str: chalk.bold(msg.account.acct) + ' echoed your update: ' + this._cleanString(msg.status.content),
channel: channel,
timestamp: Date.parse(msg.created_at)
});
} else if (msg.type === 'favourite') {
this.emit({
str: chalk.bold(msg.account.acct) + ' favourited your update: ' + this._cleanString(msg.status.content),
channel: channel,
timestamp: Date.parse(msg.created_at)
});
} else if (msg.type === 'mention') {
this.emit({
str: chalk.bold(msg.account.acct) + ' mentioned you ' + this._cleanString(msg.status.content),
channel: channel,
timestamp: Date.parse(msg.created_at)
});
} else {
this._vorpal.log('channel', msg);
}
}
}
// signUp returns a Promise for a set of options. If the promise resolves, these options
// will be saved into the user preferences, then a new instance of this platform's `Account`
// will be instantiated.
export function signUp() {
return new Promise( (resolve, reject) => {
/// Twitter only has one known API endpoint, no need to handle this.
let server = 'api.twitter.com';
let oauth = new OAuth(
"https://" + server + "/oauth/request_token",
"https://" + server + "/oauth/access_token",
soclialConsumerKey,
soclialConsumerSecret,
"1.0A",
'oob',
"HMAC-SHA1"
);
// console.log('oauth instance: ', oauth);
oauth.getOAuthRequestToken( (error, oauthToken, oauthTokenSecret, oauthAuthorizeUrl, additionalParameters )=>{
if(error) {
return reject( 'Error retrieving the OAuth Request Token: ' + JSON.stringify(error) );
}
// console.log('Successfully retrieved the OAuth Request Token:', oauthToken,
// ', secret: ', oauthTokenSecret,
// ', auth url:', oauthAuthorizeUrl);
let url = "http://" + server + "/oauth/authenticate?oauth_token=" + oauthToken;
console.log( chalk.bold('In order to add a new Twitter account, visit ', chalk.underline(url), ' to get a verification code.') );
return inquirer.prompt([{
type: 'input',
name: 'code',
message: 'Enter verification code: '
}]).then((answer)=>{
if (!answer.code) {
return reject('No verification code was introduced.');
}
// console.log('We got verification code:', answer.code);
oauth.getOAuthAccessToken(
oauthToken,
oauthTokenSecret,
answer.code,
function( error, oauthClientToken, oauthClientSecret, additionalParameters ) {
if( error ) {
return reject( 'Error retrieving the OAuth Client Token: ' + JSON.stringify(error) );
}
return resolve({
clientId: oauthClientToken,
clientSecret: oauthClientSecret
});
}
);
});
reject();
});
});
}
export const defaultBadge = 'tw';
export const name = 'twitter';
export { TwitterAccount as Account };
......@@ -309,6 +309,10 @@ debug@^2.1.1:
dependencies:
ms "0.7.2"
deep-extend@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253"
deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
......@@ -1273,7 +1277,7 @@ replace-ext@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924"
request@^2.81.0:
request@^2.72.0, request@^2.81.0:
version "2.81.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
dependencies:
......@@ -1553,6 +1557,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
twitter@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/twitter/-/twitter-1.7.0.tgz#2882e208e0ad83bb226528613561f1dd233ac94b"
dependencies:
deep-extend "^0.4.1"
request "^2.72.0"
type-check@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment