Created
August 13, 2020 21:13
-
-
Save icelander/13540e6916dbd58c80fbf883a773d57c to your computer and use it in GitHub Desktop.
members_to_csv.rb is a Ruby script that generates a CSV file containing the users who are members of a team or channel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ruby | |
require 'csv' | |
require 'yaml' | |
require 'httparty' | |
require 'uri' | |
# ## members_to_csv.rb | |
# | |
# ### About | |
# | |
# members_to_csv.rb is a Ruby script that generates a CSV file containing the | |
# users who are members of a team or channel | |
# | |
# ### File Format | |
# | |
# The file created will be named `team-name-YYYY-MM-DD.csv` or | |
# `team-name-channel-name-YYYY-MM-DD.csv` and will contain the following fields, | |
# repeated for each different team: | |
# | |
# - Team Name | |
# - Channel Name | |
# - First Name | |
# - Last Name | |
# - Username | |
# - Email Address | |
# - Date Channel Last Viewed | |
# | |
# ### Usage: | |
# | |
# **Dependencies:** This script requires that you install Ruby - | |
# https://www.ruby-lang.org/en/documentation/installation/ - and install the | |
# required gems: | |
# | |
# - csv | |
# - yaml | |
# - uri | |
# - httparty | |
# | |
# Once you have Ruby installed, install them with this command: | |
# | |
# gem install csv yaml uri httparty | |
# | |
# | |
# 1. Create a file named `conf.yaml` with this format: | |
# | |
# ```yaml | |
# server_name: | |
# url: https://<Mattermost Server URL>/ <- INCLUDE TRAILING SLASH | |
# login_id: <Mattermost admin username> | |
# auth_token: <Auth Token> | |
# ``` | |
# | |
# OR | |
# | |
# ```yaml | |
# server_name: | |
# url: https://<Mattermost Server URL>/ <- INCLUDE TRAILING SLASH | |
# login_id: <Mattermost admin username> | |
# password: <Password> | |
# ``` | |
# | |
# 2. Run it through Ruby: `ruby members_to_csv.rb team-name[:channel-name]` | |
# | |
# If you want to get all the users for a team, provide just the team name, e.g. | |
# | |
# ruby members_to_csv.rb team-name | |
# | |
# If you want a specific channel, include the channel name: | |
# | |
# ruby members_to_csv.rb team-name:channel-name | |
# | |
# CSV files are generated in the current working directory. | |
$config = YAML.load( | |
File.open('conf.yaml').read | |
) | |
class MattermostApi | |
include HTTParty | |
format :json | |
# UNCOMMENT NEXT LINE TO DEBUG REQUESTS | |
# debug_output $stdout | |
def initialize(config) | |
# Default Options | |
@options = { | |
headers: { | |
'Content-Type' => 'application/json', | |
'User-Agent' => 'Mattermost-HTTParty' | |
}, | |
# TODO Make this more secure | |
verify: false | |
} | |
# check the config for mattermost_url | |
if ! (config.key?("url") && url_valid?(config['url'])) | |
raise 'url is required in configuration' | |
end | |
@base_uri = config['url'] + 'api/v4/' | |
token = nil | |
if config.key?('auth_token') | |
token = config['auth_token'] | |
else | |
# Use password login | |
if (config.key?('login_id') && config.key?('password')) | |
token = get_login_token(config['login_id'], config['password']) | |
end | |
end | |
if token.nil? | |
raise 'token not set, check for token or login_id and password' | |
end | |
@options[:headers]['Authorization'] = "Bearer #{token}" | |
@options[:body] = nil | |
end | |
def url_valid?(url) | |
url = URI.parse(url) rescue false | |
end | |
def get_team_members(team_name) | |
puts "Getting channels for team: #{team_name}" | |
team = get_url("/teams/name/#{team_name}") | |
# Return Values | |
# - "id": "string", | |
# - "create_at": 0, | |
# - "update_at": 0, | |
# - "delete_at": 0, | |
# - "display_name": "string", | |
# - "name": "string", | |
# - "description": "string", | |
# - "email": "string", | |
# - "type": "string", | |
# - "allowed_domains": "string", | |
# - "invite_id": "string", | |
# - "allow_open_invite": true | |
return false if team.nil? | |
channels = get_url("/channels") | |
# Return value: | |
# - "id": "string", | |
# - "create_at": 0, | |
# - "update_at": 0, | |
# - "delete_at": 0, | |
# - "team_id": "string", | |
# - "type": "string", | |
# - "display_name": "string", | |
# - "name": "string", | |
# - "header": "string", | |
# - "purpose": "string", | |
# - "last_post_at": 0, | |
# - "total_msg_count": 0, | |
# - "extra_update_at": 0, | |
# - "creator_id": "string" | |
output = [] | |
channels.each_with_index do |channel, index| | |
if channel['team_id'] == team['id'] | |
output = output + get_channel_members(team_name, channel['name']) | |
end | |
end | |
return output | |
end | |
def get_channel_members(team_name, channel_name) | |
puts " - Getting members of channel: #{channel_name}" | |
channel = get_url("/teams/name/#{team_name}/channels/name/#{channel_name}") | |
members = get_url("/channels/#{channel['id']}/members") | |
# Return Values: | |
# - "channel_id": "string", | |
# - "user_id": "string", | |
# - "roles": "string", | |
# - "last_viewed_at": 0, | |
# - "msg_count": 0, | |
# - "mention_count": 0, | |
# - "notify_props": | |
# {}, | |
# "last_update_at": 0 | |
# } | |
output = [] | |
csv_fields = [ | |
"Team Name", | |
"Channel Name", | |
"First Name", | |
"Last Name", | |
"Username", | |
"Email Address", | |
"Date Channel Last Viewed" | |
] | |
output << csv_fields | |
members.each_with_index do |member, index| | |
# - Team Name | |
# - Channel Name | |
# - First Name | |
# - Last Name | |
# - Username | |
# - Email Address | |
# - Date Channel Last Viewed | |
# Build the CSV Row | |
user = get_url("/users/#{member['user_id']}") | |
last_viewed = "never" | |
if member['last_viewed_at'] != 0 | |
last_viewed = Date.strptime((member['last_viewed_at']/1000).to_s, '%s').to_s | |
end | |
csv_row = [] | |
csv_row = [team_name, | |
channel_name, | |
user['first_name'], | |
user['last_name'], | |
user['username'], | |
user['email'], | |
last_viewed | |
] | |
output << csv_row | |
end | |
return output | |
end | |
def get_all_users | |
get_url('users') | |
end | |
def get_url(url) | |
# TODO: Make this handle pagination | |
JSON.parse(self.class.get("#{@base_uri}#{url}", @options).to_s) | |
end | |
end | |
$mm = MattermostApi.new($config['test_server']) | |
# If it contains a colon, get just that channel | |
if ARGV[0].include? ":" | |
team_name, channel_name = ARGV[0].split(':') | |
filename = "./#{team_name}-#{channel_name}-#{Time.now.strftime("%Y-%m-%d")}.csv" | |
puts "Outputting channel members of #{team_name}:#{channel_name} to #{filename}" | |
output = $mm.get_channel_members(team_name, channel_name) | |
else # get all channels for that team | |
team_name = ARGV[0] | |
filename = "./#{team_name}-#{Time.now.strftime("%Y-%m-%d")}.csv" | |
puts "Outputting team members of #{team_name} to #{filename}" | |
output = $mm.get_team_members(ARGV[0]) | |
end | |
CSV.open(filename, "wb") do |csv| | |
output.each do |o| | |
csv << o | |
end | |
end | |
puts "File output complete" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment