Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Actions are not being saved to the route #211

Open
isaacmast opened this issue Dec 19, 2020 · 1 comment
Open

Actions are not being saved to the route #211

isaacmast opened this issue Dec 19, 2020 · 1 comment

Comments

@isaacmast
Copy link

BUG OVERVIEW

I'm experiencing a bug that's preventing my Routes in Mailgun from being created with multiple actions. I'm following the examples straight out of the docs (both the API Reference and the User Manual), but to no avail. When I send the POST request to create the route in Mailgun using the gem's post method, I get a 200 response from Mailgun saying that the route has been created, but the actions that I've specified in the request params aren't showing up in the response's route object. I checked the route in Mailgun's web UI and, sure enough, the actions that I specified in the request weren't saved to the route.

According to the examples in the docs, the action param can be set to an array of actions if you want to configure the route to have multiple actions. I was doing just this, but wasn't having any success. As an example of what I was doing, I was setting the action param to ["forward('[email protected]')", "stop()"]. After having tried various other strategies like including just a single action in the array and using escaped double quotes in the forward() action expression, I decided to dig into the gem's code to get a better idea of what might be going on. After poking around for a bit, I came to the conclusion that it has to do with how rest-client URL encodes array parameters. rest-client URL encodes array parameters using "bracket notation", which is specific to rack/rails applications, but it seems that Mailgun's endpoint expects array params to be flattened.

For example, if the action param is set to ["forward('[email protected]')", "stop()"]:

**[BAD]** `rest-client` URL encodes the array like this using bracket notation: 

    `action[]=forward%28%27foo%40example.com%27%29&action[]=stop%28%29`

**[GOOD]** but Mailgun's endpoint seemingly expects it to be encoded like this:

    `action=forward%28%27foo%40example.com%27%29&action=stop%28%29`

When the action param is encoded like the [GOOD] example, the actions are successfully persisted to the route when the route gets created.

STEPS TO REPRODUCE

def create_route
  data = {}
  data[:priority] = 0
  data[:description] = "Sample route"
  data[:expression] = "match_recipient('.*@YOUR_DOMAIN_NAME')"
  data[:action] = []
  data[:action] << "forward('http://myhost.com/messages/')"
  data[:action] << "stop()"
  mg_client = Mailgun::Client.new("YOUR_API_KEY")
  mg_client.post "routes", data
end

Actual response, but with fake id (note the "actions" array is totally empty):

#<Mailgun::Response:0x000055a167b417d0
 @body=
  "{\n  \"message\": \"Route has been created\",\n  \"route\": {\n    \"actions\": [],\n    \"created_at\": \"Fri, 18 Dec 2020 22:47:13 GMT\",\n    \"description\": \"Sample route\",\n    \"expression\": \"match_recipient('.*@YOUR_DOMAIN_NAME')\",\n    \"id\": \"sample_id\",\n    \"priority\": 0\n  }\n}",
 @code=200>

SOLUTION

As a workaround, I've been leveraging the ability of ruby hashes to have both symbol and string keys that have the same name. For example:

data = {
    ...
    :action => "forward('[email protected]')",
    "action" => "stop()"
}

This tricks the rest-client into treating the :action and "action" params as separate params and URL encodes them without the bracket notation, which seems to work with Mailgun's endpoint.

I checked the rest-client gem and it looks like there's a solution for this issue through the use of their custom ParamsArray class. In version 2.1.0 of the rest-client gem, you can pass in a ParamsArray object as the request payload and it removes the bracket notation during the URL encoding process for array params. For example:

data = RestClient::ParamsArray.new([[:priority, 0], [:description, "Forward emails"], [:expression, "match_recipient('[email protected]')"], [:action, "forward('bar@somewhere_else.com')"], [:action, "stop()"]])
rest_client["routes"].post data, headers

encodes the params like so in the request:

"priority=0&description=Forward+emails&expression=match_recipient%28%27foo%40example.com%27%29&action=forward%28%27bar%40somewhere_else.com%27%29&action=stop%28%29"

It looks like rest-client is pegged at 2.0.2. Updating to 2.1.0 and refactoring the the mailgun-ruby gem's methods to make use of the ParamsArray class would solve this issue.

@BrendaEgeland
Copy link

three years later ... same issue :-/ . No response from MailGun on my support requests. Thank you so much for posting your solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants