AnyEvent-SlackBot

 view release on metacpan or  search on metacpan

lib/AnyEvent/SlackBot.pm  view on Meta::CPAN

    return $self->new_false("Failed to get conenction info from slack, error was: ".$response->status_line);
  }
}

=item * my $id=$self->next_id

Provides an id for the next message.

=cut

sub next_id {
  my ($self)=@_;
  return ++$self->{next_id}
}

=item * if($self->is_connected) { ... }

Denotes if we are currently connected to slack

=cut

sub is_connected {
  return defined($_[0]->connection)
}

=item * $self->send($ref)

Converts $ref to json and sends it on the session.

=cut

sub send {
  my ($self,$ref)=@_;
  my $json=to_json($ref);
  if($self->connection) {
    $self->connection->send($json);
    ++$self->stats->{total_messages_sent};
  } else {
    push @{$self->{backlog}},$json;
  }
}

=item * $self->send_typing($json)

Given $json sends a currently typing reply

=cut

sub send_typing {
  my ($self,$json)=@_;
  my $id=$self->next_id;
  my $msg={
    bot_id=>$self->bot_id,
    channel=>$json->{channel},
    id=>$id,
    type=>'typing',
  };
  $self->send($msg);
}

=item * $self->post_to_web($msg,$endpoint|undef,"FORM"|"JSON"|undef)

Posts the to the given REST Endpoint outside of the WebSocket.

  msg:
    Hash ref representing the requrest being sent
      token: set to $self->token if not set
      scope: set to: 'chat:write:bot' if not set

  endpoint:
    The Rest xxx endpint, the default is 'chat.postMessage'

  type:
    Sets how the data will be sent over
    Supported options are:
      - FORM: posts the data using form encoding
      - JSON: converts $msg to a json string and posts

=cut

sub post_to_web {
  my ($self,$msg,$endpoint,$type)=@_;
  $endpoint='chat.postMessage' unless defined($endpoint);
  $type='FORM';

  $self->stats->{running_posts}++;
  my $url="https://slack.com/api/$endpoint";


  $msg->{token}=$self->token unless exists $msg->{token};
  $msg->{scope}='chat:write:bot'  unless exists $msg->{scope};

  my $request;

  if($type eq 'FORM') {
    $request=POST $url,[%{$msg}];
  } else {
    $request=POST $url,'Conent-Type'=>'application/json',Content=>to_json($msg);
  }

  $self->agent->add_cb($request,sub {
    my ($agent,$request,$response)=@_;
    ++$self->stats->{http_posts_sent};
    $self->stats->{running_posts}--;
    if($response->code!=200) {
      $self->log_error("Failed to send Message,error was: ".$response->status_line) ;
    } else {
      my $json=eval { from_json($response->decoded_content) };
      if($@) {
        $self->log_error("Failed to parse json response, error was: $@") 
      } else {
        $self->{ignore}->{$json->{ts}}++;
        $self->log_error("Slack Responded with an eror: $json->{error}".Dumper($json)) unless $json->{ok};
      }
    }

    if($self->stats->{running_posts}==0) {
      # some times we get a response from the websocet before
      # the http request completes

      BACKLOG: while(my $args=shift @{$self->unknown_que}) {
        my (undef,$ref,$data)=@{$args};
	$self->log_info("processing backlog event");

	next if $self->we_sent_msg($ref);

	$self->on_event->($self,$ref,$data);
      }
    }
  });
  $self->agent->run_next;
}

=item * if($self->we_sent_msg($json,$connection_data)) { ... }

When true, $json is a duplicate from something we sent

=cut

sub we_sent_msg {
  my ($self,$ref,$data)=@_;
  if(exists $ref->{msg}) {
    my $sent=delete $self->{ignore}->{$ref->{msg}};
    if(defined($sent)) {
      $self->info("This is a message we sent");
      $self->on_reply->($self,$ref,$data);
      return 1;;



( run in 1.139 second using v1.01-cache-2.11-cpan-2398b32b56e )