Update With Media

starlineventure
@starlineventure Starline Ventures

Im trying to post an image and I keep on getting error creating status.
This is the function.
I basically set the ur to the https upload.twitter.com.
Then I do some validation on the status message itself.
Then I take a url image. I use a curl function to follow any redirects.
Using file get contents I write that image to a local file. Then I echo some
stuff make sure that process worked. It does. Write bytes has a number
greater than zero and file exists always returns 1.
I set the file of data['media'] to what I think it is supposed to be
and I get an error everytime. Any clues?

  1. public function statusUpdateWithMedia($status, $url)
  2.     {
  3.         $this->_init();
  4.         $this->setUri('https://upload.twitter.com');
  5.         $path = '/1/statuses/update_with_media.xml';
  6.         $len = iconv_strlen(htmlspecialchars($status, ENT_QUOTES, 'UTF-8'), 'UTF-8');
  7.         if ($len > self::STATUS_MAX_CHARACTERS) {
  8.             include_once 'Zend/Service/Twitter/Exception.php';
  9.             throw new Zend_Service_Twitter_Exception(
  10.                 'Status must be no more than '
  11.                 . self::STATUS_MAX_CHARACTERS
  12.                 . ' characters in length'
  13.             );
  14.         } elseif (0 == $len) {
  15.             include_once 'Zend/Service/Twitter/Exception.php';
  16.             throw new Zend_Service_Twitter_Exception(
  17.                 'Status must contain at least one character'
  18.             );
  19.         }
  20.  
  21.         $data = array('status' => $status);
  22.         $remove = "";
  23.         if ($url && iconv_strlen($url, 'UTF-8') > 0) {
  24.  
  25.            $photo = $this->get_web_page($url);
  26.          $photo = $photo['url'];
  27.           echo "The Photo Url is $photo";
  28.  
  29.            $photo = file_get_contents($photo);
  30.             $t = explode(".", $url);
  31.  
  32.           $ext = strtolower($t[(sizeof($t) - 1)]);
  33.  
  34.            if($ext != "jpg" && $ext != "png" && $ext != "jpeg" && $ext != "gif")
  35.           $ext = "jpeg";
  36.            echo "What is the size of photo " . sizeof($photo) . "</br>";
  37.             echo "</br>";
  38.           $remove = "MettyaPhoto1.$ext";
  39.            $bytes = file_put_contents($remove, $photo);
  40.            echo "How many bytes were put $bytes </br>";
  41.            echo "Does the file exists " . file_exists($remove);
  42.          $mediaphoto = "MettyaPhoto";
  43.             $data['media[]'] = "@{$remove};type=image/$ext;filename={$mediaphoto}";
  44.         }
  45.         $response = $this->_post($path, $data);
  46.         if(file_exists($remove))
  47.         unlink($remove);
  48.         return new Zend_Rest_Client_Result($response->getBody());
  49.     }
2 weeks 5 days ago

Replies

starlineventure
@starlineventure Starline Ventures

This is the error I receive from the xml object:

  1. Zend_Rest_Client_Result Object
  2. (
  3.     [_sxml:protected] => SimpleXMLElement Object
  4.         (
  5.             [request] => /1/statuses/update_with_media.xml
  6.             [error] => Error creating status.
  7.         )
  8.  
  9.     [_errstr:protected] => 
  10. )
2 weeks 5 days ago
episod
@episod Taylor Singletary

I'm not familiar enough with Zend to know whether it's handling other details for you -- do you know how it's doing OAuth in this context as well as how it is presenting the mixed content HTTP request? Are you able to use this same library to make basic requests and POST-based requests on api.twitter.com without the complication of file upload?

1 week 6 days ago
starlineventure
@starlineventure Starline Ventures

The same library definitely works making basic requests without a file upload:
This is the status update function

  1. public function statusUpdate($status, $inReplyToStatusId = null)
  2.     {
  3.         $this->_init();
  4.         $path = '/1/statuses/update.xml';
  5.         $len = iconv_strlen(htmlspecialchars($status, ENT_QUOTES, 'UTF-8'), 'UTF-8');
  6.         if ($len > self::STATUS_MAX_CHARACTERS) {
  7.             include_once 'Zend/Service/Twitter/Exception.php';
  8.             throw new Zend_Service_Twitter_Exception(
  9.                 'Status must be no more than '
  10.                 . self::STATUS_MAX_CHARACTERS
  11.                 . ' characters in length'
  12.             );
  13.         } elseif (0 == $len) {
  14.             include_once 'Zend/Service/Twitter/Exception.php';
  15.             throw new Zend_Service_Twitter_Exception(
  16.                 'Status must contain at least one character'
  17.             );
  18.         }
  19.         $data = array('status' => $status);
  20.         if (is_numeric($inReplyToStatusId) && !empty($inReplyToStatusId)) {
  21.             $data['in_reply_to_status_id'] = $inReplyToStatusId;
  22.         }
  23.         $response = $this->_post($path, $data);
  24.         return new Zend_Rest_Client_Result($response->getBody());
  25.     }
