Zapier 代码 (JS) + Twitter API - POST statuses/retweet/:id

Posted

技术标签:

【中文标题】Zapier 代码 (JS) + Twitter API - POST statuses/retweet/:id【英文标题】:Zapier Code (JS) + Twitter API - POST statuses/retweet/:id 【发布时间】:2018-11-05 19:22:09 【问题描述】:

@ReganStarr 为 Zapier 编写的 JS 代码可以为作为变量传递的任何给定 tweet_id 生成 “like” 动作。我正在尝试对其进行修改以生成 “转推” 操作。

var twitterApplicationConsumerKey = 'MyTwitterConsumerKey';
var twitterApplicationConsumerSecret = 'MyTwitterConsumerSecret';
var twitterApplicationAccessToken = 'MyTwitterAccessToken';
var twitterApplicationAccessTokenSecret = 'MyTwitterTokenSecret'; 

// That's it. No need to edit anything below.

function b64_hmac_sha1(k,d,_p,_z)
  if(!_p)_p='=';if(!_z)_z=8;function _f(t,b,c,d)if(t<20)return(b&c)|((~b)&d);if(t<40)return b^c^d;if(t<60)return(b&c)|(b&d)|(c&d);return b^c^d;function _k(t)return(t<20)?1518500249:(t<40)?1859775393:(t<60)?-1894007588:-899497514;function _s(x,y)var l=(x&0xFFFF)+(y&0xFFFF),m=(x>>16)+(y>>16)+(l>>16);return(m<<16)|(l&0xFFFF);function _r(n,c)return(n<<c)|(n>>>(32-c));function _c(x,l)x[l>>5]|=0x80<<(24-l%32);x[((l+64>>9)<<4)+15]=l;var w=[80],a=1732584193,b=-271733879,c=-1732584194,d=271733878,e=-1009589776;for(var i=0;i<x.length;i+=16)var o=a,p=b,q=c,r=d,s=e;for(var j=0;j<80;j++)if(j<16)w[j]=x[i+j];elsew[j]=_r(w[j-3]^w[j-8]^w[j-14]^w[j-16],1);var t=_s(_s(_r(a,5),_f(j,b,c,d)),_s(_s(e,w[j]),_k(j)));e=d;d=c;c=_r(b,30);b=a;a=t;a=_s(a,o);b=_s(b,p);c=_s(c,q);d=_s(d,r);e=_s(e,s);return[a,b,c,d,e];function _b(s)var b=[],m=(1<<_z)-1;for(var i=0;i<s.length*_z;i+=_z)b[i>>5]|=(s.charCodeAt(i/8)&m)<<(32-_z-i%32);return b;function _h(k,d)var b=_b(k);if(b.length>16)b=_c(b,k.length*_z);var p=[16],o=[16];for(var i=0;i<16;i++)p[i]=b[i]^0x36363636;o[i]=b[i]^0x5C5C5C5C;var h=_c(p.concat(_b(d)),512+d.length*_z);return _c(o.concat(h),512+160);function _n(b)var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s='';for(var i=0;i<b.length*4;i+=3)var r=(((b[i>>2]>>8*(3-i%4))&0xFF)<<16)|(((b[i+1>>2]>>8*(3-(i+1)%4))&0xFF)<<8)|((b[i+2>>2]>>8*(3-(i+2)%4))&0xFF);for(var j=0;j<4;j++)if(i*8+j*6>b.length*32)s+=_p;elses+=t.charAt((r>>6*(3-j))&0x3F);return s;function _x(k,d)return _n(_h(k,d));return _x(k,d);


var tweetId = input.tweet_id;

//create nonce
function generateRandomString(desiredLengthOfRandomString) 
    var result = '';
    var possibleCharactersForRandomString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < desiredLengthOfRandomString; i++ )
        result += possibleCharactersForRandomString.charAt(Math.floor(Math.random() * possibleCharactersForRandomString.length));

    return result;


var randomString = generateRandomString(32);
var nonce = new Buffer(randomString).toString('base64');


//create timestamp
var timestamp = Math.floor(new Date() / 1000);

//create the signature
var signatureParameterString = 'id=' + tweetId + '&oauth_consumer_key=' + twitterApplicationConsumerKey + '&oauth_nonce=' + encodeURIComponent(nonce) + '&oauth_signature_method=HMAC-SHA1&oauth_timestamp=' + timestamp + '&oauth_token=' + twitterApplicationAccessToken + '&oauth_version=1.0';

var signatureBaseString = 'POST&https%3A%2F%2Fapi.twitter.com%2F1.1%2Ffavorites%2Fcreate.json&' + encodeURIComponent(signatureParameterString);

var signingKey = encodeURIComponent(twitterApplicationConsumerSecret) + '&' + encodeURIComponent(twitterApplicationAccessTokenSecret);

var signature = b64_hmac_sha1(signingKey, signatureBaseString);

var apiUrl = 'https://api.twitter.com/1.1/favorites/create.json?id=' + tweetId;

var oauthString = 'OAuth oauth_consumer_key="' + twitterApplicationConsumerKey + '", oauth_nonce="' + encodeURIComponent(nonce) + '", oauth_signature="' + encodeURIComponent(signature) + '", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' + timestamp + '", oauth_token="' + twitterApplicationAccessToken + '", oauth_version="1.0"';

fetch(apiUrl, 
  method: 'POST',
  headers: 
    'Authorization': oauthString
  
)
.then(function(res) 
  return res.json();
)
.then(function(body) 
  var output = body;
  callback(null, output);
)
.catch(callback);

我以为通过修改这一行:

var apiUrl = 'https://api.twitter.com/1.1/favorites/create.json?id=' + tweetId;

到这里:

var apiUrl = 'https://api.twitter.com/1.1/statuses/' + tweetId +'.json';

按照 Twitter here 的指示,就足够了,但它不起作用:-(

我做错了什么?

【问题讨论】:

【参考方案1】:

我相信 Twitter 上提到的端点与您将其更改为的端点不同。您可以尝试将apiUrl 更改为以下内容吗?

var apiUrl = 'https://api.twitter.com/1.1/statuses/retweet/' + tweetId +'.json';

或(为了更好的可读性)

var apiUrl = `https://api.twitter.com/1.1/statuses/retweet/$tweetId.json`;

我没有对此进行测试,但它看起来像是问题的原因。如果失败,请同时发布您遇到的错误。

更新:

SignatureBaseStringSignatureParameterString 也需要更改。

var twitterApplicationConsumerKey = 'MyTwitterConsumerKey';
var twitterApplicationConsumerSecret = 'MyTwitterConsumerSecret';
var twitterApplicationAccessToken = 'MyTwitterAccessToken';
var twitterApplicationAccessTokenSecret = 'MyTwitterTokenSecret'; 

// That's it. No need to edit anything below.

function b64_hmac_sha1(k,d,_p,_z)
  if(!_p)_p='=';if(!_z)_z=8;function _f(t,b,c,d)if(t<20)return(b&c)|((~b)&d);if(t<40)return b^c^d;if(t<60)return(b&c)|(b&d)|(c&d);return b^c^d;function _k(t)return(t<20)?1518500249:(t<40)?1859775393:(t<60)?-1894007588:-899497514;function _s(x,y)var l=(x&0xFFFF)+(y&0xFFFF),m=(x>>16)+(y>>16)+(l>>16);return(m<<16)|(l&0xFFFF);function _r(n,c)return(n<<c)|(n>>>(32-c));function _c(x,l)x[l>>5]|=0x80<<(24-l%32);x[((l+64>>9)<<4)+15]=l;var w=[80],a=1732584193,b=-271733879,c=-1732584194,d=271733878,e=-1009589776;for(var i=0;i<x.length;i+=16)var o=a,p=b,q=c,r=d,s=e;for(var j=0;j<80;j++)if(j<16)w[j]=x[i+j];elsew[j]=_r(w[j-3]^w[j-8]^w[j-14]^w[j-16],1);var t=_s(_s(_r(a,5),_f(j,b,c,d)),_s(_s(e,w[j]),_k(j)));e=d;d=c;c=_r(b,30);b=a;a=t;a=_s(a,o);b=_s(b,p);c=_s(c,q);d=_s(d,r);e=_s(e,s);return[a,b,c,d,e];function _b(s)var b=[],m=(1<<_z)-1;for(var i=0;i<s.length*_z;i+=_z)b[i>>5]|=(s.charCodeAt(i/8)&m)<<(32-_z-i%32);return b;function _h(k,d)var b=_b(k);if(b.length>16)b=_c(b,k.length*_z);var p=[16],o=[16];for(var i=0;i<16;i++)p[i]=b[i]^0x36363636;o[i]=b[i]^0x5C5C5C5C;var h=_c(p.concat(_b(d)),512+d.length*_z);return _c(o.concat(h),512+160);function _n(b)var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s='';for(var i=0;i<b.length*4;i+=3)var r=(((b[i>>2]>>8*(3-i%4))&0xFF)<<16)|(((b[i+1>>2]>>8*(3-(i+1)%4))&0xFF)<<8)|((b[i+2>>2]>>8*(3-(i+2)%4))&0xFF);for(var j=0;j<4;j++)if(i*8+j*6>b.length*32)s+=_p;elses+=t.charAt((r>>6*(3-j))&0x3F);return s;function _x(k,d)return _n(_h(k,d));return _x(k,d);


var tweetId = inputData.tweet_id;

//create nonce
function generateRandomString(desiredLengthOfRandomString) 
    var result = '';
    var possibleCharactersForRandomString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < desiredLengthOfRandomString; i++ )
        result += possibleCharactersForRandomString.charAt(Math.floor(Math.random() * possibleCharactersForRandomString.length));

    return result;


var randomString = generateRandomString(32);
var nonce = new Buffer(randomString).toString('base64');


//create timestamp
var timestamp = Math.floor(new Date() / 1000);

//create the signature
var signatureParameterString = 'oauth_consumer_key=' + twitterApplicationConsumerKey + '&oauth_nonce=' + encodeURIComponent(nonce) + '&oauth_signature_method=HMAC-SHA1&oauth_timestamp=' + timestamp + '&oauth_token=' + twitterApplicationAccessToken + '&oauth_version=1.0';

var signatureBaseString = `POST&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fretweet%2F$tweetId.json&` + encodeURIComponent(signatureParameterString);

var signingKey = encodeURIComponent(twitterApplicationConsumerSecret) + '&' + encodeURIComponent(twitterApplicationAccessTokenSecret);

var signature = b64_hmac_sha1(signingKey, signatureBaseString);

// var apiUrl = 'https://api.twitter.com/1.1/favorites/create.json?id=' + tweetId;

var apiUrl = `https://api.twitter.com/1.1/statuses/retweet/$tweetId.json`;

var oauthString = 'OAuth oauth_consumer_key="' + twitterApplicationConsumerKey + '", oauth_nonce="' + encodeURIComponent(nonce) + '", oauth_signature="' + encodeURIComponent(signature) + '", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' + timestamp + '", oauth_token="' + twitterApplicationAccessToken + '", oauth_version="1.0"';

fetch(apiUrl, 
  method: 'POST',
  headers: 
    'Authorization': oauthString
  
)
.then(function(res) 
  return res.json();
)
.then(function(body) 
  var output = body;
  console.log(output);
  callback(null, output);
)
.catch(callback);

【讨论】:

奇怪...它返回消息:无法验证您的身份。代码 32,但 oauth 凭据对于已经工作的“喜欢”操作是相同的。可能是涉及这一行的东西:var signatureBaseString = 'POST&amp;https%3A%2F%2Fapi.twitter.com%2F1.1%2Ffavorites%2Fcreate.json&amp;' + encodeURIComponent(signatureParameterString); 它似乎是提供凭据的变量,与类似的请求捆绑在一起,但我不确定? @EladRatson 你是对的,这是身份验证方法的问题。 SignatureBaseStringSignatureParameterString 变量将被更改。我已经用正确的代码更新了我的答案。像往常一样,如果此答案解决了您的问题,请投票并将其标记为正确。 (info here)

以上是关于Zapier 代码 (JS) + Twitter API - POST statuses/retweet/:id的主要内容,如果未能解决你的问题,请参考以下文章

用于 Twitter HTML 的 Zapier Python 或 Javascript 代码

Zapier 查找 Twitter URL 提及

如何使用 Zapier 的 Twitter API 进行身份验证?

如何在 Zapier 代码中发布推文

如何将 RoamResearch 连接到 Zapier?

如何在“Zapier 代码”中编写节点获取(Rest-API)?