title: Handling routing_key for topic routing
body: <p>I am a bit new to the Erlang Environment</p>
  
  <p>I am writing an email testing application that filters incoming email with a randomly generated routing_keys on a topic exchange to make emails entering my system</p>
  
  <p>Once they are delivered (and processed) on a queue, I want to label them again with the previously randomly routing_key to route them to another exchange to make them ready for the final consume.</p>
  
  <p>This 2nd producing step is causing me real troubles</p>
  
  <p>I am getting data back from a tcp socket (processed by a third-tier program: spamassassin) with handle_info pattern matching</p>
  
  <p>I rely on a gen_server to consume messages first through the regular amqp_client/include/amqp_client.hrl Library</p>
  
  <p>I use handle_info in my gen_server behaviour and then pattern match on the parameters.</p>
  
  <p>Detecting delivered AMQP message is done through function heads (records) in handle_info callback</p>
  
  <p>TCP socket is nice to talk with spamassassin, it returns me a 3-tuple with binary string data like that:</p>
  
  <p><code>{tcp,#Port&lt;0.55&gt;,&lt;&lt;"SPAMD/1.1 0 EX_OK\r\nContent-length: 564\r\nSpam: True ; 7.9 / 5.0\r\n\r\nReceived: from localhost by XXXX.ikexpress.com\n\twith SpamAssassin (version 3.4.2);\n\tThu, 15 Aug 2019 21:44:12 +0200\nX-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on\n\tXXXXX.ikexpress.com\nX-Spam-Flag: YES\nX-Spam-Level: *******\nX-Spam-Status: Yes, score=7.9 required=5.0 tests=EMPTY_MESSAGE,MISSING_DATE,\n\tMISSING_FROM,MISSING_HEADERS,MISSING_MID,MISSING_SUBJECT,\n\tNO_HEADERS_MESSAGE,NO_RECEIVED,NO_RELAYS autolearn=no\n\tautolearn_force=no version=3.4.2\nMIME-Version: 1.0\nContent-Type: multipart/mixed; boundary=\"----------=_5D55B60C.D2FC2670\"\n\n"&gt;&gt;}</code></p>
  
  <p>The loop in the second handle_info match OK the answer from the listening gen_tcp server, but I have to do the packaging to send it to a topic Exchange (topic_scored_email exchange) </p>
  
  <pre><code>***My gen_server****
  handle_info({#'basic.deliver'{routing_key=Key, consumer_tag=Tag}, Content}, State) -&gt;
      #amqp_msg{props = Properties, payload = Payload} = Content,
      #'P_basic'{message_id = MessageId, headers = Headers} = Properties,
      send_to_spamassassin:calcule_score(Payload),
      {noreply, State};
  handle_info(Msg, State) -&gt;
      case Msg of
          {_,_,Data} -&gt;
             scored_email:main(Data);
          {_,_} -&gt;
      end,
      {noreply, State}.
  
  ***send_to_spamassassin function ***
      calcule_score(Message) -&gt;
      case gen_tcp:connect("localhost", 783, [{mode, binary}]) of
          {ok, Sock} -&gt;
              …
              gen_tcp:send(Sock, Message2);
          {error,_} -&gt;
              io:fwrite("Connection error! Quitting...~n")
      end.
  
  ***scored_email***
  main(Argv) -&gt;
      {ok, Connection} = amqp_connection:start(#amqp_params_network{virtual_host = &lt;&lt;"/"&gt;&gt;}),
      {ok, Channel} = amqp_connection:open_channel(Connection),
      amqp_channel:call(Channel, #'exchange.declare'{exchange = &lt;&lt;"topic_scored_email"&gt;&gt;,type = &lt;&lt;"topic"&gt;&gt;}),
      {RoutingKey, Message} = case Argv of
                                  …
  %DOING PATTERN MATCHING THAT WORKS HERE
                                  …
                              end,
      amqp_channel:cast(Channel,#'basic.publish'{exchange = &lt;&lt;"topic_scored_email"&gt;&gt;,routing_key = RoutingKey},#amqp_msg{payload = Message})
  </code></pre>
  
  <p>The first issue is type of the data (binary string) but I guess it can be a workaround using BIF binary_to_tuple or stuff like that.</p>
  
  <p>What I struggle to understand is how I could pass the right RoutingKey, since Erlang is functional, there is no side effect or assignation.</p>
  
  <p>That change in format data (AMQP --> raw TCP --> then AMQP again) seems impossible (to me) to achieve with OTP abstraction</p>
  
  <p>However, I would like to reassemble every processed message with the right routing key matched 5 lines above.</p>
  
  <p>How could I modify my code, to do that? I come from imperative language and reach my limit here…</p>
  
  <p>Yours</p>