Skip to content

Instantly share code, notes, and snippets.

@0x263b
Last active September 25, 2021 13:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0x263b/619137ed39578057c096530d2b671581 to your computer and use it in GitHub Desktop.
Save 0x263b/619137ed39578057c096530d2b671581 to your computer and use it in GitHub Desktop.
Archive a discord DM and all attachments
#!/usr/bin/env ruby
# encoding: utf-8
Encoding.default_external = "UTF-8"
Encoding.default_internal = "UTF-8"
require "open-uri"
require "json"
require "net/https"
require "uri"
require "date"
require "fileutils"
CHANNEL = "" # Channel ID of the DM
TOKEN = "" # My API Token
COOKIE = "__cfduid=" # My Cookie
# Get channel object
data = open("https://discordapp.com/api/v6/channels/#{CHANNEL}",
"Authorization" => TOKEN,
"Cookie" => COOKIE).read
data = JSON.parse(data)
# Username
DM = "#{data["recipients"][0]["username"]}\##{data["recipients"][0]["discriminator"]}"
puts "Downloading DM history with #{DM}"
# Make a directory for the attachments
CHAN_DIR = "#{File.expand_path(File.dirname(__FILE__))}/#{CHANNEL}__#{DM}"
FileUtils.mkpath(CHAN_DIR)
# Initialize
@messages = []
last = data["last_message_id"]
direction = "before"
# Check if there is already a saved archive
if File.file?("#{CHAN_DIR}.json")
data = File.read("#{CHAN_DIR}.json")
@messages = JSON.parse(data)
last = @messages.last["id"]
direction = "after"
end
more = true
n = 0
while more == true do # Loop through search result pages
begin
data = open("https://discordapp.com/api/v6/channels/#{CHANNEL}/messages?#{direction}=#{last}&limit=100",
"Authorization" => TOKEN,
"Cookie" => COOKIE).read
data = JSON.parse(data)
@messages << data
if direction == "before"
last = data.last["id"]
else
last = data.first["id"]
end
more = false if data.length == 0
n += 1
print "\r"
print "Pages downloaded: #{n}"
$stdout.flush
sleep 1 # Sleep to avoid Rate Limit
rescue
more = false
end
end
# Clean up messages for saving
@messages.flatten!.uniq!{ |msg| msg["id"] } # delete duplicates
@messages.sort_by!{ |message| -message["timestamp"] } # Sort oldest to newest
# Save log
File.write("#{CHAN_DIR}.json", JSON.pretty_generate(@messages))
# Download attachments
puts ""
puts "Saved logs"
puts "Downloading attachments..."
n = 0
@messages.each do |message|
begin
next unless message["attachments"].length > 0
message["attachments"].each do |attachment|
name = "#{attachment["id"]}__#{attachment["filename"]}"
fn = "#{CHAN_DIR}/#{name}"
next if File.file?(fn) # Skip files we've downloaded already
open(attachment["url"]) do |f|
File.open(fn,"wb") do |file|
file.puts f.read
end
end
n += 1
print "\r"
print "Attachments downloaded: #{n}"
$stdout.flush
sleep 0.5 # Sleep to avoid Rate Limit
end
rescue Exception => e
puts e.message
end
end
puts ""
puts "Complete"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment