-export([
           start_link/1,
-          get_connection/0,
-                 open_channel/0
+          open_channel/0, % TODO: get rid of open_channel as an external call
+          send_message/2
         ]).
 
 -export([
           init/1,
-          handle_call/3
+          handle_call/3,
+          handle_cast/2
         ]).
 
 -define(RESTART, timer:seconds(30)).
     Connection = get_connection(),
     amqp_connection:open_channel(Connection).
 
+send_message(#'basic.publish'{} = Headers, Content) ->
+    gen_server:cast(?MODULE, {send_message, Headers, Content}).
+
 % Callbacks
 init({RatelimitTableId}) ->
     rate_limit:wait_and_reset(RatelimitTableId, amqp_connection, ?RESTART),
 handle_call(get_connection, _From, Connection) ->
     {reply, Connection, Connection}.
 
+handle_cast({send_message, Headers, Content}, Connection) ->
+    % Currently only support basic.publish requests.
+    #'basic.publish'{} = Headers,
+
+    {ok, Channel} = amqp_connection:open_channel(Connection),
+    amqp_channel:call(Channel, Headers, Content),
+    amqp_channel:close(Channel),
+    {noreply, Connection}.
+
 start_link_connection() ->
     Username = get_config(username, "guest"),
     Password = get_config(password, "guest"),
 
     BinKey = list_to_binary(RoutingKey),
     BinReplyKey = list_to_binary(ReplyTo),
     BinBody = list_to_binary(Body),
-    {ok, Channel} = amqp_bot_connection:open_channel(),
-    amqp_channel:call(Channel, #'basic.publish'{ routing_key = BinKey,
-                                                 exchange = ?EXCHANGE },
-                               #amqp_msg{ payload = BinBody,
-                                          props = #'P_basic' {
-                                              reply_to = BinReplyKey
-                                          }
-                                        }),
-    amqp_channel:close(Channel).
+    Headers = #'basic.publish'{ routing_key = BinKey,
+                                exchange = ?EXCHANGE },
+    Content = #amqp_msg{ payload = BinBody,
+                         props = #'P_basic' {
+                              reply_to = BinReplyKey
+                         }
+                       },
+    amqp_bot_connection:send_message(Headers, Content).
 
 %% @doc Encode an IRC-domain string as an AMQP-compatible routing key -- that
 %% is, in the set [A-Za-z0-9}.  We encode them as follows: