How to upload tailored audience list?

ton

#1

Edit: I just realized documentation mentions a whitelist. Is there any way to check if my app is whitelisted?


This is the request I tried (taken from here https://dev.twitter.com/rest/ton)

twurl -t -H ton.twitter.com /1.1/ton/bucket/ta_partner/ -X POST -A "Content-Type: text/plain" -A "Content-Length: 12" --data "aaa@test.com"

Response

opening connection to ton.twitter.com:443...
opened
starting SSL for ton.twitter.com:443...
SSL established
<- "POST /1.1/ton/bucket/ta_partner/ HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 14\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: OAuth gem v0.4.7\r\nAuthorization: OAuth oauth_consumer_key=\"***\", oauth_nonce=\"***\", oauth_signature=\"***\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1437406132\", oauth_token=\"***\", oauth_version=\"1.0\"\r\nConnection: close\r\nHost: ton.twitter.com\r\n\r\n"
<- "aaa%40test.com"
-> "HTTP/1.1 403 Forbidden\r\n"
-> "connection: close\r\n"
-> "content-length: 0\r\n"
-> "date: Mon, 20 Jul 2015 15:28:54 GMT\r\n"
-> "server: tsa_a\r\n"
-> "set-cookie: guest_id=v1%3A143740613433381487; Domain=.twitter.com; Path=/; Expires=Wed, 19-Jul-2017 15:28:54 UTC\r\n"
-> "strict-transport-security: max-age=631138519\r\n"
-> "x-connection-hash: 3a3d8a118a36d5e51a775e02e4b63d78\r\n"
-> "x-rate-limit-limit: 50\r\n"
-> "x-rate-limit-remaining: 49\r\n"
-> "x-rate-limit-reset: 1437407034\r\n"
-> "x-response-time: 9\r\n"
-> "x-tsa-request-body-time: 514\r\n"
-> "\r\n"
reading 0 bytes...
-> ""
read 0 bytes
Conn close

As you can see I received an HTTP 403 error.
Is there a whitelist to use TON API or am I missing something?


#2

@ulsoz you’re close but there are a few issues with the request.

  1. The ta_partner bucket requires that you set an X-TON-Expires header. You can read more about about that here.

From our TON API documentation:

Buckets

For Tailored Audiences, please use the bucket name ta_partner.

Note that the ta_partner bucket also requires the X-TON-Expires header to be set with an expiration date up to 7 days from the current date (see the ton-upload example script for more detail). For all other TON API buckets, this header is optional however it’s safe and a good practice to pass this header all the time and buckets that do not require it will simply ignore it.

  1. A Content-Type of application/x-www-form-urlencoded is never permitted in the TON API.

You’re setting the Content-Type correctly, but it looks like you’re using an older version of twurl where it was errantly forcing Content-Type to application/x-www-form-urlencoded on all requests. Ensure you’re running twurl v0.9.3 or higher so that you don’t run into this issue.

gem uninstall --force twurl && gem install twurl -v 0.9.3

Once you have those issues corrected, you should be able to do the following:

twurl -t -H ton.twitter.com /1.1/ton/bucket/ta_partner -X POST -A "Content-Type: text/plain" -A "X-TON-Expires: Sat, 05 Sep 2015 23:01:50 GMT" -A "Content-Length: 12" --data "aaa@test.com"

opening connection to ton.twitter.com:443...
opened
starting SSL for ton.twitter.com:443...
SSL established
<- "POST /1.1/ton/bucket/ta_partner HTTP/1.1\r\nContent-Type: text/plain\r\nX-Ton-Expires: Sat, 05 Sep 2015 23:01:50 GMT\r\nContent-Length: 12\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: OAuth gem v0.4.7\r\nAuthorization: OAuth oauth_body_hash=\"ZmqMusMfLNliIT45yUqjwqfwUQ0%3D\", oauth_consumer_key=\"OIDntXZULiYrCzSBq23BQ\", oauth_nonce=\"NdZHTLBog4yXkJ7NUDOMHvzSvXEsRCTgKOiPaNyxeIA\", oauth_signature=\"xNPQBV6Pv8JvoK8Wyj%2BnNfvdGLQ%3D\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1440631051\", oauth_token=\"15678855-Q9DtXWXni83LwkqPcUl3dBkhtr9VgHu02nLKueKMI\", oauth_version=\"1.0\"\r\nConnection: close\r\nHost: ton.twitter.com\r\n\r\n"
<- "aaa@test.com"
-> "HTTP/1.1 201 Created\r\n"
-> "connection: close\r\n"
-> "content-length: 0\r\n"
-> "content-type: text/plain\r\n"
-> "date: Wed, 26 Aug 2015 23:17:31 GMT\r\n"
-> "location: /1.1/ton/data/ta_partner/15678855/qpO2_-TSjGA8rXA.txt\r\n"
-> "server: tsa_a\r\n"
-> "set-cookie: guest_id=v1%3A144063105152928411; Domain=.twitter.com; Path=/; Expires=Fri, 25-Aug-2017 23:17:31 UTC\r\n"
-> "strict-transport-security: max-age=631138519\r\n"
-> "x-connection-hash: 68aef5ab65b6e2d72d3f9d020322c43e\r\n"
-> "x-rate-limit-limit: 90000\r\n"
-> "x-rate-limit-remaining: 89999\r\n"
-> "x-rate-limit-reset: 1440631951\r\n"
-> "x-response-time: 13\r\n"
-> "x-tsa-request-body-time: 47\r\n"
-> "\r\n"
reading 0 bytes...
-> ""
read 0 bytes
Conn close

#3

In Simple.txt, I put aaa@test.com

twurl -t -H ton.twitter.com /1.1/ton/bucket/ta_partner -X POST -A “Content-Type: text/plain” -A “X-TON-Expires: Sat, 26 Nov 2016 23:01:50 GMT” --file Simple.txt
opening connection to ton.twitter.com:443
opened
starting SSL for ton.twitter.com:443
SSL established
<- "POST /1.1/ton/bucket/ta_partner HTTP/1.1\r\nContent-Type: multipart/form-data, boundary=“00Twurl129918792308398455lruwT99”\r\nX-Ton-Expires: Sat, 26 Nov 2016 23:01:50 GMT\r\nAccept-Encoding: gzi
p;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: /\r\nUser-Agent: OAuth gem v0.5.1\r\n

\n–00Twurl129918792308398455lruwT99–\r\n"
-> “HTTP/1.1 400 Bad Request\r\n”
-> “cache-control: no-cache\r\n”
-> “connection: close\r\n”
-> “content-length: 0\r\n”
-> “date: Tue, 22 Nov 2016 07:10:15 GMT\r\n”
-> “server: tsa_b\r\n”

Can someone help to give the correct query?


#4

C:\Ruby23-x64\lib\ruby\gems\2.3.0\gems\twurl-0.9.3\lib\twurl\oauth_client.rb

I go to the file above, and comment out the multipart_body for ‘file’, and also the hard setting ‘request.content_type’, and run below command, seems like OK…

// oauth_client.rb file

def perform_request_from_options(options, &block)
request_class = METHODS.fetch(options.request_method.to_sym)
request = request_class.new(options.path, options.headers)

  if options.upload && options.upload['file'].count > 0
    boundary = "00Twurl" + rand(1000000000000000000).to_s + "lruwT99"
    multipart_body = []
    file_field = options.upload['filefield'] ? options.upload['filefield'] : 'media[]'
    options.data.each {|key, value|
      multipart_body << "--#{boundary}\r\n"
      multipart_body << "Content-Disposition: form-data; name=\"#{key}\"\r\n"
      multipart_body << "\r\n"
      multipart_body << value
      multipart_body << "\r\n"
    }
    options.upload['file'].each {|filename|
      #multipart_body << "--#{boundary}\r\n"
      #multipart_body << "Content-Disposition: form-data; name=\"#{file_field}\"; filename=\"#{File.basename(filename)}\"\r\n"
      #multipart_body << "Content-Type: application/octet-stream\r\n"
      #multipart_body << "Content-Transfer-Encoding: base64\r\n" if options.upload['base64']
      #multipart_body << "\r\n"
      # http://stackoverflow.com/questions/7157207/how-can-i-read-a-file-with-ruby need to read in binary
      file = File.open(filename, "rb")
      if options.upload['base64']
        #enc = Base64.encode64(File.read(filename))
        enc = Base64.encode64(file.read())
        multipart_body << enc
      else
        #multipart_body << File.read(filename)
        multipart_body << file.read()
      end
    }
    #multipart_body << "\r\n--#{boundary}--\r\n"
    request.body = multipart_body.join
    #request.content_type = "multipart/form-data, boundary=\"#{boundary}\""
  elsif request.content_type && options.data