1 week 6 days ago
starlineventure
@starlineventure Starline Ventures

Im pretty sure the Oauth signature works without a problem because using the code for a simple status update works fine. And actually if I post a tweet that has the t.co url in it...and that same tweet has an image attached...using the statusUpdate function will actually post a tweet with that image.

The post function calls a prepare function that basically checks that the URI is set properly.
Then it calls a function called performPost that would use the $data variable
that was passed in the $response = $this->_post($path, $data);

This is the performPost function that uses the $data variable

  1.  protected function _performPost($method, $data = null)
  2.     {
  3.         $client = $this->_localHttpClient;
  4.         if (is_string($data)) {
  5.             $client->setRawData($data);
  6.         } elseif (is_array($data) || is_object($data)) {
  7.             $client->setParameterPost((array) $data);
  8.         }
  9.         return $client->request($method);
  10.     }
1 week 6 days ago
starlineventure
@starlineventure Starline Ventures

So I updated the _performPost function with a safe_encode function that I borrowed from the TmhOauth library. https://github.com/themattharris/tmhOAuth/blob/master/tmhOAuth.php

The new _performPost function now looks like this:

  1.  protected function _performPost($method, $data = null)
  2.     {
  3.         $client = $this->_localHttpClient;
  4.         if (is_string($data)) {
  5.             $client->setRawData($data);
  6.         } elseif (is_array($data)){
  7.        error_log("Tesgggggg");
  8.       $this->safe_encode($data); 
  9.      $client->setParameterPost((array) $data);        
  10.        } elseif (is_object($data)) {
  11.             $client->setParameterPost((array) $data);
  12.         }
  13.         return $client->request($method);
  14.     }
  15.  
  16.    private function safe_encode(&$data) {
  17.      if (is_array($data)) {
  18.        return array_map(array($this, 'safe_encode'), $data);
  19.       } else if (is_scalar($data)) {
  20.        return str_ireplace(
  21.          array('+', '%7E'),
  22.          array(' ', '~'),
  23.            rawurlencode($data)
  24.           );
  25.        } else {
  26.          return '';
  27.      }
  28.     }
  29.  
  30.    }
1 week 6 days ago
starlineventure
@starlineventure Starline Ventures

But now Im getting this error saying that my tweet text is too long, even though I check the text length before I actually send the tweet. So strange things are happening

  1. How long is the text of the tweet 132
  2. What is the size of photo 1</br></br>
  3. How many bytes were put 97478 </br>
  4. Does the file exists 1
  5. How long is the text of the tweet 132
  6. What is the size of photo 1</br></br>
  7. How many bytes were put 97478 </br>
  8. Does the file exists 1
  9. Zend_Rest_Client_Result Object
  10. (
  11.     [_sxml:protected] => SimpleXMLElement Object
  12.         (
  13.             [request] => /1/statuses/update_with_media.xml
  14.             [error] => The text of your tweet is too long.
  15.         )
  16.  
  17.     [_errstr:protected] => 
  18. )
  19. 1
1 week 6 days ago
starlineventure
@starlineventure Starline Ventures

I have another post showing how I updated the performPost function but it is awaiting moderation

1 week 6 days ago
starlineventure
@starlineventure Starline Ventures

I figured that the text of the tweet was getting extending past the length of 132 when I passed it through the safe_encode method and it found a url. So I put a url cleaner to remove all urls from the text, and now we're back to the same error of..."error creating status"

  1.  How long is the text of the tweet 132 
  2. New Orleans Hornets: We hope to see you at Generations Hall on Sunday for #Honeybee Audition Finals! http://instagr.am/p/NUNgRAjYJB/ 
  3. How long is the text of the tweet 132 
  4. New Orleans Hornets: We hope to see you at Generations Hall on Sunday for #Honeybee Audition Finals!
  5. What is the size of photo 1</br></br>How many bytes were put 97478 </br>
  6. Does the file exists 1 
  7. How long is the text of the tweet 132 
  8. New Orleans Hornets: We hope to see you at Generations Hall on Sunday for #Honeybee Audition Finals! http://instagr.am/p/NUNgRAjYJB/ 
  9. How long is the text of the tweet 132 New Orleans Hornets: We hope to see you at Generations Hall on Sunday for #Honeybee Audition Finals!
  10. What is the size of photo 1</br></br>
  11. How many bytes were put 97478 </br>
  12. Does the file exists 1
  13. Zend_Rest_Client_Result Object
  14. (
  15.     [_sxml:protected] => SimpleXMLElement Object
  16.         (
  17.             [request] => /1/statuses/update_with_media.xml
  18.             [error] => Error creating status.
  19.         )
  20.  
  21.     [_errstr:protected] => 
  22. )
