|
const Discord = require('discord.js'); |
|
const R = require('ramda'); |
|
const bot = new Discord.Client(); |
|
const request = require('request'); |
|
const fs = require('fs'); |
|
const path = require('path'); |
|
const mkdirp = require('mkdirp'); |
|
|
|
const prog = require("commander"); |
|
|
|
prog |
|
.version('0.0.0') |
|
.usage('<token> <channelid>') |
|
.parse(process.argv); |
|
|
|
bot.on('ready', async () => { |
|
console.log("[i] Logged in!"); |
|
|
|
// Try a normal guild channel |
|
let channel = bot.channels.get(prog.args[1]); |
|
|
|
// Try a dm channel |
|
if ( !channel ) channel = bot.users.get(prog.args[1]).dmChannel; |
|
if ( !channel ) { |
|
throw new Error("Invalid id"); |
|
} |
|
|
|
console.log(`[i] Found channel '${channel.name}'`); |
|
|
|
console.log(`[i] Fetching messages`); |
|
|
|
// This function accumulates all of the messages in a channel |
|
const accumulate = (channel) => new Promise((resolve, reject) => { |
|
let accumulator; |
|
|
|
const next = (before) => { |
|
// The hard-limit of a fetchMessages request is 100, so we apply the limit. |
|
// If we didn't supply a 'before' id, we don't pass it. |
|
return channel.fetchMessages(before ? {limit: 100, before: before} : {limit: 100}).then(messages => { |
|
if ( accumulator ) { |
|
accumulator = accumulator.concat(messages); |
|
} |
|
else { |
|
// If we didn't initialize the accumulator yet, we can do it now. |
|
accumulator = messages; |
|
} |
|
|
|
if ( messages.size < 100 ) return Promise.resolve(accumulator); |
|
else return next(messages.last().id) |
|
}).catch( e => console.error(`[!] ${e.toString()}`)) |
|
} |
|
|
|
// Pass through to the promise. |
|
next().then(resolve).catch(reject); |
|
}); |
|
|
|
const messages = await accumulate(channel); |
|
|
|
const images = messages.filter( message => message.attachments.size > 0 ); |
|
|
|
// Extract imageURLs from messages |
|
const imageURLs = images.map(i => i.attachments.map( a => a.url)).reduce( ( a, b ) => a.concat(b) ); |
|
|
|
console.log(`[i] Ok, we're going to download ${imageURLs.length} files`); |
|
|
|
// Create a directory so the files actually don't throw an error. |
|
mkdirp(path.join(__dirname, 'downloads'), async () => { |
|
const next = (i) => { |
|
const imageURL = imageURLs[i]; |
|
|
|
console.log(`[i] Downloading ${R.last(imageURL.split('/'))}`); |
|
const stream = request(imageURL).pipe(fs.createWriteStream(path.join(__dirname, 'downloads', `[${i}] ${R.last(imageURL.split('/'))}`))); |
|
|
|
stream.on('finish', () => { |
|
if ( i + 1 < imageURLs.length ) next(i + 1); |
|
}); |
|
} |
|
|
|
next(0); |
|
|
|
}); |
|
|
|
}); |
|
|
|
// Finally, log in. |
|
bot.login(prog.args[0]); |
|
|
|
console.log("[i] Logging in...") |