The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

AnyEvent::SparkBot - Cisco Spark WebSocket Client for the AnyEvent Loop

SYNOPSIS

use Modern::Perl;
use Data::Dumper;
use AnyEvent::SparkBot;
use AnyEvent::Loop;
$|=1;

our $obj=new AnyEvent::SparkBot(token=>$ENV{SPARK_TOKEN},on_message=>\&cb);

$obj->que_getWsUrl(sub { 
  my ($agent,$id,$result)=@_;

  # start here if we got a valid connection
  return $obj->start_connection if $result;
  $obj->handle_reconnect;
});
$obj->agent->run_next;
AnyEvent::Loop::run;

sub cb {
  my ($sb,$result,$eventType,$verb,$json)=@_;
  return unless $eventType eq 'conversation.activity' and $verb eq 'post';

  # Data::Result Object is False when combination of EvenType and Verb are unsupprted
  if($result) {
    my $data=$result->get_data;
    my $response={
      roomId=>$data->{roomId},
      personId=>$data->{personId},
      text=>"ya.. ya ya.. I'm on it!"
    };
    # Proxy our lookup in a Retry-After ( prevents a lot of errors )
    $obj->run_lookup('que_createMessage',(sub {},$response);
  } else {
    print "Error: $result\n";
  }
}

DESCRIPTION

Connects to cisco spark via a websocket. By itself this class only provides connectivty to Spark, the on_message callback is used to handle events that come in. By default No hanlder is provided.

Moo Role(s)

This module uses the following Moo role(s)

HTTP::MultiGet::Role
AnyEvent::SparkBot::SharedRole

OO Arguments and accessors

Required Argument(s)

token: The token used to authenticate the bot
on_message: code ref used to handle incomming messages

Optional Arguments

reconnect: default is true
logger: null(default) or an instance of log4perl::logger
lastConn: location to the last connection file
  # it may be a very good idea to set this value
  # default: /tmp/sparkBotLastConnect.json
defaultUrl: https://wdm-a.wbx2.com/wdm/api/v1/devices
  # this is where we authenticate and pull the websocket url from
deviceDesc: JSON hash, representing the client description
agent: an instance of AnyEvent::HTTP::MultiGet
retryTimeout: default 10, sets how long to wait afer getting a 429 error
retryCount: default 1, sets how many retries when we get a 429 error

Timout and retry values:

pingEvery: 60 # used to check how often we run a ping
  # pings only happen if no inbound request has come in for 
  # the interval
pingWait: 10 
  # how long to wait for a ping response
reconnect_sleep: 10
  # how long to wait before we try to reconnect

Objects set at runtime:

lastConn: sets the location of the last connection file
ping: sets an object that will wake up and do something
lastPing: contains the last ping string value
connection: contains the current websocket connection if any
spark: Instance of AnyEvent::HTTP::Spark
currentUser: Hash ref representing the current bot user

OO Methods

  • my $result=$self->new_true({qw( some data )});

    Returns a new true Data::Result object.

  • my $result=$self->new_false("why this failed")

    Returns a new false Data::Result object

  • my $self->start_connection()

    Starts the bot up.

  • $self->handle_message($connection,$message)

    Handles incoming messages

  • $self->run_lookup('que_method',$cb,@args);

    Proxies the internal $self->spark object in a method that honnors the Retry-After interval.

    Example:

    $self->run_lookup('que_getMe',sub {
      my ($sb,$id,$result,$request,$response)=@_;
      return print Dumper($result->get_data) if $result;
    
      warn "Failed to getMe, error was; $result";
    });
  • $self->handle_reconnect()

    Handles reconnecting to spark

  • $self->setPing()

    Sets the next ping object

  • $self->setPingWait()

    This method is called by ping, sets a timeout to wait for the response.

  • my $result=$self->getLastConn()

    Fetches the last connection info

    Returns a Data::Result Object, when true it contains the hash, when false it contains why it failed.

  • my $result=$self->saveLastConn($ref)

    Saves the last conenction, returns a Data::Result Object

    $ref is assumed to be the data strucutre intended to be serialzied into json

  • my $job_id=$self->que_deleteLastUrl($cb)

    Returns a Data::Result Object, when true it contains the url that was deleted, when false it contains why it failed.

  • my $job_id=$self->que_getWsUrl($cb)

    Gets the WebSocket URL

    Returns a Data::Result Object: When true it contains the url. When false it contains why it failed.

  • $self->log_delete_call($id,$result)

    Call back to handle logging clean up of previous session

AUTHOR

Michael Shipper <AKALINUX@CPAN.ORG>