-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Connection.pm6
114 lines (86 loc) · 2.97 KB
/
Connection.pm6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use API::Discord::Exceptions;
use API::Discord::WebSocket::Messages;
use API::Discord::WebSocket;
unit class API::Discord::Connection;
=begin pod
=head1 NAME
API::Discord::Connection - Combines a websocket and a REST client
=head1 DESCRIPTION
Discord sends us information over the websocket, and we send it stuff over the
REST client. Mostly.
This is used internally and probably of limited use otherwise.
=head1 SYNOPSIS
my $c = API::Discord::Connection.new:
:url(wss://...),
:$token,
;
... # other stuff
=head1 PROPERTIES
=end pod
use API::Discord::Types;
use API::Discord::HTTPResource;
# Probably make API::Discord::Connection::WS later for hb etc
use Cro::HTTP::Client;
#| Websocket URL
has Str $.ws-url is required;
#| REST URL
has Str $.rest-url is required;
#| User's bot/API token
has Str $.token is required;
#| Allows multiple instances to run the same bot
has Int $.shard = 0;
has Int $.shards-max = 1;
#| The Cro HTTP client used for REST-y stuff.
has Cro::HTTP::Client $!rest;
#| The Discord WebScoket object, which parses raw WebSocket messages into Discord
#| messages, as well as handling protocol details such as sessions, sequences, and
#| heartbeats. There may be many connections over the lifetime of this object.
has API::Discord::WebSocket $!websocket .= new(ws-url => $!ws-url, token => $!token);
#| This Promise is kept when Discord has sent us a READY event
has Promise $.ready = Promise.new;
=begin pod
=head1 METHODS
=head2 new
C<$.ws-url>, C<$.rest-url> and C<$.token> are required here.
=end pod
submethod TWEAK {
# TODO: We should also take the user-agent URL and the REST URL as
# constructor parameters
$!rest = Cro::HTTP::Client.new(
content-type => 'application/json',
http => '1.1',
headers => [
Authorization => 'Bot ' ~ $!token,
User-agent => "DiscordBot (https://github.io/shuppet/p6-api-discord, 0.0.1)",
Accept => 'application/json, */*',
Connection => 'keep-alive',
]
)
but RESTy[$!rest-url];
}
#| A Supply of messages that are not handled by the protocol gubbins. When this is first
#| tapped, it begins listening on the WebSocket for messages, manages the protocol, and
#| so forth. Should there be a disconnect, a reconnect will be performed automatically.
method messages returns Supply {
supply {
note "Making initial connection";
connect();
sub connect() {
whenever $!websocket.connection-messages {
when API::Discord::WebSocket::Event::Disconnected {
note "Connection lost; establishing a new one";
connect();
}
when API::Discord::WebSocket::Event::Ready {
$!ready.keep unless $!ready;
proceed;
}
default {
emit .payload;
}
}
}
}
}
#| Gimme your REST client
method rest { $!rest }