diff --git a/contrib/vertobot/.gitignore b/contrib/vertobot/.gitignore
deleted file mode 100644
index 071a780574..0000000000
--- a/contrib/vertobot/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-vucbot.yaml
-vertobot.yaml
diff --git a/contrib/vertobot/bot.pl b/contrib/vertobot/bot.pl
deleted file mode 100755
index 31eed40925..0000000000
--- a/contrib/vertobot/bot.pl
+++ /dev/null
@@ -1,309 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-use 5.010; # //
-use IO::Socket::SSL qw(SSL_VERIFY_NONE);
-use IO::Async::Loop;
-use Net::Async::WebSocket::Client;
-use Net::Async::Matrix 0.11_002;
-use JSON;
-use YAML;
-use Data::UUID;
-use Getopt::Long;
-use Data::Dumper;
-
-binmode STDOUT, ":encoding(UTF-8)";
-binmode STDERR, ":encoding(UTF-8)";
-
-my $loop = IO::Async::Loop->new;
-# Net::Async::HTTP + SSL + IO::Poll doesn't play well. See
-# https://rt.cpan.org/Ticket/Display.html?id=93107
-ref $loop eq "IO::Async::Loop::Poll" and
- warn "Using SSL with IO::Poll causes known memory-leaks!!\n";
-
-GetOptions(
- 'C|config=s' => \my $CONFIG,
- 'eval-from=s' => \my $EVAL_FROM,
-) or exit 1;
-
-if( defined $EVAL_FROM ) {
- # An emergency 'eval() this file' hack
- $SIG{HUP} = sub {
- my $code = do {
- open my $fh, "<", $EVAL_FROM or warn( "Cannot read - $!" ), return;
- local $/; <$fh>
- };
-
- eval $code or warn "Cannot eval() - $@";
- };
-}
-
-defined $CONFIG or die "Must supply --config\n";
-
-my %CONFIG = %{ YAML::LoadFile( $CONFIG ) };
-
-my %MATRIX_CONFIG = %{ $CONFIG{matrix} };
-# No harm in always applying this
-$MATRIX_CONFIG{SSL_verify_mode} = SSL_VERIFY_NONE;
-
-# Track every Room object, so we can ->leave them all on shutdown
-my %bot_matrix_rooms;
-
-my $bridgestate = {};
-my $roomid_by_callid = {};
-
-my $bot_verto = Net::Async::WebSocket::Client->new(
- on_frame => sub {
- my ( $self, $frame ) = @_;
- warn "[Verto] receiving $frame";
- on_verto_json($frame);
- },
-);
-$loop->add( $bot_verto );
-
-my $sessid = lc new Data::UUID->create_str();
-
-my $bot_matrix = Net::Async::Matrix->new(
- %MATRIX_CONFIG,
- on_log => sub { warn "log: @_\n" },
- on_invite => sub {
- my ($matrix, $invite) = @_;
- warn "[Matrix] invited to: " . $invite->{room_id} . " by " . $invite->{inviter} . "\n";
-
- $matrix->join_room( $invite->{room_id} )->get;
- },
- on_room_new => sub {
- my ($matrix, $room) = @_;
-
- warn "[Matrix] have a room ID: " . $room->room_id . "\n";
-
- $bot_matrix_rooms{$room->room_id} = $room;
-
- # log in to verto on behalf of this room
- $bridgestate->{$room->room_id}->{sessid} = $sessid;
-
- $room->configure(
- on_message => \&on_room_message,
- );
-
- my $f = send_verto_json_request("login", {
- 'login' => $CONFIG{'verto-dialog-params'}{'login'},
- 'passwd' => $CONFIG{'verto-config'}{'passwd'},
- 'sessid' => $sessid,
- });
- $matrix->adopt_future($f);
-
- # we deliberately don't paginate the room, as we only care about
- # new calls
- },
- on_unknown_event => \&on_unknown_event,
- on_error => sub {
- print STDERR "Matrix failure: @_\n";
- },
-);
-$loop->add( $bot_matrix );
-
-sub on_unknown_event
-{
- my ($matrix, $event) = @_;
- print Dumper($event);
-
- my $room_id = $event->{room_id};
- my %dp = %{$CONFIG{'verto-dialog-params'}};
- $dp{callID} = $bridgestate->{$room_id}->{callid};
-
- if ($event->{type} eq 'm.call.invite') {
- $bridgestate->{$room_id}->{matrix_callid} = $event->{content}->{call_id};
- $bridgestate->{$room_id}->{callid} = lc new Data::UUID->create_str();
- $bridgestate->{$room_id}->{offer} = $event->{content}->{offer}->{sdp};
- $bridgestate->{$room_id}->{gathered_candidates} = 0;
- $roomid_by_callid->{ $bridgestate->{$room_id}->{callid} } = $room_id;
- # no trickle ICE in verto apparently
- }
- elsif ($event->{type} eq 'm.call.candidates') {
- # XXX: compare call IDs
- if (!$bridgestate->{$room_id}->{gathered_candidates}) {
- $bridgestate->{$room_id}->{gathered_candidates} = 1;
- my $offer = $bridgestate->{$room_id}->{offer};
- my $candidate_block = {
- audio => '',
- video => '',
- };
- foreach (@{$event->{content}->{candidates}}) {
- if ($_->{sdpMid}) {
- $candidate_block->{$_->{sdpMid}} .= "a=" . $_->{candidate} . "\r\n";
- }
- else {
- $candidate_block->{audio} .= "a=" . $_->{candidate} . "\r\n";
- $candidate_block->{video} .= "a=" . $_->{candidate} . "\r\n";
- }
- }
-
- # XXX: assumes audio comes first
- #$offer =~ s/(a=rtcp-mux[\r\n]+)/$1$candidate_block->{audio}/;
- #$offer =~ s/(a=rtcp-mux[\r\n]+)/$1$candidate_block->{video}/;
-
- $offer =~ s/(m=video)/$candidate_block->{audio}$1/;
- $offer =~ s/(.$)/$1\n$candidate_block->{video}$1/;
-
- my $f = send_verto_json_request("verto.invite", {
- "sdp" => $offer,
- "dialogParams" => \%dp,
- "sessid" => $bridgestate->{$room_id}->{sessid},
- });
- $matrix->adopt_future($f);
- }
- else {
- # ignore them, as no trickle ICE, although we might as well
- # batch them up
- # foreach (@{$event->{content}->{candidates}}) {
- # push @{$bridgestate->{$room_id}->{candidates}}, $_;
- # }
- }
- }
- elsif ($event->{type} eq 'm.call.hangup') {
- if ($bridgestate->{$room_id}->{matrix_callid} eq $event->{content}->{call_id}) {
- my $f = send_verto_json_request("verto.bye", {
- "dialogParams" => \%dp,
- "sessid" => $bridgestate->{$room_id}->{sessid},
- });
- $matrix->adopt_future($f);
- }
- else {
- warn "Ignoring unrecognised callid: ".$event->{content}->{call_id};
- }
- }
- else {
- warn "Unhandled event: $event->{type}";
- }
-}
-
-sub on_room_message
-{
- my ($room, $from, $content) = @_;
- my $room_id = $room->room_id;
- warn "[Matrix] in $room_id: $from: " . $content->{body} . "\n";
-}
-
-Future->needs_all(
- $bot_matrix->login( %{ $CONFIG{"matrix-bot"} } )->then( sub {
- $bot_matrix->start;
- }),
-
- $bot_verto->connect(
- %{ $CONFIG{"verto-bot"} },
- on_connect_error => sub { die "Cannot connect to verto - $_[-1]" },
- on_resolve_error => sub { die "Cannot resolve to verto - $_[-1]" },
- )->on_done( sub {
- warn("[Verto] connected to websocket");
- }),
-)->get;
-
-$loop->attach_signal(
- PIPE => sub { warn "pipe\n" }
-);
-$loop->attach_signal(
- INT => sub { $loop->stop },
-);
-$loop->attach_signal(
- TERM => sub { $loop->stop },
-);
-
-eval {
- $loop->run;
-} or my $e = $@;
-
-# When the bot gets shut down, have it leave the rooms so it's clear to observers
-# that it is no longer running.
-# if( $CONFIG{"leave-on-shutdown"} // 1 ) {
-# print STDERR "Removing bot from Matrix rooms...\n";
-# Future->wait_all( map { $_->leave->else_done() } values %bot_matrix_rooms )->get;
-# }
-# else {
-# print STDERR "Leaving bot users in Matrix rooms.\n";
-# }
-
-die $e if $e;
-
-exit 0;
-
-{
- my $json_id;
- my $requests;
-
- sub send_verto_json_request
- {
- $json_id ||= 1;
-
- my ($method, $params) = @_;
- my $json = {
- jsonrpc => "2.0",
- method => $method,
- params => $params,
- id => $json_id,
- };
- my $text = JSON->new->encode( $json );
- warn "[Verto] sending $text";
- $bot_verto->send_frame ( $text );
- my $request = $loop->new_future;
- $requests->{$json_id} = $request;
- $json_id++;
- return $request;
- }
-
- sub send_verto_json_response
- {
- my ($result, $id) = @_;
- my $json = {
- jsonrpc => "2.0",
- result => $result,
- id => $id,
- };
- my $text = JSON->new->encode( $json );
- warn "[Verto] sending $text";
- $bot_verto->send_frame ( $text );
- }
-
- sub on_verto_json
- {
- my $json = JSON->new->decode( $_[0] );
- if ($json->{method}) {
- if (($json->{method} eq 'verto.answer' && $json->{params}->{sdp}) ||
- $json->{method} eq 'verto.media') {
-
- my $room_id = $roomid_by_callid->{$json->{params}->{callID}};
- my $room = $bot_matrix_rooms{$room_id};
-
- if ($json->{params}->{sdp}) {
- # HACK HACK HACK HACK
- $room->_do_POST_json( "/send/m.call.answer", {
- call_id => $bridgestate->{$room_id}->{matrix_callid},
- version => 0,
- answer => {
- sdp => $json->{params}->{sdp},
- type => "answer",
- },
- })->then( sub {
- send_verto_json_response( {
- method => $json->{method},
- }, $json->{id});
- })->get;
- }
- }
- else {
- warn ("[Verto] unhandled method: " . $json->{method});
- send_verto_json_response( {
- method => $json->{method},
- }, $json->{id});
- }
- }
- elsif ($json->{result}) {
- $requests->{$json->{id}}->done($json->{result});
- }
- elsif ($json->{error}) {
- $requests->{$json->{id}}->fail($json->{error}->{message}, $json->{error});
- }
- }
-}
-
diff --git a/contrib/vertobot/bridge.pl b/contrib/vertobot/bridge.pl
deleted file mode 100755
index a551850f40..0000000000
--- a/contrib/vertobot/bridge.pl
+++ /dev/null
@@ -1,493 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-use 5.010; # //
-use IO::Socket::SSL qw(SSL_VERIFY_NONE);
-use IO::Async::Loop;
-use Net::Async::WebSocket::Client;
-use Net::Async::HTTP;
-use Net::Async::HTTP::Server;
-use JSON;
-use YAML;
-use Data::UUID;
-use Getopt::Long;
-use Data::Dumper;
-use URI::Encode qw(uri_encode uri_decode);
-
-binmode STDOUT, ":encoding(UTF-8)";
-binmode STDERR, ":encoding(UTF-8)";
-
-my $msisdn_to_matrix = {
- '447417892400' => '@matthew:matrix.org',
-};
-
-my $matrix_to_msisdn = {};
-foreach (keys %$msisdn_to_matrix) {
- $matrix_to_msisdn->{$msisdn_to_matrix->{$_}} = $_;
-}
-
-
-my $loop = IO::Async::Loop->new;
-# Net::Async::HTTP + SSL + IO::Poll doesn't play well. See
-# https://rt.cpan.org/Ticket/Display.html?id=93107
-# ref $loop eq "IO::Async::Loop::Poll" and
-# warn "Using SSL with IO::Poll causes known memory-leaks!!\n";
-
-GetOptions(
- 'C|config=s' => \my $CONFIG,
- 'eval-from=s' => \my $EVAL_FROM,
-) or exit 1;
-
-if( defined $EVAL_FROM ) {
- # An emergency 'eval() this file' hack
- $SIG{HUP} = sub {
- my $code = do {
- open my $fh, "<", $EVAL_FROM or warn( "Cannot read - $!" ), return;
- local $/; <$fh>
- };
-
- eval $code or warn "Cannot eval() - $@";
- };
-}
-
-defined $CONFIG or die "Must supply --config\n";
-
-my %CONFIG = %{ YAML::LoadFile( $CONFIG ) };
-
-my %MATRIX_CONFIG = %{ $CONFIG{matrix} };
-# No harm in always applying this
-$MATRIX_CONFIG{SSL_verify_mode} = SSL_VERIFY_NONE;
-
-my $bridgestate = {};
-my $roomid_by_callid = {};
-
-my $sessid = lc new Data::UUID->create_str();
-my $as_token = $CONFIG{"matrix-bot"}->{as_token};
-my $hs_domain = $CONFIG{"matrix-bot"}->{domain};
-
-my $http = Net::Async::HTTP->new();
-$loop->add( $http );
-
-sub create_virtual_user
-{
- my ($localpart) = @_;
- my ( $response ) = $http->do_request(
- method => "POST",
- uri => URI->new(
- $CONFIG{"matrix"}->{server}.
- "/_matrix/client/api/v1/register?".
- "access_token=$as_token&user_id=$localpart"
- ),
- content_type => "application/json",
- content => <<EOT
-{
- "type": "m.login.application_service",
- "user": "$localpart"
-}
-EOT
- )->get;
- warn $response->as_string if ($response->code != 200);
-}
-
-my $http_server = Net::Async::HTTP::Server->new(
- on_request => sub {
- my $self = shift;
- my ( $req ) = @_;
-
- my $response;
- my $path = uri_decode($req->path);
- warn("request: $path");
- if ($path =~ m#/users/\@(\+.*)#) {
- # when queried about virtual users, auto-create them in the HS
- my $localpart = $1;
- create_virtual_user($localpart);
- $response = HTTP::Response->new( 200 );
- $response->add_content('{}');
- $response->content_type( "application/json" );
- }
- elsif ($path =~ m#/transactions/(.*)#) {
- my $event = JSON->new->decode($req->body);
- print Dumper($event);
-
- my $room_id = $event->{room_id};
- my %dp = %{$CONFIG{'verto-dialog-params'}};
- $dp{callID} = $bridgestate->{$room_id}->{callid};
-
- if ($event->{type} eq 'm.room.membership') {
- my $membership = $event->{content}->{membership};
- my $state_key = $event->{state_key};
- my $room_id = $event->{state_id};
-
- if ($membership eq 'invite') {
- # autojoin invites
- my ( $response ) = $http->do_request(
- method => "POST",
- uri => URI->new(
- $CONFIG{"matrix"}->{server}.
- "/_matrix/client/api/v1/rooms/$room_id/join?".
- "access_token=$as_token&user_id=$state_key"
- ),
- content_type => "application/json",
- content => "{}",
- )->get;
- warn $response->as_string if ($response->code != 200);
- }
- }
- elsif ($event->{type} eq 'm.call.invite') {
- my $room_id = $event->{room_id};
- $bridgestate->{$room_id}->{matrix_callid} = $event->{content}->{call_id};
- $bridgestate->{$room_id}->{callid} = lc new Data::UUID->create_str();
- $bridgestate->{$room_id}->{sessid} = $sessid;
- # $bridgestate->{$room_id}->{offer} = $event->{content}->{offer}->{sdp};
- my $offer = $event->{content}->{offer}->{sdp};
- # $bridgestate->{$room_id}->{gathered_candidates} = 0;
- $roomid_by_callid->{ $bridgestate->{$room_id}->{callid} } = $room_id;
- # no trickle ICE in verto apparently
-
- my $f = send_verto_json_request("verto.invite", {
- "sdp" => $offer,
- "dialogParams" => \%dp,
- "sessid" => $bridgestate->{$room_id}->{sessid},
- });
- $self->adopt_future($f);
- }
- # elsif ($event->{type} eq 'm.call.candidates') {
- # # XXX: this could fire for both matrix->verto and verto->matrix calls
- # # and races as it collects candidates. much better to just turn off
- # # candidate gathering in the webclient entirely for now
- #
- # my $room_id = $event->{room_id};
- # # XXX: compare call IDs
- # if (!$bridgestate->{$room_id}->{gathered_candidates}) {
- # $bridgestate->{$room_id}->{gathered_candidates} = 1;
- # my $offer = $bridgestate->{$room_id}->{offer};
- # my $candidate_block = "";
- # foreach (@{$event->{content}->{candidates}}) {
- # $candidate_block .= "a=" . $_->{candidate} . "\r\n";
- # }
- # # XXX: collate using the right m= line - for now assume audio call
- # $offer =~ s/(a=rtcp.*[\r\n]+)/$1$candidate_block/;
- #
- # my $f = send_verto_json_request("verto.invite", {
- # "sdp" => $offer,
- # "dialogParams" => \%dp,
- # "sessid" => $bridgestate->{$room_id}->{sessid},
- # });
- # $self->adopt_future($f);
- # }
- # else {
- # # ignore them, as no trickle ICE, although we might as well
- # # batch them up
- # # foreach (@{$event->{content}->{candidates}}) {
- # # push @{$bridgestate->{$room_id}->{candidates}}, $_;
- # # }
- # }
- # }
- elsif ($event->{type} eq 'm.call.answer') {
- # grab the answer and relay it to verto as a verto.answer
- my $room_id = $event->{room_id};
-
- my $answer = $event->{content}->{answer}->{sdp};
- my $f = send_verto_json_request("verto.answer", {
- "sdp" => $answer,
- "dialogParams" => \%dp,
- "sessid" => $bridgestate->{$room_id}->{sessid},
- });
- $self->adopt_future($f);
- }
- elsif ($event->{type} eq 'm.call.hangup') {
- my $room_id = $event->{room_id};
- if ($bridgestate->{$room_id}->{matrix_callid} eq $event->{content}->{call_id}) {
- my $f = send_verto_json_request("verto.bye", {
- "dialogParams" => \%dp,
- "sessid" => $bridgestate->{$room_id}->{sessid},
- });
- $self->adopt_future($f);
- }
- else {
- warn "Ignoring unrecognised callid: ".$event->{content}->{call_id};
- }
- }
- else {
- warn "Unhandled event: $event->{type}";
- }
-
- $response = HTTP::Response->new( 200 );
- $response->add_content('{}');
- $response->content_type( "application/json" );
- }
- else {
- warn "Unhandled path: $path";
- $response = HTTP::Response->new( 404 );
- }
-
- $req->respond( $response );
- },
-);
-$loop->add( $http_server );
-
-$http_server->listen(
- addr => { family => "inet", socktype => "stream", port => 8009 },
- on_listen_error => sub { die "Cannot listen - $_[-1]\n" },
-);
-
-my $bot_verto = Net::Async::WebSocket::Client->new(
- on_frame => sub {
- my ( $self, $frame ) = @_;
- warn "[Verto] receiving $frame";
- on_verto_json($frame);
- },
-);
-$loop->add( $bot_verto );
-
-my $verto_connecting = $loop->new_future;
-$bot_verto->connect(
- %{ $CONFIG{"verto-bot"} },
- on_connected => sub {
- warn("[Verto] connected to websocket");
- if (not $verto_connecting->is_done) {
- $verto_connecting->done($bot_verto);
-
- send_verto_json_request("login", {
- 'login' => $CONFIG{'verto-dialog-params'}{'login'},
- 'passwd' => $CONFIG{'verto-config'}{'passwd'},
- 'sessid' => $sessid,
- });
- }
- },
- on_connect_error => sub { die "Cannot connect to verto - $_[-1]" },
- on_resolve_error => sub { die "Cannot resolve to verto - $_[-1]" },
-);
-
-# die Dumper($verto_connecting);
-
-my $as_url = $CONFIG{"matrix-bot"}->{as_url};
-
-Future->needs_all(
- $http->do_request(
- method => "POST",
- uri => URI->new( $CONFIG{"matrix"}->{server}."/_matrix/appservice/v1/register" ),
- content_type => "application/json",
- content => <<EOT
-{
- "as_token": "$as_token",
- "url": "$as_url",
- "namespaces": { "users": [ { "regex": "\@\\\\+.*", "exclusive": false } ] }
-}
-EOT
- )->then( sub{
- my ($response) = (@_);
- warn $response->as_string if ($response->code != 200);
- return Future->done;
- }),
- $verto_connecting,
-)->get;
-
-$loop->attach_signal(
- PIPE => sub { warn "pipe\n" }
-);
-$loop->attach_signal(
- INT => sub { $loop->stop },
-);
-$loop->attach_signal(
- TERM => sub { $loop->stop },
-);
-
-eval {
- $loop->run;
-} or my $e = $@;
-
-die $e if $e;
-
-exit 0;
-
-{
- my $json_id;
- my $requests;
-
- sub send_verto_json_request
- {
- $json_id ||= 1;
-
- my ($method, $params) = @_;
- my $json = {
- jsonrpc => "2.0",
- method => $method,
- params => $params,
- id => $json_id,
- };
- my $text = JSON->new->encode( $json );
- warn "[Verto] sending $text";
- $bot_verto->send_frame ( $text );
- my $request = $loop->new_future;
- $requests->{$json_id} = $request;
- $json_id++;
- return $request;
- }
-
- sub send_verto_json_response
- {
- my ($result, $id) = @_;
- my $json = {
- jsonrpc => "2.0",
- result => $result,
- id => $id,
- };
- my $text = JSON->new->encode( $json );
- warn "[Verto] sending $text";
- $bot_verto->send_frame ( $text );
- }
-
- sub on_verto_json
- {
- my $json = JSON->new->decode( $_[0] );
- if ($json->{method}) {
- if (($json->{method} eq 'verto.answer' && $json->{params}->{sdp}) ||
- $json->{method} eq 'verto.media') {
-
- my $caller = $json->{dialogParams}->{caller_id_number};
- my $callee = $json->{dialogParams}->{destination_number};
- my $caller_user = '@+' . $caller . ':' . $hs_domain;
- my $callee_user = $msisdn_to_matrix->{$callee} || warn "unrecogised callee: $callee";
- my $room_id = $roomid_by_callid->{$json->{params}->{callID}};
-
- if ($json->{params}->{sdp}) {
- $http->do_request(
- method => "POST",
- uri => URI->new(
- $CONFIG{"matrix"}->{server}.
- "/_matrix/client/api/v1/send/m.call.answer?".
- "access_token=$as_token&user_id=$caller_user"
- ),
- content_type => "application/json",
- content => JSON->new->encode({
- call_id => $bridgestate->{$room_id}->{matrix_callid},
- version => 0,
- answer => {
- sdp => $json->{params}->{sdp},
- type => "answer",
- },
- }),
- )->then( sub {
- send_verto_json_response( {
- method => $json->{method},
- }, $json->{id});
- })->get;
- }
- }
- elsif ($json->{method} eq 'verto.invite') {
- my $caller = $json->{dialogParams}->{caller_id_number};
- my $callee = $json->{dialogParams}->{destination_number};
- my $caller_user = '@+' . $caller . ':' . $hs_domain;
- my $callee_user = $msisdn_to_matrix->{$callee} || warn "unrecogised callee: $callee";
-
- my $alias = ($caller lt $callee) ? ($caller.'-'.$callee) : ($callee.'-'.$caller);
- my $room_id;
-
- # create a virtual user for the caller if needed.
- create_virtual_user($caller);
-
- # create a room of form #peer-peer and invite the callee
- $http->do_request(
- method => "POST",
- uri => URI->new(
- $CONFIG{"matrix"}->{server}.
- "/_matrix/client/api/v1/createRoom?".
- "access_token=$as_token&user_id=$caller_user"
- ),
- content_type => "application/json",
- content => JSON->new->encode({
- room_alias_name => $alias,
- invite => [ $callee_user ],
- }),
- )->then( sub {
- my ( $response ) = @_;
- my $resp = JSON->new->decode($response->content);
- $room_id = $resp->{room_id};
- $roomid_by_callid->{$json->{params}->{callID}} = $room_id;
- })->get;
-
- # join it
- my ($response) = $http->do_request(
- method => "POST",
- uri => URI->new(
- $CONFIG{"matrix"}->{server}.
- "/_matrix/client/api/v1/join/$room_id?".
- "access_token=$as_token&user_id=$caller_user"
- ),
- content_type => "application/json",
- content => '{}',
- )->get;
-
- $bridgestate->{$room_id}->{matrix_callid} = lc new Data::UUID->create_str();
- $bridgestate->{$room_id}->{callid} = $json->{dialogParams}->{callID};
- $bridgestate->{$room_id}->{sessid} = $sessid;
-
- # put the m.call.invite in there
- $http->do_request(
- method => "POST",
- uri => URI->new(
- $CONFIG{"matrix"}->{server}.
- "/_matrix/client/api/v1/send/m.call.invite?".
- "access_token=$as_token&user_id=$caller_user"
- ),
- content_type => "application/json",
- content => JSON->new->encode({
- call_id => $bridgestate->{$room_id}->{matrix_callid},
- version => 0,
- answer => {
- sdp => $json->{params}->{sdp},
- type => "offer",
- },
- }),
- )->then( sub {
- # acknowledge the verto
- send_verto_json_response( {
- method => $json->{method},
- }, $json->{id});
- })->get;
- }
- elsif ($json->{method} eq 'verto.bye') {
- my $caller = $json->{dialogParams}->{caller_id_number};
- my $callee = $json->{dialogParams}->{destination_number};
- my $caller_user = '@+' . $caller . ':' . $hs_domain;
- my $callee_user = $msisdn_to_matrix->{$callee} || warn "unrecogised callee: $callee";
- my $room_id = $roomid_by_callid->{$json->{params}->{callID}};
-
- # put the m.call.hangup into the room
- $http->do_request(
- method => "POST",
- uri => URI->new(
- $CONFIG{"matrix"}->{server}.
- "/_matrix/client/api/v1/send/m.call.hangup?".
- "access_token=$as_token&user_id=$caller_user"
- ),
- content_type => "application/json",
- content => JSON->new->encode({
- call_id => $bridgestate->{$room_id}->{matrix_callid},
- version => 0,
- }),
- )->then( sub {
- # acknowledge the verto
- send_verto_json_response( {
- method => $json->{method},
- }, $json->{id});
- })->get;
- }
- else {
- warn ("[Verto] unhandled method: " . $json->{method});
- send_verto_json_response( {
- method => $json->{method},
- }, $json->{id});
- }
- }
- elsif ($json->{result}) {
- $requests->{$json->{id}}->done($json->{result});
- }
- elsif ($json->{error}) {
- $requests->{$json->{id}}->fail($json->{error}->{message}, $json->{error});
- }
- }
-}
-
diff --git a/contrib/vertobot/config.yaml b/contrib/vertobot/config.yaml
deleted file mode 100644
index 555d9389d7..0000000000
--- a/contrib/vertobot/config.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-# Generic Matrix connection params
-matrix:
- server: 'matrix.org'
- SSL: 1
-
-# Bot-user connection details
-matrix-bot:
- user_id: '@vertobot:matrix.org'
- password: ''
- domain: 'matrix.org"
- as_url: 'http://localhost:8009'
- as_token: 'vertobot123'
-
-verto-bot:
- host: webrtc.freeswitch.org
- service: 8081
- url: "ws://webrtc.freeswitch.org:8081/"
-
-verto-config:
- passwd: 1234
-
-verto-dialog-params:
- useVideo: false
- useStereo: false
- tag: "webcam"
- login: "1008@webrtc.freeswitch.org"
- destination_number: "9664"
- caller_id_name: "FreeSWITCH User"
- caller_id_number: "1008"
- callID: ""
- remote_caller_id_name: "Outbound Call"
- remote_caller_id_number: "9664"
diff --git a/contrib/vertobot/cpanfile b/contrib/vertobot/cpanfile
deleted file mode 100644
index 800dc288ed..0000000000
--- a/contrib/vertobot/cpanfile
+++ /dev/null
@@ -1,14 +0,0 @@
-requires 'parent', 0;
-requires 'Future', '>= 0.29';
-requires 'Net::Async::Matrix', '>= 0.11_002';
-requires 'Net::Async::Matrix::Utils';
-requires 'Net::Async::WebSocket::Protocol', 0;
-requires 'Data::UUID', 0;
-requires 'IO::Async', '>= 0.63';
-requires 'IO::Async::SSL', 0;
-requires 'IO::Socket::SSL', 0;
-requires 'YAML', 0;
-requires 'JSON', 0;
-requires 'Getopt::Long', 0;
-
-
diff --git a/contrib/vertobot/verto-example.json b/contrib/vertobot/verto-example.json
deleted file mode 100644
index e0230498a6..0000000000
--- a/contrib/vertobot/verto-example.json
+++ /dev/null
@@ -1,207 +0,0 @@
-# JSON is shown in *reverse* chronological order.
-# Send v. Receive is implicit.
-
-{
- "jsonrpc": "2.0",
- "id": 7,
- "result": {
- "callID": "12795aa6-2a8d-84ee-ce63-2e82ffe825ef",
- "message": "CALL ENDED",
- "causeCode": 16,
- "cause": "NORMAL_CLEARING",
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- }
-}
-
-{
- "jsonrpc": "2.0",
- "method": "verto.bye",
- "params": {
- "dialogParams": {
- "useVideo": false,
- "useStereo": true,
- "tag": "webcam",
- "login": "1008@webrtc.freeswitch.org",
- "destination_number": "9664",
- "caller_id_name": "FreeSWITCH User",
- "caller_id_number": "1008",
- "callID": "12795aa6-2a8d-84ee-ce63-2e82ffe825ef",
- "remote_caller_id_name": "Outbound Call",
- "remote_caller_id_number": "9664"
- },
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- },
- "id": 7
-}
-
-{
- "jsonrpc": "2.0",
- "id": 6,
- "result": {
- "callID": "12795aa6-2a8d-84ee-ce63-2e82ffe825ef",
- "action": "toggleHold",
- "holdState": "active",
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- }
-}
-
-{
- "jsonrpc": "2.0",
- "method": "verto.modify",
- "params": {
- "action": "toggleHold",
- "dialogParams": {
- "useVideo": false,
- "useStereo": true,
- "tag": "webcam",
- "login": "1008@webrtc.freeswitch.org",
- "destination_number": "9664",
- "caller_id_name": "FreeSWITCH User",
- "caller_id_number": "1008",
- "callID": "12795aa6-2a8d-84ee-ce63-2e82ffe825ef",
- "remote_caller_id_name": "Outbound Call",
- "remote_caller_id_number": "9664"
- },
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- },
- "id": 6
-}
-
-{
- "jsonrpc": "2.0",
- "id": 5,
- "result": {
- "callID": "12795aa6-2a8d-84ee-ce63-2e82ffe825ef",
- "action": "toggleHold",
- "holdState": "held",
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- }
-}
-
-{
- "jsonrpc": "2.0",
- "method": "verto.modify",
- "params": {
- "action": "toggleHold",
- "dialogParams": {
- "useVideo": false,
- "useStereo": true,
- "tag": "webcam",
- "login": "1008@webrtc.freeswitch.org",
- "destination_number": "9664",
- "caller_id_name": "FreeSWITCH User",
- "caller_id_number": "1008",
- "callID": "12795aa6-2a8d-84ee-ce63-2e82ffe825ef",
- "remote_caller_id_name": "Outbound Call",
- "remote_caller_id_number": "9664"
- },
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- },
- "id": 5
-}
-
-{
- "jsonrpc": "2.0",
- "id": 349819,
- "result": {
- "method": "verto.answer"
- }
-}
-
-{
- "jsonrpc": "2.0",
- "id": 349819,
- "method": "verto.answer",
- "params": {
- "callID": "12795aa6-2a8d-84ee-ce63-2e82ffe825ef",
- "sdp": "v=0\no=FreeSWITCH 1417101432 1417101433 IN IP4 209.105.235.10\ns=FreeSWITCH\nc=IN IP4 209.105.235.10\nt=0 0\na=msid-semantic: WMS jA3rmwLVwUq1iE6TYEYHeLk2YTUlh1Vq\nm=audio 30134 RTP/SAVPF 111 126\na=rtpmap:111 opus/48000/2\na=fmtp:111 minptime=10; stereo=1\na=rtpmap:126 telephone-event/8000\na=silenceSupp:off - - - -\na=ptime:20\na=sendrecv\na=fingerprint:sha-256 F8:72:18:E9:72:89:99:22:5B:F8:B6:C6:C6:0D:C5:9B:B2:FB:BC:CA:8D:AB:13:8A:66:E1:37:38:A0:16:AA:41\na=rtcp-mux\na=rtcp:30134 IN IP4 209.105.235.10\na=ssrc:210967934 cname:rOIEajpw4FocakWY\na=ssrc:210967934 msid:jA3rmwLVwUq1iE6TYEYHeLk2YTUlh1Vq a0\na=ssrc:210967934 mslabel:jA3rmwLVwUq1iE6TYEYHeLk2YTUlh1Vq\na=ssrc:210967934 label:jA3rmwLVwUq1iE6TYEYHeLk2YTUlh1Vqa0\na=ice-ufrag:OKwTmGLapwmxn7OF\na=ice-pwd:MmaMwq8rVmtWxfLbQ7U2Ew3T\na=candidate:2372654928 1 udp 659136 209.105.235.10 30134 typ host generation 0\n"
- }
-}
-
-{
- "jsonrpc": "2.0",
- "id": 4,
- "result": {
- "message": "CALL CREATED",
- "callID": "12795aa6-2a8d-84ee-ce63-2e82ffe825ef",
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- }
-}
-
-{
- "jsonrpc": "2.0",
- "method": "verto.invite",
- "params": {
- "sdp": "v=0\r\no=- 1381685806032722557 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE audio\r\na=msid-semantic: WMS 6OOMyGAyJakjwaOOBtV7WcBCCuIW6PpuXsNg\r\nm=audio 63088 RTP/SAVPF 111 103 104 0 8 106 105 13 126\r\nc=IN IP4 81.138.8.249\r\na=rtcp:63088 IN IP4 81.138.8.249\r\na=candidate:460398169 1 udp 2122260223 10.10.79.10 49945 typ host generation 0\r\na=candidate:460398169 2 udp 2122260223 10.10.79.10 49945 typ host generation 0\r\na=candidate:3460887983 1 udp 2122194687 192.168.1.64 63088 typ host generation 0\r\na=candidate:3460887983 2 udp 2122194687 192.168.1.64 63088 typ host generation 0\r\na=candidate:945327227 1 udp 1685987071 81.138.8.249 63088 typ srflx raddr 192.168.1.64 rport 63088 generation 0\r\na=candidate:945327227 2 udp 1685987071 81.138.8.249 63088 typ srflx raddr 192.168.1.64 rport 63088 generation 0\r\na=candidate:1441981097 1 tcp 1518280447 10.10.79.10 0 typ host tcptype active generation 0\r\na=candidate:1441981097 2 tcp 1518280447 10.10.79.10 0 typ host tcptype active generation 0\r\na=candidate:2160789855 1 tcp 1518214911 192.168.1.64 0 typ host tcptype active generation 0\r\na=candidate:2160789855 2 tcp 1518214911 192.168.1.64 0 typ host tcptype active generation 0\r\na=ice-ufrag:cP4qeRhn0LpcpA88\r\na=ice-pwd:fREmgSkXsDLGUUH1bwfrBQhW\r\na=ice-options:google-ice\r\na=fingerprint:sha-256 AF:35:64:1B:62:8A:EF:27:AE:2B:88:2E:FE:78:29:0B:08:DA:64:6C:DE:02:57:E3:EE:B1:D7:86:B8:36:8F:B0\r\na=setup:actpass\r\na=mid:audio\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=sendrecv\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=fmtp:111 minptime=10; stereo=1\r\na=rtpmap:103 ISAC/16000\r\na=rtpmap:104 ISAC/32000\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:106 CN/32000\r\na=rtpmap:105 CN/16000\r\na=rtpmap:13 CN/8000\r\na=rtpmap:126 telephone-event/8000\r\na=maxptime:60\r\na=ssrc:558827154 cname:vdKHBNqa17t2gmE3\r\na=ssrc:558827154 msid:6OOMyGAyJakjwaOOBtV7WcBCCuIW6PpuXsNg bf1303fb-9833-4d7d-b9e4-b32cfe04acc3\r\na=ssrc:558827154 mslabel:6OOMyGAyJakjwaOOBtV7WcBCCuIW6PpuXsNg\r\na=ssrc:558827154 label:bf1303fb-9833-4d7d-b9e4-b32cfe04acc3\r\n",
- "dialogParams": {
- "useVideo": false,
- "useStereo": true,
- "tag": "webcam",
- "login": "1008@webrtc.freeswitch.org",
- "destination_number": "9664",
- "caller_id_name": "FreeSWITCH User",
- "caller_id_number": "1008",
- "callID": "12795aa6-2a8d-84ee-ce63-2e82ffe825ef",
- "remote_caller_id_name": "Outbound Call",
- "remote_caller_id_number": "9664"
- },
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- },
- "id": 4
-}
-
-{
- "jsonrpc": "2.0",
- "id": 3,
- "result": {
- "message": "logged in",
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- }
-}
-
-{
- "jsonrpc": "2.0",
- "id": 1,
- "error": {
- "code": -32000,
- "message": "Authentication Required"
- }
-}
-
-{
- "jsonrpc": "2.0",
- "method": "login",
- "params": {
- "login": "1008@webrtc.freeswitch.org",
- "passwd": "1234",
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- },
- "id": 3
-}
-
-{
- "jsonrpc": "2.0",
- "id": 2,
- "error": {
- "code": -32000,
- "message": "Authentication Required"
- }
-}
-
-{
- "jsonrpc": "2.0",
- "method": "login",
- "params": {
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- },
- "id": 1
-}
-
-{
- "jsonrpc": "2.0",
- "method": "login",
- "params": {
- "sessid": "03a11060-3e14-23b6-c620-51b892c52983"
- },
- "id": 2
-}
|