diff --git a/app.js b/app.js index 7bf4c53..34514a9 100644 --- a/app.js +++ b/app.js @@ -1,3 +1,7 @@ +if ( !process.env.PROJECT_NAME || !process.env.PROJECT_ID ){ + require( 'dotenv' ).config(); +} + const path = require( 'path' ), express = require( 'express' ), session = require( 'express-session' ), diff --git a/bot/bot-copy.js b/bot/bot-copy.js index 950dd5c..72b3318 100644 --- a/bot/bot-copy.js +++ b/bot/bot-copy.js @@ -1,54 +1,58 @@ -const fs = require( 'fs' ), - crypto = require( 'crypto' ), - url = require( 'url' ), - util = require( 'util' ), - moment = require( 'moment' ), - dbHelper = require( __dirname + '/../helpers/db.js' ), - keys = require( __dirname + '/../helpers/keys.js' ), - request = require( 'request' ), - publicKeyPath = '.data/rsa/pubKey', - privateKeyPath = '.data/rsa/privKey', - botURL = `https://${ process.env.PROJECT_DOMAIN }.glitch.me`, - botComposeReply = require( __dirname + '/responses.js' ); +if ( !process.env.PROJECT_NAME || !process.env.PROJECT_ID ){ + require( 'dotenv' ).config(); +} + +const fs = require('fs'), + crypto = require('crypto'), + url = require('url'), + util = require('util'), + moment = require('moment'), + dbHelper = require(__dirname + '/../helpers/db.js'), + keys = require(__dirname + '/../helpers/keys.js'), + request = require('request'), + public_key_path = '.data/rsa/pubKey', + private_key_path = '.data/rsa/privKey', + bot_url = `https://${process.env.PROJECT_DOMAIN}.glitch.me`, + botComposeReply = require(__dirname + '/responses.js'); -if ( !fs.existsSync( publicKeyPath ) || !fs.existsSync( privateKeyPath ) ) { - keys.generateKeys( function( ){ - process.kill( process.pid ); - } ); +if (!fs.existsSync(public_key_path) || !fs.existsSync(private_key_path)) { + keys.generateKeys(function(){ + process.kill(process.pid); + }); } else{ - let publicKey = fs.readFileSync( publicKeyPath, 'utf8' ), - privateKey = fs.readFileSync( privateKeyPath, 'utf8' ); + var public_key = fs.readFileSync(public_key_path, 'utf8'), + private_key = fs.readFileSync(private_key_path, 'utf8'); module.exports = { - bot_url: botURL, + bot_url: bot_url, links: [ // { // rel: 'http://webfinger.net/rel/profile-page', // type: 'text/html', - // href: `${ botURL }` + // href: `${bot_url}` // }, // { // rel: 'http://schemas.google.com/g/2010#updates-from', // type: 'application/atom+xml', - // href: `${ botURL }/feed` + // href: `${bot_url}/feed` // }, { rel: 'self', type: 'application/activity+json', - href: `${ botURL }/bot` + href: `${bot_url}/bot` }, // { // rel: 'hub', - // href: `${ botURL }/pubsub` + // href: `${bot_url}/pubsub` // }, // { // rel: 'salmon', - // href: `${ botURL }/salmon` + // href: `${bot_url}/salmon` // }, // { // rel: 'magic-public-key', - // href: `data:application/magic-public-key,RSA.${ publicKey.replace( '-----BEGIN PUBLIC KEY-----\n', '' ).replace( '\n-----END PUBLIC KEY-----', '' ).replace( '\\n', '' ) }` + // href: `data:application/magic-public-key,RSA.${public_key.replace('-----BEGIN PUBLIC KEY-----\n', '').replace('\n-----END PUBLIC KEY-----', '').replace('\\n', '')}` // } ], info: { @@ -56,7 +60,7 @@ else{ 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1' ], - 'id': `${ botURL }/bot`, + 'id': `${bot_url}/bot`, 'icon': [{ 'url': process.env.BOT_AVATAR_URL, 'type': 'Image' @@ -68,225 +72,224 @@ else{ 'type': 'Person', 'name': process.env.BOT_USERNAME, 'preferredUsername': process.env.BOT_USERNAME, - 'inbox': `${ botURL }/inbox`, + 'inbox': `${bot_url}/inbox`, 'publicKey': { - 'id': `${ botURL }/bot#main-key`, - 'owner': `${ botURL }/bot`, - 'publicKeyPem': publicKey + 'id': `${bot_url}/bot#main-key`, + 'owner': `${bot_url}/bot`, + 'publicKeyPem': public_key } }, - // script: botScript, script: require( __dirname + '/script.js' ), composeReply: botComposeReply, - sendReply: function( options, cb ){ - let bot = this, - replyToUsername = ''; + sendReply: function(options, cb){ + var bot = this, + reply_to_username = ''; try{ - let actor_url_parts = options.payload.actor.split( '/' ); - let username = actor_url_parts[actor_url_parts.length-1]; - replyToUsername = `@${ username }@${ url.parse( options.payload.actor ).hostname } `; + var actor_url_parts = options.payload.actor.split('/'); + var username = actor_url_parts[actor_url_parts.length-1]; + reply_to_username = `@${username}@${url.parse(options.payload.actor).hostname} `; - console.log( {replyToUsername} ); - } catch( err ){ /*noop*/ } + console.log({reply_to_username}); + } catch(err){ /*noop*/ } - bot.createPost( { + bot.createPost({ type: 'Note', - content: `
${ options.payload.object.content }${ options.payload.object.url }

${ options.reply_message }

`, - reply_message: `${ replyToUsername } ${ options.reply_message}`, + content: `
${options.payload.object.content}${options.payload.object.url}

${options.reply_message}

`, + reply_message: `${reply_to_username} ${options.reply_message}`, in_reply_to: options.payload.object.url - }, function( err, message ){ - // console.log( err, message ); - } ); + }, function(err, message){ + // console.log(err, message); + }); }, - createPost: function( options, cb ){ - let bot = this; + createPost: function(options, cb){ + var bot = this; - if ( ( !options.content || options.content.trim( ).length === 0 ) && !options.attachment ){ - console.log( 'error: no post content or attachments' ); + if ((!options.content || options.content.trim().length === 0 ) && !options.attachment ){ + console.log('error: no post content or attachments'); return false; } - let post_type = options.type || 'Note', + var post_type = options.type || 'Note', post_description = options.description, - post_date = moment( ).format( ), + post_date = moment().format(), post_in_reply_to = options.in_reply_to || null, reply_message = options.reply_message || null, post_content = options.content || options.url || '', - post_attachment = JSON.stringify( options.attachment ) || '[]'; + post_attachment = JSON.stringify(options.attachment) || '[]'; - dbHelper.savePost( { + dbHelper.savePost({ type: post_type, content: post_content, attachment: post_attachment - }, function( err, data ){ - let post_id = data.lastID; + }, function(err, data){ + var post_id = data.lastID; - let post_object; + var post_object; - if ( post_type === 'Note' ){ + if ( post_type === 'Note' ){ post_object = { - 'id': `${ botURL }/post/${ post_id }`, + 'id': `${bot_url}/post/${post_id}`, 'type': post_type, 'published': post_date, - 'attributedTo': `${ botURL }/bot`, + 'attributedTo': `${bot_url}/bot`, 'content': reply_message || post_content, 'to': 'https://www.w3.org/ns/activitystreams#Public' }; - if ( options.attachment ){ - let attachments = []; + if (options.attachment){ + var attachments = []; - options.attachment.forEach( function( attachment ){ - attachments.push( { + options.attachment.forEach(function(attachment){ + attachments.push({ 'type': 'Image', 'content': attachment.content, 'url': attachment.url - } ); - } ); + }); + }); post_object.attachment = attachments; } } - if ( post_in_reply_to ){ + if (post_in_reply_to){ post_object.inReplyTo = post_in_reply_to; } - let post = { + var post = { '@context': 'https://www.w3.org/ns/activitystreams', - 'id': `${ botURL }/post/${ post_id }`, + 'id': `${bot_url}/post/${post_id}`, 'type': 'Create', - 'actor': `${ botURL }/bot`, + 'actor': `${bot_url}/bot`, 'object': post_object } - console.log( {post_in_reply_to} ); + console.log({post_in_reply_to}); - dbHelper.getFollowers( function( err, followers ){ - if ( followers ){ - console.log( `sending update to ${ followers.length } follower( s )...` ); + dbHelper.getFollowers(function(err, followers){ + if (followers){ + console.log(`sending update to ${followers.length} follower(s)...`); - followers.forEach( function( follower ){ - if ( follower.url ){ - bot.signAndSend( { + followers.forEach(function(follower){ + if (follower.url){ + bot.signAndSend({ follower: follower, message: post - }, function( err, data ){ + }, function(err, data){ - } ); + }); } - } ); + }); } - } ); + }); - if ( cb ){ - cb( null, post ); + if (cb){ + cb(null, post); } - } ); + }); }, - deletePost: function( post_id, follower_url, cb ){ - let bot = this; - // guid = crypto.randomBytes( 16 ).toString( 'hex' ); + deletePost: function(post_id, follower_url, cb){ + var bot = this; + // guid = crypto.randomBytes(16).toString('hex'); - bot.signAndSend( { + bot.signAndSend({ follower: { url: follower_url }, message: { '@context': 'https://www.w3.org/ns/activitystreams', - // 'summary': `${ bot} deleted a post`, - // 'id': `${ bot.bot_url}/${ guid}`, + // 'summary': `${bot} deleted a post`, + // 'id': `${bot.bot_url}/${guid}`, 'type': 'Delete', - 'actor': `${ bot.bot_url }/bot`, - 'object': `${ bot.bot_url }/post/${ post_id }` + 'actor': `${bot.bot_url}/bot`, + 'object': `${bot.bot_url}/post/${post_id}` } - }, function( err, data ){ - if ( cb ){ - cb( err, data ); + }, function(err, data){ + if (cb){ + cb(err, data); } - } ); + }); }, - accept: function( payload, cb ){ - let bot = this, - guid = crypto.randomBytes( 16 ).toString( 'hex' ); + accept: function(payload, cb){ + var bot = this, + guid = crypto.randomBytes(16).toString('hex'); - dbHelper.getEvent( payload.id, function( err, data ){ - // console.log( 'get_event', err, data ); + dbHelper.getEvent(payload.id, function(err, data){ + // console.log('get_event', err, data); - bot.signAndSend( { + bot.signAndSend({ follower: { url: payload.actor }, message: { '@context': 'https://www.w3.org/ns/activitystreams', - 'id': `${ bot.bot_url }/${ guid }`, + 'id': `${bot.bot_url}/${guid}`, 'type': 'Accept', - 'actor': `${ bot.bot_url }/bot`, + 'actor': `${bot.bot_url}/bot`, 'object': payload, } - }, function( err, data ){ - if ( cb ){ - cb( err, payload, data ); + }, function(err, data){ + if (cb){ + cb(err, payload, data); } - console.log( 'saving event', payload.id ) - dbHelper.saveEvent( payload.id ); - } ); + console.log('saving event', payload.id) + dbHelper.saveEvent(payload.id); + }); - } ); -// dbHelper.getEvent( payload.id, function( err, data ){ -// console.log( 'get_event', err, data ); + }); +// dbHelper.getEvent(payload.id, function(err, data){ +// console.log('get_event', err, data); -// if ( !err && !data ){ -// bot.signAndSend( { +// if (!err && !data){ +// bot.signAndSend({ // follower: { // url: payload.actor // }, // message: { // '@context': 'https://www.w3.org/ns/activitystreams', -// 'id': `${ bot.bot_url }/${ guid }`, +// 'id': `${bot.bot_url}/${guid}`, // 'type': 'Accept', -// 'actor': `${ bot.bot_url }/bot`, +// 'actor': `${bot.bot_url}/bot`, // 'object': payload, // } -// }, function( err, data ){ -// if ( cb ){ -// cb( err, payload, data ); +// }, function(err, data){ +// if (cb){ +// cb(err, payload, data); // } -// console.log( 'saving event', payload.id ) -// dbHelper.saveEvent( payload.id ); -// } ); -// } else if ( !err ){ -// console.log( 'duplicate event' ); +// console.log('saving event', payload.id) +// dbHelper.saveEvent(payload.id); +// }); +// } else if (!err){ +// console.log('duplicate event'); // } -// } ); +// }); }, - signAndSend: function( options, cb ){ - let bot = this; - console.log( 'message to sign:' ); - console.log( util.inspect( options.message, false, null, true ) ); + signAndSend: function(options, cb){ + var bot = this; + // console.log('message to sign:'); + // console.log(util.inspect(options.message, false, null, true)); - options.follower.url = options.follower.url.replace( 'http://localhost:3000', 'https://befc66af.ngrok.io' ); + options.follower.url = options.follower.url.replace('http://localhost:3000', 'https://befc66af.ngrok.io'); - if ( options.follower.url && options.follower.url !== 'undefined' ){ - options.follower.domain = url.parse( options.follower.url ).hostname; + if (options.follower.url && options.follower.url !== 'undefined'){ + options.follower.domain = url.parse(options.follower.url).hostname; - let signer = crypto.createSign( 'sha256' ), + var signer = crypto.createSign('sha256'), d = new Date(), - string_to_sign = `( request-target ): post /inbox\nhost: ${ options.follower.domain}\ndate: ${ d.toUTCString() }`; + string_to_sign = `(request-target): post /inbox\nhost: ${options.follower.domain}\ndate: ${d.toUTCString()}`; - signer.update( string_to_sign ); - signer.end( ); + signer.update(string_to_sign); + signer.end(); - let signature = signer.sign( privateKey ); - let signatureB64 = signature.toString( 'base64' ); - let header = `keyId="${ botURL }/bot",headers="( request-target ) host date",signature="${ signatureB64 }"`; + var signature = signer.sign(private_key); + var signature_b64 = signature.toString('base64'); + var header = `keyId="${bot_url}/bot",headers="(request-target) host date",signature="${signature_b64}"`; - let reqObject = { - url: `https://${ options.follower.domain }/inbox`, + var req_object = { + url: `https://${options.follower.domain}/inbox`, headers: { 'Host': options.follower.domain, - 'Date': d.toUTCString( ), + 'Date': d.toUTCString(), 'Signature': header }, method: 'POST', @@ -294,23 +297,23 @@ else{ body: options.message }; - console.log( 'request object:' ); - console.log( util.inspect( reqObject, false, null, true ) ); + // console.log('request object:'); + // console.log(util.inspect(req_object, false, null, true)); - request( reqObject, function ( error, response ){ - console.log( `sent message to ${ options.follower.url }...` ); - if ( error ) { - console.log( 'error:', error, response ); + request(req_object, function (error, response){ + console.log(`sent message to ${options.follower.url}...`); + if (error) { + console.log('error:', error, response); } else { - console.log( 'response:', response.statusCode, response.statusMessage ); - console.log( response.body ); + console.log('response:', response.statusCode, response.statusMessage); + // console.log(response); } - if ( cb ){ - cb( error, response ); + if (cb){ + cb(error, response); } - } ); + }); } } }; diff --git a/bot/bot.js b/bot/bot.js index 9a33898..1be3719 100644 --- a/bot/bot.js +++ b/bot/bot.js @@ -1,54 +1,58 @@ -var fs = require('fs'), - crypto = require('crypto'), - url = require('url'), - util = require('util'), - moment = require('moment'), - dbHelper = require(__dirname + '/../helpers/db.js'), - keys = require(__dirname + '/../helpers/keys.js'), - request = require('request'), - public_key_path = '.data/rsa/pubKey', - private_key_path = '.data/rsa/privKey', - bot_url = `https://${process.env.PROJECT_DOMAIN}.glitch.me`, - botComposeReply = require(__dirname + '/responses.js'); +if ( !process.env.PROJECT_NAME || !process.env.PROJECT_ID ){ + require( 'dotenv' ).config(); +} + +const fs = require( 'fs' ), + crypto = require( 'crypto' ), + url = require( 'url' ), + util = require( 'util' ), + moment = require( 'moment' ), + dbHelper = require( __dirname + '/../helpers/db.js' ), + keys = require( __dirname + '/../helpers/keys.js' ), + request = require( 'request' ), + publicKeyPath = '.data/rsa/pubKey', + privateKeyPath = '.data/rsa/privKey', + botUrl = `https://${ process.env.PROJECT_DOMAIN}.glitch.me`, + botComposeReply = require( __dirname + '/responses.js' ); -if (!fs.existsSync(public_key_path) || !fs.existsSync(private_key_path)) { - keys.generateKeys(function(){ - process.kill(process.pid); - }); +if ( !fs.existsSync( publicKeyPath ) || !fs.existsSync( privateKeyPath ) ) { + keys.generateKeys( function(){ + process.kill( process.pid ); + } ); } else{ - var public_key = fs.readFileSync(public_key_path, 'utf8'), - private_key = fs.readFileSync(private_key_path, 'utf8'); + const publicKey = fs.readFileSync( publicKeyPath, 'utf8' ), + privateKey = fs.readFileSync( privateKeyPath, 'utf8' ); module.exports = { - bot_url: bot_url, + bot_url: botUrl, links: [ // { // rel: 'http://webfinger.net/rel/profile-page', // type: 'text/html', - // href: `${bot_url}` + // href: `${ botUrl }` // }, // { // rel: 'http://schemas.google.com/g/2010#updates-from', // type: 'application/atom+xml', - // href: `${bot_url}/feed` + // href: `${ botUrl }/feed` // }, { rel: 'self', type: 'application/activity+json', - href: `${bot_url}/bot` + href: `${ botUrl }/bot` }, // { // rel: 'hub', - // href: `${bot_url}/pubsub` + // href: `${ botUrl }/pubsub` // }, // { // rel: 'salmon', - // href: `${bot_url}/salmon` + // href: `${ botUrl }/salmon` // }, // { // rel: 'magic-public-key', - // href: `data:application/magic-public-key,RSA.${public_key.replace('-----BEGIN PUBLIC KEY-----\n', '').replace('\n-----END PUBLIC KEY-----', '').replace('\\n', '')}` + // href: `data:application/magic-public-key,RSA.${ publicKey.replace( '-----BEGIN PUBLIC KEY-----\n', '').replace( '\n-----END PUBLIC KEY-----', '').replace( '\\n', '') }` // } ], info: { @@ -56,7 +60,7 @@ else{ 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1' ], - 'id': `${bot_url}/bot`, + 'id': `${ botUrl }/bot`, 'icon': [{ 'url': process.env.BOT_AVATAR_URL, 'type': 'Image' @@ -68,221 +72,221 @@ else{ 'type': 'Person', 'name': process.env.BOT_USERNAME, 'preferredUsername': process.env.BOT_USERNAME, - 'inbox': `${bot_url}/inbox`, + 'inbox': `${ botUrl }/inbox`, 'publicKey': { - 'id': `${bot_url}/bot#main-key`, - 'owner': `${bot_url}/bot`, - 'publicKeyPem': public_key + 'id': `${ botUrl }/bot#main-key`, + 'owner': `${ botUrl }/bot`, + 'publicKeyPem': publicKey } }, script: require( __dirname + '/script.js' ), composeReply: botComposeReply, - sendReply: function(options, cb){ - var bot = this, - reply_to_username = ''; + sendReply: function( options, cb ){ + let bot = this, + replyToUsername = ''; try{ - var actor_url_parts = options.payload.actor.split('/'); - var username = actor_url_parts[actor_url_parts.length-1]; - reply_to_username = `@${username}@${url.parse(options.payload.actor).hostname} `; + let actorUrlParts = options.payload.actor.split( '/' ); + let username = actorUrlParts[actorUrlParts.length-1]; + replyToUsername = `@${ username}@${ url.parse(options.payload.actor).hostname} `; - console.log({reply_to_username}); - } catch(err){ /*noop*/ } + console.log( { replyToUsername } ); + } catch( err ){ /* noop */ } - bot.createPost({ + bot.createPost( { type: 'Note', - content: `
${options.payload.object.content}${options.payload.object.url}

${options.reply_message}

`, - reply_message: `${reply_to_username} ${options.reply_message}`, + content: `
${ options.payload.object.content }${ options.payload.object.url }

${ options.reply_message }

`, + reply_message: `${ replyToUsername } ${ options.reply_message }`, in_reply_to: options.payload.object.url - }, function(err, message){ - // console.log(err, message); - }); + }, function( err, message ){ + // console.log( err, message ); + } ); }, - createPost: function(options, cb){ - var bot = this; + createPost: function( options, cb ){ + let bot = this; - if ((!options.content || options.content.trim().length === 0 ) && !options.attachment ){ - console.log('error: no post content or attachments'); + if ( ( !options.content || options.content.trim().length === 0 ) && !options.attachment ){ + console.log( 'error: no post content or attachments' ); return false; } - var post_type = options.type || 'Note', - post_description = options.description, - post_date = moment().format(), - post_in_reply_to = options.in_reply_to || null, - reply_message = options.reply_message || null, - post_content = options.content || options.url || '', - post_attachment = JSON.stringify(options.attachment) || '[]'; + let postType = options.type || 'Note', + postDescription = options.description, + postDate = moment().format(), + postInReplyTo = options.in_reply_to || null, + replyMessage = options.reply_message || null, + postContent = options.content || options.url || '', + postAttachment = JSON.stringify( options.attachment ) || '[]'; - dbHelper.savePost({ - type: post_type, - content: post_content, - attachment: post_attachment - }, function(err, data){ - var post_id = data.lastID; + dbHelper.savePost( { + type: postType, + content: postContent, + attachment: postAttachment + }, function( err, data ){ + let postID = data.lastID; - var post_object; + let postObject; - if ( post_type === 'Note' ){ - post_object = { - 'id': `${bot_url}/post/${post_id}`, - 'type': post_type, - 'published': post_date, - 'attributedTo': `${bot_url}/bot`, - 'content': reply_message || post_content, + if ( postType === 'Note' ){ + postObject = { + 'id': `${ botUrl }/post/${ postID }`, + 'type': postType, + 'published': postDate, + 'attributedTo': `${ botUrl }/bot`, + 'content': replyMessage || postContent, 'to': 'https://www.w3.org/ns/activitystreams#Public' }; - if (options.attachment){ - var attachments = []; + if ( options.attachment ){ + let attachments = []; - options.attachment.forEach(function(attachment){ - attachments.push({ + options.attachment.forEach( function( attachment ){ + attachments.push( { 'type': 'Image', 'content': attachment.content, 'url': attachment.url - }); - }); - post_object.attachment = attachments; + } ); + } ); + postObject.attachment = attachments; } } - if (post_in_reply_to){ - post_object.inReplyTo = post_in_reply_to; + if ( postInReplyTo ){ + postObject.inReplyTo = postInReplyTo; } - var post = { + let post = { '@context': 'https://www.w3.org/ns/activitystreams', - 'id': `${bot_url}/post/${post_id}`, + 'id': `${ botUrl }/post/${ postID }`, 'type': 'Create', - 'actor': `${bot_url}/bot`, - 'object': post_object + 'actor': `${ botUrl }/bot`, + 'object': postObject } - console.log({post_in_reply_to}); + console.log( {postInReplyTo} ); - dbHelper.getFollowers(function(err, followers){ - if (followers){ - console.log(`sending update to ${followers.length} follower(s)...`); + dbHelper.getFollowers( function( err, followers ){ + if ( followers ){ + console.log( `sending update to ${ followers.length} follower(s)...` ); - followers.forEach(function(follower){ - if (follower.url){ - bot.signAndSend({ + followers.forEach( function( follower ){ + if ( follower.url ){ + bot.signAndSend( { follower: follower, message: post - }, function(err, data){ + }, function( err, data ){ - }); + } ); } - }); + } ); } - }); + } ); - if (cb){ - cb(null, post); + if ( cb ){ + cb( null, post ); } - }); + } ); }, - deletePost: function(post_id, follower_url, cb){ - var bot = this; - // guid = crypto.randomBytes(16).toString('hex'); + deletePost: function( postID, followerUrl, cb ){ + let bot = this; + // guid = crypto.randomBytes(16).toString( 'hex' ); - bot.signAndSend({ + bot.signAndSend( { follower: { - url: follower_url + url: followerUrl }, message: { '@context': 'https://www.w3.org/ns/activitystreams', - // 'summary': `${bot} deleted a post`, - // 'id': `${bot.bot_url}/${guid}`, + // 'summary': `${ bot} deleted a post`, + // 'id': `${ bot.bot_url }/${ guid }`, 'type': 'Delete', - 'actor': `${bot.bot_url}/bot`, - 'object': `${bot.bot_url}/post/${post_id}` + 'actor': `${ bot.bot_url }/bot`, + 'object': `${ bot.bot_url }/post/${ postID }` } - }, function(err, data){ - if (cb){ - cb(err, data); + }, function( err, data ){ + if ( cb ){ + cb( err, data ); } - }); + } ); }, - accept: function(payload, cb){ - var bot = this, - guid = crypto.randomBytes(16).toString('hex'); + accept: function( payload, cb ){ + let bot = this, + guid = crypto.randomBytes(16).toString( 'hex' ); - dbHelper.getEvent(payload.id, function(err, data){ - // console.log('get_event', err, data); + dbHelper.getEvent(payload.id, function( err, data ){ + // console.log( 'getEvent', err, data ); - bot.signAndSend({ + bot.signAndSend( { follower: { url: payload.actor }, message: { '@context': 'https://www.w3.org/ns/activitystreams', - 'id': `${bot.bot_url}/${guid}`, + 'id': `${ bot.bot_url }/${ guid }`, 'type': 'Accept', - 'actor': `${bot.bot_url}/bot`, + 'actor': `${ bot.bot_url }/bot`, 'object': payload, } - }, function(err, data){ - if (cb){ - cb(err, payload, data); + }, function( err, data ){ + if ( cb ){ + cb( err, payload, data ); } - console.log('saving event', payload.id) - dbHelper.saveEvent(payload.id); - }); + console.log( 'saving event', payload.id) + dbHelper.saveEvent(payload.id ); + } ); - }); -// dbHelper.getEvent(payload.id, function(err, data){ -// console.log('get_event', err, data); + } ); +// dbHelper.getEvent(payload.id, function( err, data ){ +// console.log( 'getEvent', err, data ); -// if (!err && !data){ -// bot.signAndSend({ +// if ( !err && !data ){ +// bot.signAndSend( { // follower: { // url: payload.actor // }, // message: { // '@context': 'https://www.w3.org/ns/activitystreams', -// 'id': `${bot.bot_url}/${guid}`, +// 'id': `${ bot.bot_url }/${ guid }`, // 'type': 'Accept', -// 'actor': `${bot.bot_url}/bot`, +// 'actor': `${ bot.bot_url }/bot`, // 'object': payload, // } -// }, function(err, data){ -// if (cb){ -// cb(err, payload, data); +// }, function( err, data ){ +// if ( cb ){ +// cb( err, payload, data ); // } -// console.log('saving event', payload.id) -// dbHelper.saveEvent(payload.id); -// }); -// } else if (!err){ -// console.log('duplicate event'); +// console.log( 'saving event', payload.id) +// dbHelper.saveEvent(payload.id ); +// } ); +// } else if ( !err ){ +// console.log( 'duplicate event' ); // } -// }); +// } ); }, - signAndSend: function(options, cb){ - var bot = this; - // console.log('message to sign:'); - // console.log(util.inspect(options.message, false, null, true)); + signAndSend: function( options, cb ){ + let bot = this; + // console.log( 'message to sign:' ); + // console.log( util.inspect(options.message, false, null, true) ); - options.follower.url = options.follower.url.replace('http://localhost:3000', 'https://befc66af.ngrok.io'); + options.follower.url = options.follower.url.replace( 'http://localhost:3000', 'https://befc66af.ngrok.io' ); - if (options.follower.url && options.follower.url !== 'undefined'){ - options.follower.domain = url.parse(options.follower.url).hostname; + if ( options.follower.url && options.follower.url !== 'undefined' ){ + options.follower.domain = url.parse( options.follower.url ).hostname; - var signer = crypto.createSign('sha256'), + let signer = crypto.createSign( 'sha256' ), d = new Date(), - string_to_sign = `(request-target): post /inbox\nhost: ${options.follower.domain}\ndate: ${d.toUTCString()}`; + stringToSign = `(request-target): post /inbox\nhost: ${ options.follower.domain}\ndate: ${ d.toUTCString() }`; - signer.update(string_to_sign); + signer.update( stringToSign ); signer.end(); - var signature = signer.sign(private_key); - var signature_b64 = signature.toString('base64'); - var header = `keyId="${bot_url}/bot",headers="(request-target) host date",signature="${signature_b64}"`; + let signature = signer.sign(privateKey ); + let signatureB64 = signature.toString( 'base64' ); + let header = `keyId="${ botUrl }/bot",headers="(request-target) host date",signature="${ signatureB64}"`; - var req_object = { - url: `https://${options.follower.domain}/inbox`, + let reqObject = { + url: `https://${ options.follower.domain }/inbox`, headers: { 'Host': options.follower.domain, 'Date': d.toUTCString(), @@ -293,23 +297,23 @@ else{ body: options.message }; - // console.log('request object:'); - // console.log(util.inspect(req_object, false, null, true)); + // console.log( 'request object:' ); + // console.log( util.inspect(reqObject, false, null, true) ); - request(req_object, function (error, response){ - console.log(`sent message to ${options.follower.url}...`); - if (error) { - console.log('error:', error, response); + request( reqObject, function (error, response ){ + console.log( `sent message to ${ options.follower.url}...` ); + if ( error) { + console.log( 'error:', error, response ); } else { - console.log('response:', response.statusCode, response.statusMessage); - // console.log(response); + console.log( 'response:', response.statusCode, response.statusMessage ); + // console.log( response ); } - if (cb){ - cb(error, response); + if ( cb ){ + cb( error, response ); } - }); + } ); } } }; diff --git a/bot/script.js b/bot/script.js index 303d346..7020f3a 100644 --- a/bot/script.js +++ b/bot/script.js @@ -1,18 +1,45 @@ const express = require( 'express' ), - router = express.Router(), + helpers = require( __dirname + '/../helpers/general.js' ), + ColorScheme = require('color-scheme'), + generators = { + triangular_mesh: require(__dirname + '/../generators/triangular-mesh.js') + }, grammar = require( __dirname + '/../tracery/tracery.js' ).grammar; module.exports = function(){ const bot = require( __dirname + '/bot.js' ), - content = grammar.flatten( '#origin#' ); + content = grammar.flatten( '#origin#' ), + scheme = new ColorScheme; - console.log( 'posting new message...' ); + /* See https://www.npmjs.com/package/color-scheme#schemes on how to use ColorScheme. */ - bot.createPost( { - type: 'Note', // See www.w3.org/ns/activitystreams#objects - content: content - }, function( err, message ){ + scheme.from_hex( helpers.getRandomHex().replace( '#','' ) ) + .scheme( 'mono' ) + .variation( 'soft' ); + generators.triangular_mesh( { + width: 800, + height: 360, + colors: scheme.colors() + }, function( err, imgData ){ + const imgUrl = `${ bot.bot_url }/${ imgData.path }`; + console.log( 'posting new image...', imgUrl ); - } ); + var imgName = imgData.path.replace( 'img/', '' ); + + bot.createPost( { + type: 'Note', + content: content, + attachment: [ + { + url: imgUrl, + content: content // Image description here. + } + ] + }, function( err, message ){ + if ( err ){ + console.log( err ); + } + } ); + } ); }; diff --git a/examples/generative-art-bot/routes/bot-endpoint.js b/examples/generative-art-bot/routes/bot-endpoint.js deleted file mode 100644 index 5a54d60..0000000 --- a/examples/generative-art-bot/routes/bot-endpoint.js +++ /dev/null @@ -1,57 +0,0 @@ -var express = require('express'), - router = express.Router(), - ColorScheme = require('color-scheme'), - generators = { - triangular_mesh: require(__dirname + '/../generators/triangular-mesh.js') - }, - grammar = require(__dirname + '/../tracery/tracery.js').grammar, - helpers = require(__dirname + '/../helpers/general.js'), - imageUploader = require(__dirname + '/../helpers/image-uploader.js'), - bot = require(__dirname + '/../bot/bot.js'); - -router.get('/', function (req, res) { - var content = grammar.flatten("#origin#"), - scheme = new ColorScheme; - -/* - See https://www.npmjs.com/package/color-scheme#schemes on how to use ColorScheme. -*/ - - scheme.from_hex(helpers.getRandomHex().replace('#','')) - .scheme('mono') - .variation('hard'); - - generators.triangular_mesh({ - width: 800, - height: 360, - colors: scheme.colors() - }, function(err, img_data){ - // console.log({img_url: `${bot.bot_url}/${img_data.path}`}); - - var img_name = img_data.path.replace('img/', ''); - - imageUploader.uploadImage(img_data, function(err, img_url, data){ - if (err){ - console.log(err); - } else { - // console.log(img_url); - - bot.createPost({ - type: 'Note', - content: content, - attachment: [ - { - url: img_url, - content: content // Image description here. - } - ] - }, function(err, message){ - res.setHeader('Content-Type', 'application/json'); - res.send(JSON.stringify(message)); - }); - } - }); - }); -}); - -module.exports = router; diff --git a/examples/generative-art-bot/script.js b/examples/generative-art-bot/script.js new file mode 100644 index 0000000..f24ca58 --- /dev/null +++ b/examples/generative-art-bot/script.js @@ -0,0 +1,44 @@ +const express = require( 'express' ), + helpers = require( __dirname + '/../helpers/general.js' ), + ColorScheme = require('color-scheme'), + generators = { + triangular_mesh: require(__dirname + '/../generators/triangular-mesh.js') + }, + grammar = require( __dirname + '/../tracery/tracery.js' ).grammar; + +module.exports = function(){ + const bot = require( __dirname + '/bot.js' ), + content = grammar.flatten( '#origin#' ), + scheme = new ColorScheme; + + /* See https://www.npmjs.com/package/color-scheme#schemes on how to use ColorScheme. */ + + scheme.from_hex( helpers.getRandomHex().replace( '#','' ) ) + .scheme( 'mono' ) + .variation( 'soft' ); + + generators.triangular_mesh( { + width: 800, + height: 360, + colors: scheme.colors() + }, function( err, imgData ){ + console.log( 'posting new image...', { imgUrl: `${ bot.bot_url }/${ imgData.path }` } ); + + var imgName = imgData.path.replace( 'img/', '' ); + + bot.createPost( { + type: 'Note', + content: content, + attachment: [ + { + url: bot.bot_url, + content: 'Abstract art' // Image description here. + } + ] + }, function( err, message ){ + if ( err ){ + console.log( err ); + } + } ); + } ); +}; diff --git a/examples/replies/bot/bot-replies.js b/examples/replies/bot/responses.js similarity index 100% rename from examples/replies/bot/bot-replies.js rename to examples/replies/bot/responses.js diff --git a/examples/tracery/README.md b/examples/tracery/README.md index 721c7be..480c182 100644 --- a/examples/tracery/README.md +++ b/examples/tracery/README.md @@ -1,4 +1,4 @@ # Tracery bot 1. Update `tracery/grammar.json` with your Tracery grammar. You can find Tracery tutorials [on Botwiki](https://botwiki.org/resources/twitterbots/#tutorials-tracery-cbdq). -2. Use the code from `examples/tracery/routes/bot-endpoint.js` to update your `routes/bot-endpoint.js` file. \ No newline at end of file +2. Use the code from `examples/tracery/script.js` to update your `bot/script.js` file. \ No newline at end of file diff --git a/examples/tracery/routes/bot-endpoint.js b/examples/tracery/routes/bot-endpoint.js deleted file mode 100644 index bc071aa..0000000 --- a/examples/tracery/routes/bot-endpoint.js +++ /dev/null @@ -1,18 +0,0 @@ -var express = require('express'), - router = express.Router(), - grammar = require(__dirname + '/../tracery/tracery.js').grammar, - bot = require(__dirname + '/../bot.js'); - -router.get('/', function (req, res) { - var content = grammar.flatten("#origin#"); - - bot.create_post({ - type: 'Note', // See www.w3.org/ns/activitystreams#objects - content: content - }, function(err, message){ - res.setHeader('Content-Type', 'application/json'); - res.send(JSON.stringify(message)); - }); -}); - -module.exports = router; diff --git a/examples/tracery/script.js b/examples/tracery/script.js new file mode 100644 index 0000000..bfbd51f --- /dev/null +++ b/examples/tracery/script.js @@ -0,0 +1,19 @@ +const express = require( 'express' ), + router = express.Router(), + grammar = require( __dirname + '/../tracery/tracery.js' ).grammar; + +module.exports = function(){ + const bot = require( __dirname + '/bot.js' ), + content = grammar.flatten( '#origin#' ); + + console.log( 'posting new message...' ); + + bot.createPost( { + type: 'Note', // See www.w3.org/ns/activitystreams#objects + content: content + }, function( err, message ){ + if ( err ){ + console.log( err ); + } + } ); +}; diff --git a/helpers/image-uploader.js b/helpers/image-uploader.js deleted file mode 100644 index 1381830..0000000 --- a/helpers/image-uploader.js +++ /dev/null @@ -1,58 +0,0 @@ -const fs = require( 'fs' ), - bot = require( __dirname + '/../bot/bot.js' ), - NeoCities = require( 'neocities' ); - -let useNeocities = false; - -if ( process.env.NEOCITIES_USERNAME && process.env.NEOCITIES_PASSWORD ){ - const neocitiesAPI = new NeoCities( process.env.NEOCITIES_USERNAME, process.env.NEOCITIES_PASSWORD ); - useNeocities = true; -} - -module.exports = { - uploadImage: function( img_data, cb ){ - let img_url = `${bot.bot_url}/${img_data.path}`, - img_name = img_data.path.replace( 'img/', '' ); - - if ( useNeocities ){ - /* - First option, NeoCities. They offer 1GB for free, and with a - paid option ( $5/month ) you get 50GB. - - https://neocities.org/supporter - - */ - neocitiesAPI.upload( [ { - name: img_name, - path: `.data/img/${img_name}` - } ], function( resp ) { - console.log( resp ); - img_url = null; - - if ( resp && resp.result === 'success' ){ - fs.unlink( `.data/img/${img_name}`, function( err ){ - if ( err ){ - console.log( err ); - } - else{ - console.log( 'deleted local image' ); - } - } ); - - img_url = `https://${process.env.NEOCITIES_USERNAME}.neocities.org/${img_name}`; - } - if ( cb ){ - cb( null, img_url, resp ); - } - } ); - } else { - /* Fall-back to local storage. It's only ~128 MB, so good luck! */ - if ( cb ){ - cb( null, img_url ); - } - } - } -}; - - - diff --git a/package.json b/package.json index 6599b6b..587c487 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "color-scheme": "^1.0.1", "gifencoder": "^1.1.0", "neocities": "^0.0.3", - "jsdom": "^12.1.0" + "jsdom": "^12.1.0", + "dotenv": "^8.2.0" }, "engines": { "node": "8.x" @@ -43,4 +44,4 @@ "fediverse", "bot" ] -} +} \ No newline at end of file diff --git a/server.js b/server.js index cd4e240..1cb37cf 100644 --- a/server.js +++ b/server.js @@ -1,3 +1,7 @@ +if ( !process.env.PROJECT_NAME || !process.env.PROJECT_ID ){ + require( 'dotenv' ).config(); +} + const app = require(__dirname + "/app.js"), db = require(__dirname + "/helpers/db.js"), bot = require(__dirname + "/bot/bot.js"), @@ -25,7 +29,7 @@ db.init(); // console.log( 'Events:', data ); // } ); -// bot.script(); +bot.script(); /* DEBUGGING END */ /*********************************************/ diff --git a/sessions-journal b/sessions-journal deleted file mode 100644 index 38ec077..0000000 Binary files a/sessions-journal and /dev/null differ diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml index c7fa5aa..02b9635 100644 --- a/shrinkwrap.yaml +++ b/shrinkwrap.yaml @@ -5,6 +5,7 @@ dependencies: color-scheme: 1.0.1 connect-sqlite3: 0.9.11 cron: 1.8.2 + dotenv: 8.2.0 express: 4.16.3 express-babelify-middleware: 0.2.1 express-handlebars: 3.0.0 @@ -1682,6 +1683,12 @@ packages: dev: false resolution: integrity: sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + /dotenv/8.2.0: + dev: false + engines: + node: '>=8' + resolution: + integrity: sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== /duplexer2/0.1.4: dependencies: readable-stream: 2.3.6 @@ -5379,6 +5386,7 @@ specifiers: color-scheme: ^1.0.1 connect-sqlite3: ^0.9.11 cron: ^1.8.2 + dotenv: ^8.2.0 express: ^4.16.3 express-babelify-middleware: ^0.2.1 express-handlebars: ^3.0.0