Search code examples
jsonrestparsinggroovyx-www-form-urlencoded

Groovy - parse/ convert x-www-form-urlencoded to something like JSON


this is my second try to explain a bit more precisely what I'm looking for ;-)

I set a webhook in Mailchimp that fires every time a new subscriber of an audience appears. Mailchimp sends a HTTP POST request to a Jira Sriptrunner REST endpoint.

The content type of this request is application/x-www-form-urlencoded.

Within the Jira endpoint I would like to read the request data. How can I do that?

The payload (raw body) I receive looks like this:

type=unsubscribe&fired_at=2020-05-26+07%3A04%3A42&data%5Baction%5D=unsub&data%5Breason%5D=manual&data%5Bid%5D=34f28a4516&data%5Bemail%5D=examlple%40bla.com&data%5Bemail_type%5D=html&data%5Bip_opt%5D=xx.xxx.xxx.198&data%5Bweb_id%5D=118321378&data%5Bmerges%5D%5BEMAIL%5D=example%40bla.com&data%5Bmerges%5D%5BFNAME%5D=Horst&data%5Bmerges%5D%5BLNAME%5D=Schlemmer&data%5Bmerges%5D%5BCOMPANY%5D=First&data%5Bmerges%5D%5BADDRESS%5D%5Baddr1%5D=XXX

Now I would like to parse the data of the raw body into a JSON or something similiar.

The result might look like this:

{
 "web_id": 123,
 "email": "example@bla.com",
 "company": "First",
 ...
 }

Meanwhile I searched around a little and found something like the node.js "querystring" module. It would be great if there is something similiar within Groovy or any other way to parse the data of application/x-www-form-urlencoded to json format.

Best regards and thanks in advance

Bernhard


Solution

  • def body = "type=unsubscribe&fired_at=2020-05-26+07%3A04%3A42&data%5Baction%5D=unsub&data%5Breason%5D=manual&data%5Bid%5D=34f28a4516&data%5Bemail%5D=examlple%40bla.com&data%5Bemail_type%5D=html&data%5Bip_opt%5D=xx.xxx.xxx.198&data%5Bweb_id%5D=118321378&data%5Bmerges%5D%5BEMAIL%5D=example%40bla.com&data%5Bmerges%5D%5BFNAME%5D=Horst&data%5Bmerges%5D%5BLNAME%5D=Schlemmer&data%5Bmerges%5D%5BCOMPANY%5D=First&data%5Bmerges%5D%5BADDRESS%5D%5Baddr1%5D=XXX"
    
    def map = body.split('&').collectEntries{e->
        e.split('=').collect{ URLDecoder.decode(it, "UTF-8") }
    }
    
    assert map.'data[merges][EMAIL]'=='example@bla.com'
    map.each{println it}
    

    prints:

    type=unsubscribe
    fired_at=2020-05-26 07:04:42
    data[action]=unsub
    data[reason]=manual
    data[id]=34f28a4516
    data[email]=examlple@bla.com
    data[email_type]=html
    data[ip_opt]=xx.xxx.xxx.198
    data[web_id]=118321378
    data[merges][EMAIL]=example@bla.com
    data[merges][FNAME]=Horst
    data[merges][LNAME]=Schlemmer
    data[merges][COMPANY]=First
    data[merges][ADDRESS][addr1]=XXX