1 week 5 days ago
episod
@episod Taylor Singletary

Are you actually uploading a photo when posting this link to an instagr.am photo? Keep in mind that when you use update_with_media you need to be sending an actual image -- in most cases you won't be including a URL within the post. In all cases, remember that the photo you're uploading with the method will be at least a 20 character URL within the tweet body as well, so your text needs to accomodate for that.

1 week 5 days ago
starlineventure
@starlineventure Starline Ventures

Yes. Uploading a photo for sure. So Im going to post the entire function, and the resulting
response. You will see that the text that is passed originally is 129 (too long) but after I pull out all urls...the text is 108. So I am getting an error creating status message.

  1.     public function statusUpdateWithMedia($status, $url)
  2.     {
  3.         $this->_init();
  4.         $this->setUri('https://upload.twitter.com');
  5.         $path = '/1/statuses/update_with_media.xml';
  6.         $len = iconv_strlen(htmlspecialchars($status, ENT_QUOTES, 'UTF-8'), 'UTF-8');
  7.         if ($len > self::STATUS_MAX_CHARACTERS) {
  8.             include_once 'Zend/Service/Twitter/Exception.php';
  9.             throw new Zend_Service_Twitter_Exception(
  10.                 'Status must be no more than '
  11.                 . self::STATUS_MAX_CHARACTERS
  12.                 . ' characters in length'
  13.             );
  14.         } elseif (0 == $len) {
  15.             include_once 'Zend/Service/Twitter/Exception.php';
  16.             throw new Zend_Service_Twitter_Exception(
  17.                 'Status must contain at least one character'
  18.             );
  19.         }
  20.  
  21.         echo " How long is the text of the tweet $len ";
  22.         echo $status;
  23.         $status = $this->cleaner($status);
  24.         $len = iconv_strlen(htmlspecialchars($status, ENT_QUOTES, 'UTF-8'), 'UTF-8');
  25.         echo " How long is the text of the tweet $len ";
  26.         echo $status;
  27.         $data = array('status' => $status);
  28.         $remove = "";
  29.         if ($url && iconv_strlen($url, 'UTF-8') > 0) {
  30.  
  31.            $photo = $this->get_web_page($url);
  32.          $photo = $photo['url'];
  33.  
  34.  
  35.            $photo = file_get_contents($photo);
  36.             $t = explode(".", $url);
  37.  
  38.           $ext = strtolower($t[(sizeof($t) - 1)]);
  39.  
  40.            if($ext != "jpg" && $ext != "png" && $ext != "jpeg" && $ext != "gif")
  41.           $ext = "jpeg";
  42.            echo "What is the size of photo " . sizeof($photo) . "</br>";
  43.             echo "</br>";
  44.           $remove = "MettyaPhoto1.$ext";
  45.            $bytes = file_put_contents($remove, $photo);
  46.            echo "How many bytes were put $bytes </br>";
  47.            echo "Does the file exists " . file_exists($remove);
  48.          $mediaphoto = "MettyaPhoto";
  49.             $data['media[]'] = "@{$remove};type=image/$ext;filename={$remove}";
  50.         }
  51.         $response = $this->_post($path, $data);
  52.         if(file_exists($remove))
  53.         unlink($remove);
  54.         return new Zend_Rest_Client_Result($response->getBody());
  55.     }

The RESPONSE:

  1. How long is the text of the tweet 129 
  2. @SamuelCookIII: RT @TeamCookNOLA: Had a great time tonight at @barackobama's #nola fundraiser. #forward http://t.co/zqKW5X4F 
  3. How long is the text of the tweet 108 
  4. @SamuelCookIII: RT @TeamCookNOLA: Had a great time tonight at @barackobama's #nola fundraiser. #forward
  5. What is the size of photo 1</br></br>
  6. How many bytes were put 109490 </br>
  7. Does the file exists 1
  8. Post Parameters:
  9. (
  10.     [status] => @SamuelCookIII: RT @TeamCookNOLA: Had a great time tonight at @barackobama's #nola fundraiser. #forward
  11.     [media[]] => @MettyaPhoto1.jpeg;type=image/jpeg;filename=MettyaPhoto1.jpeg
  12. )
  13. Zend_Rest_Client_Result Object
  14. (
  15.     [_sxml:protected] => SimpleXMLElement Object
  16.         (
  17.             [request] => /1/statuses/update_with_media.xml
  18.             [error] => Error creating status.
  19.         )
  20.  
  21.     [_errstr:protected] => 
  22. )
1 week 5 days ago
starlineventure
@starlineventure Starline Ventures

