【问题标题】:Upload media to twitter using perl使用 perl 将媒体上传到 twitter
【发布时间】:2019-01-06 22:34:10
【问题描述】:

有没有人成功地将媒体上传到 Twitter,即使用 Perl 发布带有图片的推文?

我想从我的博客上传图片,而不是手动完成。

update_with_media(status, media[]) 已弃用并崩溃。 Twitter 说要使用普通的 update(),传递一个媒体 ID。但是需要先上传媒体来获取id,我找不到代码示例。

有这方面的经验吗?

干杯, 彼得

【问题讨论】:

    标签: perl twitter media


    【解决方案1】:

    我想我会在这里添加一个更新,即使这个帖子已经很老了。我也在寻找如何使用 Perl 将媒体上传到 twitter 的答案。

    Net::Twitter 完全能够将 PNG 图像发送到 Twitter,尽管文档很差。 OP 是正确的,update_with_media 已被弃用并为我们崩溃。

    您确实需要结合使用 $nt->upload 和 $nt->update 方法。您上传了用 base64 编码的 RAW PNG 文件,我无法让 RAW PNG 文件上传工作,但 base64 编码时没有问题。上传方法成功时返回一个 JSON 结构,其中包含 media_ids。然后这些 id 与 $nt->update 方法一起传递。这是一些实际的代码

    use Net::Twitter;
    use File::Slurp;
    use MIME::Base64;
    use Data::Dumper;
    
    my $nt = Net::Twitter->new(
        ssl      => 1,
        traits   => [qw/API::RESTv1_1/],
        consumer_key        => $config->{twitter}{api_key},
        consumer_secret     => $config->{twitter}{api_secret},
        access_token        => $config->{twitter}{access_token},
        access_token_secret => $config->{twitter}{access_token_secret},
        );
    
    my $filename = "<somelink to a PNG file>";
    my $file_contents = read_file ($filename , binmode => ':raw');
    
    my $status = $nt->upload(encode_base64($file_contents));
    print "SendTweet: status = ".Dumper($status);
    
    my $status2;
    
    eval {
        $status2 = $nt->update({status => $s , media_ids => $status->{media_id} });
        print "status2 = ".Dumper($status2);
    };
    
    if ($@)
    {
        print "Error: $@\n";
    }
    

    代码是直接从我们的工作测试代码中提取的,所以应该可以工作。此代码纯粹是概念证明,因此您需要添加所有 twitter 身份验证等。

    我们只制作了 PNG 文件,但我看不出视频等不能正常工作的原因,因为我们只是遵循 Twitter 文档。

    罗伯

    【讨论】:

    • 谢谢,罗伯。我的代码现在可以正常工作,但我会将其保留在文件管理器中以备将来使用。
    【解决方案2】:

    最后我使用了带有 twurl 的 readpipe。如果我一开始就知道 twurl,我可能不会打扰 Net::Twitter! twurl 效果很好,它会返回一个完整的 json 字符串来告诉你出了什么问题(如果有的话)。

    【讨论】:

      【解决方案3】:

      先决条件:您需要为您的 Twitter 帐户获取 Oauth 密钥。 (见这里 - https://developer.twitter.com/en/docs/basics/authentication/guides/access-tokens.html)。其他地方有一些逐步的在线示例也可以提供帮助。

      这是我最终得到的代码。

      首先调用 tweet 模块(顺便说一下,这些不是有效的键 - 只需插入你的)

      use Jimtweet;
      
      my $tweet=Jimtweet->new();
      
      $tweet->consumer_key('KvfevhjwkKJvinvalidkeycvhejwkKJVCwe');
      $tweet->consumer_secret('KvfevhjwkKJvcvnvalidkeyhejwkKJVCwe'); 
      $tweet->oauth_token('KvfevhjwkKJvcvhenvalidkeyjwkKJVCwKvfevhjwkKJvcvhejwkKJVCweVU');
      $tweet->oauth_token_secret('KvfevhjwkKJvcvhejwnvalidkeykKJVCwe');
      
      my $res = $tweet->update_status($message, $ENV{DOCUMENT_ROOT}.$li);
      

      Jimtweet 是我在网上找到的一个免费模块(我忘了在哪里),但我不得不修改它以进行图像上传。如下。 $message 是要发送的文本状态消息 $li 包含我要上传的文件的本地路径。这是服务器上的本地文件。 $ENV{DOCUMENT_ROOT} 包含我网站上公共 HTML 文件的服务器路径。

      $res 包含来自 twitter 的 JSON 回复,如果需要,您可以查看。

      如果您想使用它,请从“package Jimtweet”中剪切并粘贴所有内容;然后进入一个名为 Jimtweet.pm 的文件,上面的代码应该使用它。如果您的 perl 安装找不到该模块,请尝试在 use Jimtweet; 行之前添加行 use lib "/home/your/path/to/jimtweet/directory;"

      Twitter 需要上传一张图片,然后它返回一个media_id,然后您将media_id 包含在您要发布的常规消息中。请参阅下面的 Jimtweet 包:

      package Jimtweet;
      #####JimTweet 0.1 By James Januszka 2010
      #####Email:jimjanuszka@gmail.com
      #####Twitter:@jamesjanuszka
      #####Modifications by John Bell to include image upload. Twitter: @BellUkcbajr
      use strict;
      use warnings;
      use LWP;
      use HTTP::Headers;
      use URI::Encode qw(uri_encode);
      use URI::Escape qw(uri_escape);
      use Digest::HMAC_SHA1;
      
      ####Constructor####
      sub new {
          my $self={};
          $self->{OAUTH_VERSION}=uri_escape("1.0");
          $self->{OAUTH_SIGNATURE_METHOD}=uri_escape("HMAC-SHA1");
          $self->{OAUTH_TIMESTAMP}=undef;
          $self->{OAUTH_NONCE}=undef;
          $self->{AGENT}="jimtweet/0.1";
      
      #####################
      #Use this for status updates
          $self->{URLx}="https://api.twitter.com/1.1/statuses/update.json";
      
      #####################
      #Use this for image upload
          $self->{URL}="https://upload.twitter.com/1.1/media/upload.json";
      
          $self->{BROWSER}=LWP::UserAgent->new(agent =>$self->{AGENT});
          $self->{CONSUMER_KEY}=undef;
          $self->{CONSUMER_SECRET}=undef;
          $self->{OAUTH_TOKEN}=undef;
          $self->{OAUTH_TOKEN_SECRET}=undef;
          $self->{STATUS}=undef;
          $self->{MEDIAurl}=undef;
          bless($self);
          return $self;
      } 
      
      sub consumer_key{
          my $self=shift;
          if (@_) { $self->{CONSUMER_KEY}=uri_escape(shift) }
          return $self->{CONSUMER_KEY};
      }
      
      sub consumer_secret{
          my $self = shift;
          if (@_) { $self->{CONSUMER_SECRET}=uri_escape(shift) }
          return $self->{CONSUMER_SECRET};
      }
      
      sub oauth_token{
          my $self = shift;
          if (@_) { $self->{OAUTH_TOKEN}=uri_escape(shift) }
          return $self->{OAUTH_TOKEN};
      }
      
      sub oauth_token_secret{
          my $self = shift;
          if (@_) { $self->{OAUTH_TOKEN_SECRET}=uri_escape(shift) }
          return $self->{OAUTH_TOKEN_SECRET};
      }
      
      sub update_status(@){
          sleep(2);
          my $self = shift;
          if (@_) { $self->{STATUS}=uri_escape(shift) }
          if (@_) { $self->{MEDIAurl}=shift }
      
      
      #Got parameters. Now create the POST to upload an image
      
          my $seconds = time(); 
          $self->{OAUTH_TIMESTAMP}=uri_escape($seconds);
          $self->{OAUTH_NONCE}=$self->{OAUTH_TIMESTAMP};
      
      #####################
      #Use this for uploads. Parameters have to be in alphabetical order! 
          my $query=qq(oauth_consumer_key=$self->{CONSUMER_KEY}&oauth_nonce=$self->{OAUTH_NONCE}&oauth_signature_method=$self->{OAUTH_SIGNATURE_METHOD}&oauth_timestamp=$self->{OAUTH_TIMESTAMP}&oauth_token=$self->{OAUTH_TOKEN}&oauth_version=$self->{OAUTH_VERSION});
      
          my $sig="POST&";
      
          $sig .=uri_encode($self->{URL},1);
          $sig .="&";
          $sig .=uri_encode($query,1);
      
          my $sig_key=$self->{CONSUMER_SECRET};
          $sig_key .="&";
          $sig_key .=$self->{OAUTH_TOKEN_SECRET};
      
          my $hmac = Digest::HMAC_SHA1->new($sig_key);
          $hmac->add($sig);
      
          my $oauth_signature_base64=$hmac->b64digest;
          $oauth_signature_base64 .="=";
      
          my $utf8_oauth_signature_base64=uri_escape($oauth_signature_base64);
      
          my $header=qq(OAuth oauth_nonce="$self->{OAUTH_NONCE}", oauth_signature_method="$self->{OAUTH_SIGNATURE_METHOD}", oauth_timestamp="$self->{OAUTH_TIMESTAMP}", oauth_consumer_key="$self->{CONSUMER_KEY}", oauth_token="$self->{OAUTH_TOKEN}", oauth_signature="$utf8_oauth_signature_base64", oauth_version="$self->{OAUTH_VERSION}");
      
          my $res = $self->{BROWSER}->post( 
              $self->{URL}, 
              'Authorization' => $header, 
              'content-type' => 'form-data', 
              'Content' => [ media => ["$self->{MEDIAurl}"] ]    
          );
      
          use JSON;
          my $response = decode_json  ($res->content);
          my $media_id = $response->{'media_id'};
      
          $seconds = time(); 
          $self->{OAUTH_TIMESTAMP}=uri_escape($seconds);
          $self->{OAUTH_NONCE}=$self->{OAUTH_TIMESTAMP}
      
      
          my $queryx=qq(media_ids=$media_id&oauth_consumer_key=$self->{CONSUMER_KEY}&oauth_nonce=$self->{OAUTH_NONCE}&oauth_signature_method=$self->{OAUTH_SIGNATURE_METHOD}&oauth_timestamp=$self->{OAUTH_TIMESTAMP}&oauth_token=$self->{OAUTH_TOKEN}&oauth_version=$self->{OAUTH_VERSION}&status=$self->{STATUS});
      
          my $sigx="POST&";
      
          $sigx .=uri_encode($self->{URLx},1);
          $sigx .="&";
          $sigx .=uri_encode($queryx,1);
      
          my $hmacx = Digest::HMAC_SHA1->new($sig_key);
          $hmacx->add($sigx);
      
          my $oauth_signature_base64x=$hmacx->b64digest;
          $oauth_signature_base64x .="=";
      
          my $utf8_oauth_signature_base64x=uri_escape($oauth_signature_base64x);
      
          my $headerx=qq(OAuth oauth_nonce="$self->{OAUTH_NONCE}", oauth_signature_method="$self->{OAUTH_SIGNATURE_METHOD}", oauth_timestamp="$self->{OAUTH_TIMESTAMP}", oauth_consumer_key="$self->{CONSUMER_KEY}", oauth_token="$self->{OAUTH_TOKEN}", oauth_signature="$utf8_oauth_signature_base64x", oauth_version="$self->{OAUTH_VERSION}");
      
      #And done generating content. Now to POST to twitter. 
      
          $res = $self->{BROWSER}->post( 
              $self->{URLx},
              'Authorization' => $headerx, 
              'content-type' => 'application/x-www-form-urlencoded', 
              'Content' => qq(media_ids=$media_id&status=$self->{STATUS}) 
          );
      
          return $res;
      }
      
      ####Footer####
      1;  #so the require or use succeeds
      

      【讨论】:

      • 请注意,我们更喜欢这里的技术写作风格。我们轻轻地劝阻问候,希望你能帮助,谢谢,提前感谢,感谢信,问候,亲切的问候,签名,请你能帮助,聊天材料和缩写 txtspk,恳求,你多久了被卡住,投票建议,元评论等。请编辑您的答案,并删除所有与回答此问题无关的部分。
      猜你喜欢
      • 2015-03-06
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      • 2016-10-21
      • 2015-05-27
      • 2015-06-15
      • 2021-07-22
      • 1970-01-01
      相关资源
      最近更新 更多