Skip to content

Instantly share code, notes, and snippets.

@icelander
Last active January 14, 2021 04:30
Show Gist options
  • Save icelander/c44ba3db68e12b76f8464bf6866066b7 to your computer and use it in GitHub Desktop.
Save icelander/c44ba3db68e12b76f8464bf6866066b7 to your computer and use it in GitHub Desktop.
Replaces the random channel name with usernames in Mattermost compliance reports
#!/usr/bin/env ruby
# frozen_string_literal: true
## mm_fix_compliance_reports.rb
#
## ABOUT
#
# This script takes a Mattermost Compliance Monitoring export CSV and replaces
# the direct message channel names with the corresponding usernames. For
# example:
#
# p9c1rgpiwt8if8b1u4r9785mdc__tspakayx5j8xxbg1fd4xhy3sie
#
# becomes:
#
# steve.palmer/sysadmin
#
# The first user is the one who initiated the direct message.
#
## HOW TO USE
#
# 1. Install Ruby and the HTTParty gem on your machine
# 2. Generate a personal access token without admin privileges
# 3. Get an export from System Console > Compliance > Compliance Monitoring and
# place it in the same directory as the script
# 4. Change these values to match your environment. Be sure to quote the
# strings properly, e.g.
#
# mattermost_url = 'this is correct'
# auth_token = this is not correct
#
# URL of the Mattermost server
mattermost_url = 'http://mattermost.example.com/'
# Authentication token you generated in step 2
auth_token = 'jiqffsrootb7pddhqmoc13nw3o'
#
# 5. Run the script, passing the name of the export you wish to process, e.g.
#
# ruby mm_fix_compliance_reports.rb <filename.csv>
#
# 6. The new file will be in the same directory with `fixed_` prefixed to the
# filename, e.g. fixed_posts.csv
#######################################
### DO NOT EDIT ANYTHING BELOW HERE ###
#######################################
require 'httparty'
require 'uri'
require 'csv'
class MattermostApi
include HTTParty
format :json
# UNCOMMENT NEXT LINE TO DEBUG API REQUESTS
# debug_output $stdout
def initialize(mattermost_url, auth_token)
# Default Options
@options = {
headers: {
'Content-Type' => 'application/json',
'User-Agent' => 'HTTParty On, Dudes!'
},
# TODO Make this more secure
verify: false
}
# check the config for mattermost_url
if mattermost_url.nil? or !url_valid?(mattermost_url)
raise 'url is required in configuration'
else
if mattermost_url[-1] != '/'
mattermost_url = mattermost_url + '/'
end
end
@base_uri = mattermost_url + 'api/v4/'
@options[:headers]['Authorization'] = "Bearer #{auth_token}"
@options[:body] = nil
@user = nil
test_response = self.class.get("#{@base_uri}users/me", @options)
if test_response.code == 200
@user = JSON.parse(test_response.to_s)
else
puts "Could not connect to Mattermost server #{mattermost_url}, aborting."
exit 1
end
if @user.nil? || @user['id'].nil?
puts "Could not get current user, aborting."
exit 1
end
end
def get_username_by_id(user_id)
user = self.get_url("users/#{user_id}")
if user
return user['username']
else
return false
end
end
private
def url_valid?(url)
url = URI.parse(url) rescue false
end
def get_url(url)
response = self.class.get("#{@base_uri}#{url}", @options)
if response.code != 200
raise "Error requesting URL: #{response}"
return false
end
return JSON.parse(response.to_s)
end
end
mm_api = MattermostApi.new(mattermost_url, auth_token)
# Read the CSV File
input_filename = ARGV[0]
if File.readable?(input_filename)
output_filename = "fixed_" + File.basename(input_filename)
csv_file = CSV.read(input_filename)
else
raise "Could not read #{filename}"
exit 1
end
# Check for new file
if File.exists?(output_filename)
raise "Output File #{output_filename} exists. Exiting."
exit 1
end
output_array = []
channel_name_column_index = 2
csv_file.each_with_index do |line, line_number|
if line_number == 0
channel_name_column_index = line.find_index('ChannelName')
end
if line[0] == 'direct-messages'
channel_name = line[channel_name_column_index]
user_ids = channel_name.split('__')
usernames = []
user_ids.each do |user_id|
new_username = mm_api.get_username_by_id(user_id)
if new_username
usernames << new_username
else
raise "Could not find user with ID #{user_id}"
end
end
line[channel_name_column_index] = usernames.join('/')
end
# Write line to new file
output_array << line
end
# Write output to CSV
CSV.open(output_filename, "wb") do |csv|
output_array.each do |o|
csv << o
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment