Creating a draft campaign returns 400:Bad Request

Hello,

We'd been using campaign monitor API for quite some time before we stopped a year ago. Now we are trying to use it again. However, we are facing problems with create draft campaign request.

In details, we are using the following PL/SQL wrapper to create draft campaign:

PROCEDURE Http_post2 (p_url_in              IN VARCHAR2, 
                      p_data_in             IN CLOB, 
                      p_data_type           IN VARCHAR2 DEFAULT 'text/xml', 
                      p_proxy_in            IN VARCHAR2 DEFAULT NULL, 
                      p_no_proxy_domains_in IN VARCHAR2 DEFAULT NULL, 
                      p_username_in         IN VARCHAR2 DEFAULT NULL, 
                      p_password_in         IN VARCHAR2 DEFAULT NULL, 
                      p_request_type        IN VARCHAR2, 
                      p_resp_text_out       OUT VARCHAR2, 
                      p_status_text_out     OUT VARCHAR2) 
IS 
  l_http_req  utl_http.req; 
  l_http_resp utl_http.resp; 
  l_my_scheme VARCHAR2(256); 
  l_my_realm  VARCHAR2(256); 
  l_my_proxy  BOOLEAN; 
  --value      VARCHAR2(1024); 
  value       VARCHAR2(32000); 
  name        VARCHAR2(256); 
  loc         VARCHAR2(10); 
  v_error     CLOB; 
BEGIN 
    loc := 10; 

    -- When going through a firewall, pass requests through this host. 
    -- Specify sites inside the firewall that don't need the proxy host. 
    IF ( p_proxy_in IS NOT NULL ) 
       AND ( p_no_proxy_domains_in IS NOT NULL ) THEN 
      utl_http.Set_proxy(p_proxy_in, p_no_proxy_domains_in); 
    END IF; 

    loc := 20; 

    -- Ask UTL_HTTP not to raise an exception for 4xx and 5xx status codes, 
    -- rather than just returning the text of the error page. 
    utl_http.Set_response_error_check(FALSE); 

    loc := 30; 

    -- Begin the post request 
    l_http_req := utl_http.Begin_request (p_url_in, p_request_type, 'HTTP/1.1'); 

    loc := 40; 

    -- Set the HTTP request headers 
    utl_http.Set_header(l_http_req, 'User-Agent', 'Mozilla/4.0'); 

    utl_http.Set_header(l_http_req, 'content-type', p_data_type); 

    utl_http.Set_header(l_http_req, 'content-length', Length(p_data_in)); 

    loc := 50; 

    -- Specify a user ID and password for pages that require them. 
    IF p_username_in IS NOT NULL THEN 
      utl_http.Set_authentication(l_http_req, p_username_in, p_password_in); 
    END IF; 

    loc := 60; 

    -- Write the data to the body of the HTTP request 
    utl_http.Write_text(l_http_req, p_data_in); 

    loc := 70; 

    -- Process the request and get the response. 
    l_http_resp := utl_http.Get_response (l_http_req); 

    loc := 80; 

    p_status_text_out := l_http_resp.status_code 
                         ||':' 
                         ||l_http_resp.reason_phrase; 

    --dbms_output.put_line ('status code: ' || l_http_resp.status_code); 
    --dbms_output.put_line ('reason phrase: ' || l_http_resp.reason_phrase); 
    loc := 90; 

    -- Look for client-side error and report it. 
    IF ( l_http_resp.status_code >= 400 ) 
       AND ( l_http_resp.status_code <= 499 ) THEN 
      -- Detect whether the page is password protected, 
      -- and we didn't supply the right authorization. 
      -- Note the use of utl_http.HTTP_UNAUTHORIZED, a predefined 
      -- utl_http package global variable 
      IF ( l_http_resp.status_code = utl_http.http_unauthorized ) THEN 
        utl_http.Get_authentication(l_http_resp, l_my_scheme, l_my_realm, 
        l_my_proxy 
        ); 

        IF ( l_my_proxy ) THEN 
          dbms_output.Put_line('Web proxy server is protected.'); 

          dbms_output.Put('Please supply the required ' 
                          || l_my_scheme 
                          || ' authentication username/password for realm ' 
                          || l_my_realm 
                          || ' for the proxy server.'); 
        ELSE 
          dbms_output.Put_line('Web page ' 
                               || p_url_in 
                               || ' is protected.'); 

          dbms_output.Put('Please supplied the required ' 
                          || l_my_scheme 
                          || ' authentication username/password for realm ' 
                          || l_my_realm 
                          || ' for the Web page.'); 
        END IF; 
      ELSE 
        dbms_output.Put_line('Check the URL.'); 
      END IF; 
    --utl_http.end_response(l_http_resp); 
    --return; 
    -- Look for server-side error and report it. 
    ELSIF ( l_http_resp.status_code >= 500 ) 
          AND ( l_http_resp.status_code <= 599 ) THEN 
      dbms_output.Put_line('Check if the Web site is up.'); 

      utl_http.End_response(l_http_resp); 

      RETURN; 
    END IF; 

    loc := 100; 

    FOR i IN 1..utl_http.Get_header_count(l_http_resp) LOOP 
        utl_http.Get_header(l_http_resp, i, name, value); 

        dbms_output.Put_line(name 
                             || ': ' 
                             || value); 
    END LOOP; 

    loc := 110; 

    -- Read lines until none are left and an exception is raised. 
    BEGIN 
        LOOP 
            loc := 120; 

            utl_http.Read_line(l_http_resp, value); 

            loc := 130; 

            p_resp_text_out := p_resp_text_out 
                               ||value; 
        --DBMS_OUTPUT.PUT_LINE(value); 
        END LOOP; 
    EXCEPTION 
        WHEN utl_http.end_of_body THEN 
          utl_http.End_response(l_http_resp); 
    END; 

    loc := 140; 
--utl_http.end_response (l_http_resp); 
EXCEPTION 
  WHEN OTHERS THEN 
             v_error := SQLERRM 
                        ||':' 
                        ||p_resp_text_out 
                        ||':' 
                        ||value; 

             driver_debug.P_debug('Error loc=' 
                                  ||loc, 'http_post2', v_error); 

             RAISE; 
END http_post2; 

The parameters passed to this procedure are respectively as follows:

'http://api.createsend.com/api/v3/campaigns/8eb8f49e3bb979fc32feab5133c5d812.xml',  'test', 
'text/xml', 
null, 
null, 
'OBFUSCATED',  //api key
'POST', 
NULL,
p_resp_text_out, 
p_status_text_out

The returned values are:

p_resp_text_out   => <?xml version="1.0" encoding="utf-8"?><Result><Code>310</Code><Message>HTML Content URL Required</Message></Result>
p_status_text_out  => 400:Bad Request

What HTML content URL required here? All URL provided in the request as explained below

The request sent, is as follows:

http://api.createsend.com/api/v3/campaigns/8eb8f49e3bb979fc32feab5133c5d812.xml
<?xml version="1.0" encoding="utf-8"?>
    <Campaign>
    <Name>DEMO_E_21519</Name>
    <Subject>Free Coverage to Your Loved One</Subject>
    <FromName>Promotions</FromName>
    <FromEmail>promotions@starsolutions.com.my</FromEmail>
    <ReplyTo>sales@starsolutions.com.my</ReplyTo>
    <HtmlUrl>http://192.168.1.33/maxis_edm.htm</HtmlUrl>
    <TextUrl>http://demo.stardriver.com.my/demo/STARDRIVER_DEMO.driver_library.get_plain_text?id=21519</TextUrl>
    <ListIDs>
        <ListID>bc3998d5999aaa412e1362b646f04d0e</ListID>
    </ListIDs>
    <SegmentIDs></SegmentIDs>        
</Campaign>

I tried to change HtmlUrl to different servers, and I got the same response.

The output produced by for loop in the procedure above, is as follows:

Check the URL.
Server: csw
Cache-Control: private, s-maxage=0
Content-Type: application/xml; charset=utf-8
Date: Wed, 29 Apr 2015 09:44:49 GMT
Connection: close
Content-Length: 187
<?xml version="1.0" encoding="utf-8"?><Result><Code>404</Code><Message>We couldn't find the resource you're looking for. Please check the documentation and try again</Message></Result>
404:Not Found

Again, what resource that cannot be found? I'm trying to create a draft and provided all working URL's.

This is used to work previously, but not any more.

Your support is deeply appreciated.
Regards,

Greg Strutton Greg Strutton, 1 year ago

Hey,

Thanks for getting in touch. I've just attempted to access the URL: http://192.168.1.33/maxis_edm.htm and this doesn't seem to be pubclically available. To be able to import the campaign via the API, the URL that you host the campaign needs to be public.

Could you try either changing the permissions for that specific URL, or host the campaign on a public server somewhere? That will solve the problem you're experiencing here.

Hawk, 1 year ago

Hi Greg,

I’ve changed the resource directly to public one. I tried the following URLs instead:
1)    http://demo.stardriver.com.my/maxisedm/
2)    http://demo.stardriver.com.my/demo/STARDRIVER_DEMO.driver_library.download_file_upload?p_file=1596

They returned the same result.
This is the request:

http://api.createsend.com/api/v3/campaigns/8eb8f49e3bb979fc32feab5133c5d812.xml
<?xml version="1.0" encoding="utf-8"?>
    <Campaign>
    <Name>DEMO_E_22167</Name>
    <Subject>FREE Samsung Note4 Up For Grabs !!!</Subject>
    <FromName></FromName>
    <FromEmail></FromEmail>
    <ReplyTo></ReplyTo>
    <HtmlUrl>http://demo.stardriver.com.my/maxisedm/</HtmlUrl>
    <TextUrl>http://demo.stardriver.com.my/demo/STARDRIVER_DEMO.driver_library.get_plain_text?id=22167</TextUrl>
    <ListIDs>
        <ListID>629bae515a7952a09e3111793136a9a8</ListID>
    </ListIDs>
    <SegmentIDs></SegmentIDs>        
</Campaign>

And this is the response:

<?xml version="1.0" encoding="utf-8"?><Result><Code>305</Code><Message>From Name Required</Message></Result>

The status code was: 400:Bad Request

Your help is much appreciated.

Phil Phil, 1 year ago

Hi Hawk,

The error message there is indicative of the problem. "From Name" is a required parameter. You've got several blank properties in the payload there, and FromName:

    <FromName></FromName>
    <FromEmail></FromEmail>
    <ReplyTo></ReplyTo>

By the way, i've removed the ApiKey which was contained in your first post. From a security point of view, it's not a good idea to put information like that in a public forum!

Hawk, 1 year ago

Hi Phil,

Thank for the heads-up regarding the ApiKey.

I've tried again with values added to the properties you mentioned. Unfortunately, I've received the same result.

Here is the request

http://api.createsend.com/api/v3/campaigns/8eb8f49e3bb979fc32feab5133c5d812.xml
<?xml version="1.0" encoding="utf-8"?>
    <Campaign>
    <Name>DEMO_E_22167</Name>
    <Subject>FREE Samsung Note4 Up For Grabs !!!</Subject>
    <FromName>Kareem</FromName>
    <FromEmail>kareem@starsolutions.com.my</FromEmail>
    <ReplyTo>kareem@starsolutions.com.my</ReplyTo>
    <HtmlUrl>http://demo.stardriver.com.my/maxisedm/</HtmlUrl>
    <TextUrl>http://demo.stardriver.com.my/demo/STARDRIVER_DEMO.driver_library.get_plain_text?id=22167</TextUrl>
    <ListIDs>
        <ListID>629bae515a7952a09e3111793136a9a8</ListID>
    </ListIDs>
    <SegmentIDs></SegmentIDs>        
</Campaign>
Phil Phil, 1 year ago

Hi Hawk,

Thanks for getting back to me. I doubt it's the same result that you're getting, for two reasons:
1. You've added the missing parameters. You're not going to get a "From Name Required" error code if you've included a from name.
2. The HtmlUrl and TextUrl values are not publicly accessible URLs. Publicly accessible in this case means that someone external to your company network needs to be able to view these URLs in a browser:
http://demo.stardriver.com.my/maxisedm/
http://demo.stardriver.com.my/demo/STARDRIVER_DEMO.driver_library.get_plain_text?id=22167

For me, both of those lead to gateway timeouts. If you make those URLs public, it'll probably be fine.

Phil

Hawk, 1 year ago

Thank you Phil,

I have made the URLs public. My request is as follows now:

http://api.createsend.com/api/v3/campaigns/8eb8f49e3bb979fc32feab5133c5d812.xml
<?xml version="1.0" encoding="utf-8"?>
    <Campaign>
    <Name>DEMO_E_22167</Name>
    <Subject>FREE Samsung Note4 Up For Grabs !!!</Subject>
    <FromName>Kareem</FromName>
    <FromEmail>kareem@starsolutions.com.my</FromEmail>
    <ReplyTo>kareem@starsolutions.com.my</ReplyTo>
    <HtmlUrl>https://stardriver.com.my/maxisedm/</HtmlUrl>
    <TextUrl>http://demo.stardriver.com.my/demo/STARDRIVER_DEMO.driver_library.get_plain_text?id=21513</TextUrl>
    <ListIDs>
        <ListID>629bae515a7952a09e3111793136a9a8</ListID>
    </ListIDs>
    <SegmentIDs></SegmentIDs>        
</Campaign>

TextUrl should return "this is text test email" in the browser.

I'm now receiving this error message

<?xml version="1.0" encoding="utf-8"?><Result><Code>4202</Code><Message>Almost every popular email client and spam filter does not support JavaScript. Your campaign will either be filtered as spam, or will display a security warning to your recipients. We recommend removing all JavaScript code from your campaign and then re-import it.</Message></Result>

 

With error message : 400:Bad Request

I do not know what JavaScript is meant here. Is it from the page fetched by the HtmlUrl ?
If so, how can I fix this?

Many thanks for your help!

Join 200,000 companies around the world that use Campaign Monitor to run email marketing campaigns that deliver results for their business.

Get started for free
1-888-533-8098