0

Here I have a payload coming to my controller action endpoint:

%{      
  "mandrill_events" => "[{\"event\":\"send\",\"msg\":{\"ts\":1365109999,\"subject\":\"This an example webhook message\",\"email\":\"[email protected]\",\"sender\":\"[email protected]\",\"tags\":[\"webhook-example\"],\"opens\":[],\"clicks\":[],\"state\":\"sent\",\"metadata\":{\"user_id\":111},\"_id\":\"exampleaaaaaaaaaaaaaaaaaaaaaaaaa\",\"_version\":\"exampleaaaaaaaaaaaaaaa\"},\"_id\":\"exampleaaaaaaaaaaaaaaaaaaaaaaaaa\",\"ts\":1518203456},{\"event\":\"send\",\"msg\":{\"ts\":1365109999,\"subject\":\"This an example webhook message\",\"email\":\"[email protected]\",\"sender\":\"[email protected]\",\"tags\":[\"webhook-example\"],\"opens\":[],\"clicks\":[],\"state\":\"sent\",\"metadata\":{\"user_id\":111},\"_id\":\"exampleaaaaaaaaaaaaaaaaaaaaaaaaa1\",\"_version\":\"exampleaaaaaaaaaaaaaaa\"},\"_id\":\"exampleaaaaaaaaaaaaaaaaaaaaaaaaa1\",\"ts\":1518203456}]"
}

I am trying to decode the content of mandrill_events, so that I can then access some values, but I think the bracket is throwing it off.

get_in(payload, ["mandrill_events"]) |> Base.url_decode64 |> Poison.decode!

But that didn't work either.

** (ArgumentError) argument error
    :erlang.iolist_to_binary(:error)
    (poison) lib/poison/parser.ex:35: Poison.Parser.parse/2
    (poison) lib/poison/parser.ex:51: Poison.Parser.parse!/2
    (poison) lib/poison.ex:83: Poison.decode!/2
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (iex) lib/iex/evaluator.ex:250: IEx.Evaluator.handle_eval/5
    (iex) lib/iex/evaluator.ex:230: IEx.Evaluator.do_eval/3
    (iex) lib/iex/evaluator.ex:208: IEx.Evaluator.eval/3
    (iex) lib/iex/evaluator.ex:94: IEx.Evaluator.loop/1
    (iex) lib/iex/evaluator.ex:24: IEx.Evaluator.init/4
3
  • Why do you need to do: Base.url_decode64 ? get_in(a, ["mandrill_events"]) |> Poison.decode! should be sufficient. When you do |> Base.url_decode64 it throws an error Commented Feb 9, 2018 at 19:49
  • found about it on this answer: stackoverflow.com/a/34675180/3307520 Commented Feb 9, 2018 at 19:51
  • In your case, you already have your JSON string. Look at this: get_in(a, ["mandrill_events"]) |> Base.url_encode64 That will generate a base64 encoded version of the json payload so it can be transmitted safely, without it getting altered. In such a case, it needs to be decoded first so you have your JSON string, then you can |> Poison.decode! to convert to elixir term Commented Feb 9, 2018 at 19:54

1 Answer 1

1

Short answer: get_in(a, ["mandrill_events"]) |> Poison.decode! should give you what you want.

The reason as to why the answer provided here includes the operation |> Base.url_decode64 is because that question was dealing with base64 encoded payloads. Base64 encoding is simply a way of mapping a payload to a subset of the ASCII characters that are guaranteed to be recognized by every router, so that the payload value does not get corrupted when in transit.

For example, you could do:

get_in(a, ["mandrill_events"]) |> Base.url_encode64

which will render something like this:

"W3siZXZlbnQiOiJzZW5kIiwibXNnIjp7InRzIjoxMzY1MTA5OTk5LCJzdWJqZWN0IjoiVGhpcyBhbiBleGFtcGxlIHdlYmhvb2sgbWVzc2FnZSIsImVtYWlsIjoiZXhhbXBsZS53ZWJob29rQG1hbmRyaWxsYXBwLmNvbSIsInNlbmRlciI6ImV4YW1wbGUuc2VuZGVyQG1hbmRyaWxsYXBwLmNvbSIsInRhZ3MiOlsid2ViaG9vay1leGFtcGxlIl0sIm9wZW5zIjpbXSwiY2xpY2tzIjpbXSwic3RhdGUiOiJzZW50IiwibWV0YWRhdGEiOnsidXNlcl9pZCI6MTExfSwiX2lkIjoiZXhhbXBsZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJfdmVyc2lvbiI6ImV4YW1wbGVhYWFhYWFhYWFhYWFhYWEifSwiX2lkIjoiZXhhbXBsZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ0cyI6MTUxODIwMzQ1Nn0seyJldmVudCI6InNlbmQiLCJtc2ciOnsidHMiOjEzNjUxMDk5OTksInN1YmplY3QiOiJUaGlzIGFuIGV4YW1wbGUgd2ViaG9vayBtZXNzYWdlIiwiZW1haWwiOiJleGFtcGxlLndlYmhvb2tAbWFuZHJpbGxhcHAuY29tIiwic2VuZGVyIjoiZXhhbXBsZS5zZW5kZXJAbWFuZHJpbGxhcHAuY29tIiwidGFncyI6WyJ3ZWJob29rLWV4YW1wbGUiXSwib3BlbnMiOltdLCJjbGlja3MiOltdLCJzdGF0ZSI6InNlbnQiLCJtZXRhZGF0YSI6eyJ1c2VyX2lkIjoxMTF9LCJfaWQiOiJleGFtcGxlYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYTEiLCJfdmVyc2lvbiI6ImV4YW1wbGVhYWFhYWFhYWFhYWFhYWEifSwiX2lkIjoiZXhhbXBsZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWExIiwidHMiOjE1MTgyMDM0NTZ9XQ=="

When you are dealing with base64 encoded payload, you will need to first decode it so you get a JSON string which in turn you can deserialize using Poison.

As a full sanity test, the following would work as well:

get_in(a, ["mandrill_events"]) |> Base.url_encode64 |> Base.url_decode64 |> Poison.decode!

Of course, if the string is not base64 encoded, and you try to base64 decode it accordingly as you currently are doing, then it will throw an :error which Poison does not know how to convert to an elixir term as its input is to be a JSON string, not an atom

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.