0

I'm trying to authenticate via the SOAP API. I ported my code form a python script that worked perfectly. When I try to implement in JS (Google App Script specifically), I get an "Unknown Server Error".

Here is my code:

function sfLogin(username, password){

  var url = "https://test.salesforce.com/services/Soap/u/30.0";
  var request = '<?xml version="1.0" encoding="utf-8" ?>'+
                    '<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"'+
                        'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'+
                        'xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">'+
                      '<env:Body>'+
                        '<n1:login xmlns:n1="urn:partner.soap.sforce.com">'+
                          '<n1:username>'+username+'</n1:username>'+
                          '<n1:password>'+password+'</n1:password>'+
                        '</n1:login>'+
                      '</env:Body>'+
                    '</env:Envelope>';

  var headers = {
    "Content-Type": "text/xml; charset=UTF-8", 
    "SOAPAction": "login"
  }

  var options = {
    'method': 'post',
    'headers': headers,
    'payload': request,
    'muteHttpExceptions': true
  }
  try{
    var res = UrlFetchApp.fetch(url, options).getContentText();
  }
  catch(e){
    Logger.log(e);
  }   
}

Here is the error:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
 xmlns:sf="urn:fault.partner.soap.sforce.com" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <soapenv:Fault>
            <faultcode>UNKNOWN_EXCEPTION</faultcode>    
            <faultstring>UNKNOWN_EXCEPTION: Element type &quot;env:Envelope&quot; must be followed by either attribute specifications, &quot;&gt;&quot; or &quot;/&gt;&quot;.
             </faultstring>
             <detail>
                <sf:UnexpectedErrorFault xsi:type="sf:UnexpectedErrorFault">
                    <sf:exceptionCode>UNKNOWN_EXCEPTION</sf:exceptionCode>
                    <sf:exceptionMessage>Element type &quot;env:Envelope&quot; must be followed by either attribute specifications, &quot;&gt;&quot; or &quot;/&gt;&quot;.
                    </sf:exceptionMessage>
                </sf:UnexpectedErrorFault>
             </detail>
          </soapenv:Fault>
      </soapenv:Body>
</soapenv:Envelope>

This is my POST Option:

{
  headers={
    SOAPAction=login, 
    Content-Type=text/xml; charset=UTF-8
  }, 
  method=post, 
  payload=<?xml version="1.0" encoding="utf-8" ?>
          <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> 
              <env:Body>
                 <n1:login xmlns:n1="urn:partner.soap.sforce.com">
                <n1:username>MYUSERNAME</n1:username>
                <n1:password>MYPWORD</n1:password>
                </n1:login>
              </env:Body>
          </env:Envelope>, 
  muteHttpExceptions=true
}

I've retyped each letter of that request at least 10 times. It works perfectly in my python script, just not here...

Thank you

EDIT** I checked to see the outgoing request. Below is the payload being sent out:

payload: <?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Body>
    <n1:login xmlns:n1="urn:partner.soap.sforce.com">
      <n1:username>USERNAME</n1:username>
      <n1:password>PASSWORD</n1:password>
    </n1:login>
  </env:Body>
</env:Envelope>

I believe this looks fine.

Here are the headers:

{
  SOAPAction=login, 
  X-Forwarded-For=71.183.26.223, 
  Content-Type=text/xml; charset=UTF-8
}

URL is:

"https://test.salesforce.com/services/Soap/u/30.0";

Are there any obvious errors here that I'm missing?

EDIT2**: This just got a bit more strange. I figured that the ' or '/>'). I tried putting the whole element on a single line:

<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">

This still gave the unknown error. But if I put a space between the xmlns and the preceding section, like so:

...XMLSchema" xmlns:...

I then get another error telling me the request must be of type xml/text (which it is and is put in the headers):

<?xml version="1.0" encoding="UTF-8"?>

soapenv:Client content-type of the request should be text/xml

So maybe there is something to adding white space and new lines.. How should I be formatting this in JS?

  • 1
    Are there any logging tools you can use to see the actual outbound POST request? I'm wondering if the UrlFetchApp.fetch call is escaping the payload in some way? – Daniel Ballinger Jul 29 '15 at 1:54
  • That's a good call. I'll check – ZAR Jul 29 '15 at 2:14
  • 1
    Another thought would be adding some white space between Envelope namespaces. Maybe add some newline characters in there for good measure, like after the XML declaration. – Daniel Ballinger Jul 29 '15 at 2:22
  • I've checked the request and posted the results above. They look good to me. I've never had a whitespace issue before - as long as the brackets are in place, shouldn't whitespace/newlines not matter? – ZAR Jul 29 '15 at 13:44
  • Actually, with the new edit above, whitespace may be playing a role here? – ZAR Jul 29 '15 at 14:13
1

As per my earlier comments:

Make sure there is a whitespace between the namespaces on the Envelope element.

 <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="...

Also, try adding some newlines after certain parts of the SOAP message, especially after the XML Declaration.

0

The issue was with both whitespaces AND with the google app script URLFetchApp.

The spaces were needed in the XML, so that instead of the envelope looking like:

It had the spaces:

Furthermore, although I put "text/xml" in the headers that were included in the request, google apps script automatically added contentType = application/x-www-form-urlencoded

You have to change the default options in the outgoing request rather than just adding content-type to the headers.

@DanielBallinger, both your suspicions turned out to be correct! Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.