Skip to content

Instantly share code, notes, and snippets.

@icelander
Created March 21, 2022 20:07
Show Gist options
  • Save icelander/e5be51e8a12b2d073ef79bacc54b114e to your computer and use it in GitHub Desktop.
Save icelander/e5be51e8a12b2d073ef79bacc54b114e to your computer and use it in GitHub Desktop.
A Ruby Mattermost API that does just enough to sync users
require 'httparty'
require 'uri'
require 'cgi'
class MattermostApi
include HTTParty
format :json
# debug_output STDOUT
def initialize(config)
@options = {
headers: {
'Content-Type' => 'application/json'
},
verify: false
}
if config.key?(:url) && !config[:url].nil?
url = config[:url]
else
raise 'MattermostAPI: URL is required'
end
unless url.end_with? '/'
url = url + '/'
end
unless url_valid?(url)
raise "URL #{url} is invalid"
end
@base_uri = url + 'api/v4/'
token = nil
if config.key?(:auth_token) && config[:auth_token] != ''
$log.debug("MattermostApi: Auth Token set in config: #{config[:auth_token]}")
token = config[:auth_token]
else
unless config.key?('username')
raise "MattermostApi: username is required"
end
# Use password login
$log.debug("MattermostApi: Auth Token not set in config, using password")
if (config.key?('password'))
token = self.get_login_token(config['username'], config['password'])
else
raise "MattermostApi: Password or Auth Token is required"
end
end
if token.nil?
raise 'MattermostApi: Could not set auth token.'
else
$log.debug("MattermostApi: Setting Auth Token to: #{token}")
@options[:headers]['Authorization'] = "Bearer #{token}"
end
@options[:body] = nil
@options[:query] = nil
end
def get_login_token(login_id, password)
$log.debug("Logging in with #{login_id} / #{password}")
payload = {login_id: login_id, password: password}
url = "#{@base_uri}users/login"
response = self.class.post(url, {body: payload.to_json, headers: {'Content-Type' => 'application/json'}})
if response.code == 200 || response.code == 201
return response.headers['token']
else
$log.error("Could not login to Mattermost")
end
return nil
end
def get_current_user
get_url('users/me')
end
def get_user_by_email(email)
url = "users/email/#{email}"
self.get_url(url)
end
def create_post(channel_id, message, root_id=nil, file_ids=nil, props=nil)
url = 'posts'
payload = {
channel_id: channel_id,
message: message,
root_id: root_id,
props: props,
file_ids: file_ids
}
return post_data(url, payload)
end
def get_team_by_name(team_name)
url = "teams/name/#{self.cgi_escape(team_name)}"
response = self.get_url(url)
return response
end
def get_users_teams(user_id)
url = "users/#{user_id}/teams"
response = self.get_url(url)
if response.nil?
return nil
else
return response
end
end
def get_users_channels(user_id, team_id)
url = "users/#{user_id}/teams/#{team_id}/channels"
response = self.get_url(url)
if response.nil?
return nil
else
return response
end
end
def add_user_to_team(user_id, team_id)
payload = {
team_id: team_id,
user_id: user_id
}
url = "teams/#{team_id}/members"
self.post_data(url, payload)
end
def add_user_to_channel(user_id, channel_id)
payload = {
user_id: user_id
}
url = "channels/#{channel_id}/members"
self.post_data(url, payload)
end
def cgi_escape(string)
CGI.escape(string).gsub('+', '%20')
end
def get_channel_by_name(provided_channel_name, provided_team_name=nil)
if provided_team_name.nil? and provided_channel_name.include?(':')
(team_name, channel_name) = provided_channel_name.split(':')
else
team_name = provided_team_name
channel_name = provided_channel_name
end
if team_name.nil? || channel_name.include?(':')
raise "Invalid channel and team name: #{provided_channel_name} #{team_name}"
end
url = "teams/name/#{team_name}/channels/name/#{channel_name}"
response = self.get_url(url)
return response
end
private
def url_valid?(url)
url = URI.parse(url) rescue false
end
def get_url(url, query=nil)
@options[:query] = nil
unless query.nil?
@options[:query] = query
end
response = self.class.get("#{@base_uri}#{url}", @options)
@options[:query] = nil
if response.code >= 200 && response.code <= 300 # Successful
JSON.parse(response.to_s)
else
return nil
end
end
def post_data(request_url, payload)
@options[:body] = nil
unless payload.nil?
@options[:body] = payload.to_json
end
response = self.class.post("#{@base_uri}#{request_url}", @options)
@options[:body] = nil
if response.code >= 200 && response.code <= 300 # Successful
return JSON.parse(response.to_s)
else
$log.warn("Mattermost API error #{response.code}: #{response.to_s}")
return nil
end
end
def put_data(request_url, payload)
options = @options
options[:body] = payload.to_json
self.class.put("#{@base_uri}#{request_url}", options)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment