vsTerminus / Mojo-Discord

Perl Modules that implement parts of the Discord API. Intended for Text Chat Bots.
MIT License
33 stars 10 forks source link

Feature: Blocking version of send_message #15

Closed vsTerminus closed 4 years ago

vsTerminus commented 4 years ago

Reported by @incognico - Need a way to guarantee delivery order of messages. Blocking version solves it. Also worth looking at promise chaining as a possible non-blocking solution to the problem.

incognico commented 4 years ago
diff --git a/lib/Mojo/Discord.pm b/lib/Mojo/Discord.pm
index 71e6ebf..e79185e 100644
--- a/lib/Mojo/Discord.pm
+++ b/lib/Mojo/Discord.pm
@@ -198,6 +198,14 @@ sub send_message
     $self->rest->send_message($channel, $message, $callback);
 }

+# Only supports string (simple messages).
+sub send_message_content_blocking
+{
+    my ($self, $channel, $message, $callback) = @_;
+
+    $self->rest->send_message_content_blocking($channel, $message, $callback);
+}
+
 sub edit_message
 {
     my ($self, $channel, $msgid, $message, $callback) = @_;
diff --git a/lib/Mojo/Discord/REST.pm b/lib/Mojo/Discord/REST.pm
index 909f21b..b22aff4 100644
--- a/lib/Mojo/Discord/REST.pm
+++ b/lib/Mojo/Discord/REST.pm
@@ -170,6 +170,31 @@ sub send_message
     }
 }

+sub send_message_content_blocking
+{
+    my ($self, $dest, $content, $callback) = @_; 
+
+    my $json = {
+        'content' => $content
+    };
+
+    my $route = "POST /channels/$dest";
+    if ( my $delay = $self->_rate_limited($route))
+    {
+        $self->log->warn('[REST.pm] [send_message_content_blocking] Route is rate limited. Trying again in ' . $delay . ' seconds');
+        Mojo::IOLoop->timer($delay => sub { $self->send_message_content_blocking($dest, $content, $callback) });
+    }
+    else
+    {
+        my $post_url = $self->base_url . "/channels/$dest/messages";
+        my $tx = $self->ua->post($post_url => {Accept => '*/*'} => json => $json);
+
+        $self->_set_route_rate_limits($route, $tx->res->headers);
+
+        $callback->($tx->res->json) if defined $callback;
+    }
+}
+
 sub edit_message
 {
     my ($self, $dest, $msgid, $param, $callback) = @_;
vsTerminus commented 4 years ago

I've merged this for now. I'd like to at some point revisit this problem so that I can guarantee delivery order using non-blocking calls so it doesn't break multitasking.