3

I am trying to invoke mailgun send message api. The following code works if I pass the params along with url -

String targetUrl = "https://api.mailgun.net/v2/my_domain_name/messages?from=fromAddress&to=toAddress&subject=sub&text=random+message" 

But when I try to add these params in the body then it does not work. I keep getting bad request from mailgun. -

String targetUrl = "https://api.mailgun.net/v2/my_domain_name/messages
body = [from:"fromAddress", to:"toAddress", subject:"sub", text:"random message"]

Here is the full code -

def sendEmail(String mailBody, String sub, String toIds) {
    String targetUrl = "https://api.mailgun.net/v2/my_domain_name/messages"
    def http = new HTTPBuilder(targetUrl)

    http.request( groovyx.net.http.Method.POST, groovyx.net.http.ContentType.JSON) {

        body = [from:"fromAddress", to:"toAddress", subject:"sub", text:"random message"]

        headers = ['Authorization':"Basic " + "api:my_api_key".bytes.encodeBase64().toString()]

        response.success = { resp, reader ->
            println "valid response: " + reader
        }
    }
}

Thanks!

saurabh
  • 2,389
  • 3
  • 22
  • 37
  • Can't find docs but you're sending query params as body, that's not correct - use query params. As far as I remember it should be sent as `params` map, just change `body` to `params`. – Opal Mar 28 '15 at 09:22
  • @Opal Thats what I also thought at first. I tried params in place of body. But it seems httpbuilder does not have any property named params. – saurabh Mar 28 '15 at 10:18
  • Try `uri.query = `. – Opal Mar 28 '15 at 10:47

1 Answers1

4

Your code is not working because you are telling HTTPBuilder that the request's parameters are encoded in JSON

http.request(Method.POST, ContentType.JSON)

so that you are encoding your parameters in request body in JSON, while mailgun API expects them with Content-Type: application/x-www-form-urlencoded.

curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v2/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <mailgun@YOUR_DOMAIN_NAME>' \
    -F to=YOU@YOUR_DOMAIN_NAME \
    -F to=bar@example.com \
    -F subject='Hello' \
    -F text='Testing some Mailgun awesomness!'

You can see it using as targetURL http://echo.httpkit.com, that returns the HTTP request in JSON format.

Doing that, it yields:

{
    "body": "\"from\":\"fromAddress\",\"to\":\"toAddress\",\"subject\":\"sub\",\"text\":\"random message\"}",
"docs": "http://httpkit.com/echo",
[...]

So you have to use ContentType.URLENC instead of ContentType.JSON (and optionally use Accept header for application/json type):

import groovy.json.*

import groovyx.net.*
import groovyx.net.http.*

import static groovy.json.JsonOutput.*

import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*

String targetUrl = 'http://echo.httpkit.com'
def http = new HTTPBuilder(targetUrl)

http.request(POST) {
    uri.path = '/'
    requestContentType = URLENC

    body = [from: 'fromAddress', to: 'toAddress', subject: 'sub', text: 'random message']

    headers.'Authorization' = "Basic " + "api:my_api_key".bytes.encodeBase64().toString()
    headers.'Accept' = 'application/json'

    response.success = { resp, json ->
        println prettyPrint(toJson(json))
    }
}

That yields this "echo" response (i.e., sent a POST request with urlencoded parameters):

{
    "body": "from=fromAddress&to=toAddress&subject=sub&text=random+message",
    "docs": "http://httpkit.com/echo",
    "headers": {
        "accept": "application/json",
        "authorization": "Basic YXBpOm15X2FwaV9rZXk=",
        "content-length": "61",
        "content-type": "application/x-www-form-urlencoded",
        "host": "echo.httpkit.com",
        "x-forwarded-for": "195.235.15.200"
    },
    "ip": "127.0.0.1",
    "method": "POST",
    "path": {
        "name": "/",
        "params": {

        },
        "query": ""
    },
    "powered-by": "http://httpkit.com",
    "uri": "/"
}
jalopaba
  • 8,039
  • 2
  • 44
  • 57