Specifically these are the post parameters...my previous post I just post was queued for moderation.

  1. (
  2.     [status] => @SamuelCookIII: RT @TeamCookNOLA: Had a great time tonight at @barackobama's #nola fundraiser. #forward
  3.     [media[]] => @MettyaPhoto1.jpeg;type=image/jpeg;filename=MettyaPhoto1.jpeg
  4. )
1 week 5 days ago
starlineventure
@starlineventure Starline Ventures

These are the headers:

  1. (
  2.     [0] => Host: upload.twitter.com
  3.     [1] => Connection: close
  4.     [2] => Accept-encoding: gzip, deflate
  5.     [3] => User-Agent: Zend_Http_Client
  6.     [4] => Accept-Charset: ISO-8859-1,utf-8
  7.     [5] => Authorization: OAuth realm="",oauth_consumer_key="",oauth_nonce="ebaaaedcaddddc5c7aceac81ac50bd6e66a6e12b",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1323325106",oauth_version="1.0",oauth_token="192312971267-zMYBQ3kAgQJDQ7WrTgn0TAFtP5DLGm0etaaC1d7l1W",oauth_signature="F%2B1Aw8yck4hW71Nh%2F3IVkTDjWYg%3D"
  8.     [6] => Content-Type: application/x-www-form-urlencoded
  9.     [7] => Content-Length: 212
  10. )
2 days 7 hours ago
starlineventure
@starlineventure Starline Ventures

These are the headers from a successful tweet

  1. (
  2.     [0] => Host: api.twitter.com
  3.     [1] => Connection: close
  4.     [2] => Accept-encoding: gzip, deflate
  5.     [3] => User-Agent: Zend_Http_Client
  6.     [4] => Accept-Charset: ISO-8859-1,utf-8
  7.     [5] => Authorization: OAuth realm="",oauth_consumer_key="",oauth_nonce="56d87f87c91aab521ce0c0785d50384e",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1343326085",oauth_version="1.0",oauth_token="192971267-zMYBQ3kAgQJDQ7WrTgn0TtP5DLGm0etaaC1d7l1W",oauth_signature="50e6M%2BLT0DU%2FsGoz3T%2B0vqiPuIQ%3D"
  8.     [6] => Content-Type: application/x-www-form-urlencoded
  9.     [7] => Content-Length: 155
  10. )

To this tweet in particular https://twitter.com/starlineventure/status/228552284609576960

2 days 7 hours ago
starlineventure
@starlineventure Starline Ventures

When I change the enctype to multipart I get a cannot authenticate with oauth?

  1. Content-Disposition: form-data; name="status"
  2.  
  3. jihae526: #beignets #nola #cafedumonde
  4. -----ZENDHTTPCLIENT-75dd2d8c9eb32bc5e11948b7d0ba3fcd
  5. Content-Disposition: form-data; name="media[]"
  6.  
  7. @MettyaPhoto1.jpg;type=image/jpg;filename=MettyaPhoto1.jpg
  8. -----ZENDHTTPCLIENT-75dd2d8c9eb32bc5e11948b7d0ba3fcd--
  9.  Headers Array
  10. (
  11.     [0] => Host: upload.twitter.com
  12.     [1] => Connection: close
  13.     [2] => Accept-encoding: gzip, deflate
  14.     [3] => User-Agent: Zend_Http_Client
  15.     [4] => Accept-Charset: ISO-8859-1,utf-8
  16.     [5] => Authorization: OAuth realm="",oauth_consumer_key="",oauth_nonce="56d87f87c91aab521ce0c0785d50384e",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1343326085",oauth_version="1.0",oauth_token="192971267-zMYBQ3kAgQJDQ7WrTgn0TtP5DLGm0etaaC1d7l1W",oauth_signature="50e6M%2BLT0DU%2FsGoz3T%2B0vqiPuIQ%3D"
  17.     [6] => Content-Type: multipart/form-data; boundary=---ZENDHTTPCLIENT-75dd2d8c9eb32bc5e11948b7d0ba3fcd
  18.     [7] => Content-Length: 363
  19. )
  20.  Query Zend_Rest_Client_Result Object
  21. (
  22.     [_sxml:protected] => SimpleXMLElement Object
  23.         (
  24.             [request] => /1/statuses/update_with_media.xml
  25.             [error] => Could not authenticate with OAuth.
  26.         )
  27.  
  28.     [_errstr:protected] => 
  29. )
  30. 1
2 days 7 hours ago
episod
@episod Taylor Singletary

Your OAuth library might not know how to handle multipart uploads correctly -- OAuth only signs the post parameters of a x-www-form-urlencoded request but once you do a multipart upload, you're no longer sending data of that type. Therefore, OAuth only need concern itself with the request at large and its oauth_* parameters, omitting all consideration of the POST body. It's not possible from this snippet to determine if that's the cause of your OAuth problem in this case though.

1 day 12 hours ago