AnyEvent-Mattermost
view release on metacpan or search on metacpan
lib/AnyEvent/Mattermost.pm view on Meta::CPAN
# ABSTRACT: AnyEvent module for interacting with Mattermost APIs
=pod
=encoding UTF-8
=head1 NAME
AnyEvent::Mattermost - AnyEvent module for interacting with the Mattermost APIs
=cut
use AnyEvent;
use AnyEvent::WebSocket::Client 0.37;
use Carp;
use Furl;
use JSON;
use Time::HiRes qw( time );
use Try::Tiny;
=head1 SYNOPSIS
use AnyEvent;
use AnyEvent::Mattermost;
my $host = "https://mattermost.example.com/";
my $team = "awesome-chat";
my $user = "janedoe@example.com";
my $pass = "foobar123";
my $cond = AnyEvent->condvar;
my $mconn = AnyEvent::Mattermost->new($host, $team, $user, $pass);
$mconn->on('posted' => sub {
my ($self, $message) = @_;
printf "<%s> %s\n", $message->{data}{sender_name}, $message->{data}{post}";
});
$mconn->start;
AnyEvent->condvar->recv;
=head1 DESCRIPTION
This module provides an L<AnyEvent> based interface to Mattermost chat servers
using the Web Service API.
It is very heavily inspired by L<AnyEvent::SlackRTM> and I owe a debt of
gratitude to Andrew Hanenkamp for his work on that module.
This library is still very basic and currently attempts to implement little
beyond authentication and simple message receiving and sending. Feature parity
with SlackRTM support is a definite goal, and then beyond that it would be nice
to support all the stable Mattermost API features. Baby steps.
=head1 METHODS
=cut
=head2 new
$mconn = AnyEvent::Mattermost->new( $host, $team, $email, $password );
Creates a new AnyEvent::Mattermost object. No connections are opened and no
callbacks are registered yet.
The C<$host> parameter must be the HTTP/HTTPS URL of your Mattermost server. If
you omit the scheme and provide only a hostname, HTTPS will be assumed. Note
that Mattermost servers configured over HTTP will also use unencrypted C<ws://>
for the persistent WebSockets connection for receiving incoming messages. You
should use HTTPS unless there is no other choice.
C<$team> must be the Mattermost team's short name (the version which appears in
the URLs when connected through the web client).
C<$email> must be the email address of the account to be used for logging into
the Mattermost server. The short username is not supported for logins via the
Mattermost APIs, only the email address.
C<$password> is hopefully self-explanatory.
=cut
sub new {
my ($class, $host, $team, $user, $pass) = @_;
croak "must provide a Mattermost server address"
unless defined $host && length($host) > 0;
croak "must provide a Mattermost team name"
unless defined $team && length($team) > 0;
croak "must provide a login email and password"
unless defined $user && defined $pass && length($user) > 0 && length($pass) > 0;
$host = "https://$host" unless $host =~ m{^https?://}i;
$host .= '/' unless substr($host, -1, 1) eq '/';
return bless {
furl => Furl->new( agent => "AnyEvent::Mattermost" ),
host => $host,
team => $team,
user => $user,
pass => $pass,
registry => {},
channels => {},
}, $class;
}
=head2 start
$mconn->start();
Opens the connection to the Mattermost server, authenticates the previously
provided account credentials and performs an initial data request for user,
team, and channel information.
Any errors encountered will croak() and the connection will be aborted.
=cut
sub start {
my ($self) = @_;
my $data = $self->_post('api/v3/users/login', {
name => $self->{'team'},
login_id => $self->{'user'},
password => $self->{'pass'},
});
croak "could not log in" unless exists $self->{'token'};
my $userdata = $self->_get('api/v3/users/initial_load');
croak "did not receive valid initial_load user data"
unless exists $userdata->{'user'}
&& ref($userdata->{'user'}) eq 'HASH'
&& exists $userdata->{'user'}{'id'};
croak "did not receive valid initial_load teams data"
unless exists $userdata->{'teams'}
&& ref($userdata->{'teams'}) eq 'ARRAY'
&& grep { $_->{'name'} eq $self->{'team'} } @{$userdata->{'teams'}};
$self->{'userdata'} = $userdata->{'user'};
$self->{'teamdata'} = (grep { $_->{'name'} eq $self->{'team'} } @{$userdata->{'teams'}})[0];
my $wss_url = $self->{'host'} . 'api/v3/users/websocket';
$wss_url =~ s{^http(s)?}{ws$1}i;
$self->{'client'} = AnyEvent::WebSocket::Client->new(
http_headers => $self->_headers
);
$self->{'client'}->connect($wss_url)->cb(sub {
my $client = shift;
my $conn = try {
$client->recv;
}
catch {
die $_;
};
$self->{'started'}++;
$self->{'conn'} = $conn;
$conn->on(each_message => sub { $self->_handle_incoming(@_) });
});
}
=head2 stop
$mconn->stop();
Closes connection with Mattermost server and ceases processing messages.
Callbacks which have been registered are left in place in case you wish to
start() the connection again.
If you wish to remove callbacks, without disposing of the AnyEvent::Mattermost
object itself, you will need to call on() and pass C<undef> for each events'
callback value (rather than the anonymous subroutines you had provided when
registering them).
=cut
sub stop {
my ($self) = @_;
( run in 0.783 second using v1.01-cache-2.11-cpan-bbe5e583499 )