Google apps script 如何使用OAuth2库从Google应用程序脚本发送推文?

Google apps script 如何使用OAuth2库从Google应用程序脚本发送推文?,google-apps-script,twitter,oauth-2.0,twitter-oauth,bearer-token,Google Apps Script,Twitter,Oauth 2.0,Twitter Oauth,Bearer Token,我已经成功地使用OAuth1为tweet制作了GAS。众所周知,OAuth1气体库已被弃用,所以我正尝试迁移到OAuth2库 我看到了一些变化,但是我没有得到正确的方式来授权我的请求 我现在的主要问题是: OAuth2中的承载令牌替换为OAuth1中的密钥和访问令牌 我不需要密钥和访问权限来授权rquest?我是基于谷歌开发者网站本身的例子 为了更清楚,我把从谷歌开发者网站上摘录的代码放在了我的道具上: // Call this function just once, to initiali

我已经成功地使用OAuth1为tweet制作了GAS。众所周知,OAuth1气体库已被弃用,所以我正尝试迁移到OAuth2库

我看到了一些变化,但是我没有得到正确的方式来授权我的请求

我现在的主要问题是:

  • OAuth2中的承载令牌替换为OAuth1中的密钥和访问令牌
  • 我不需要密钥和访问权限来授权rquest?我是基于谷歌开发者网站本身的例子
为了更清楚,我把从谷歌开发者网站上摘录的代码放在了我的道具上:

// Call this function just once, to initialize the OAuth client.
function initializeOAuthClient() {
  if (typeof OAuth2 === 'undefined') {
    var libUrl = 'https://developers.google.com/google-ads/scripts/docs/examples/oauth20-library';
    throw Error('OAuth2 library not found. Please take a copy of the OAuth2 ' +
        'library from ' + libUrl + ' and append to the bottom of this script.');
  }
  var tokenUrl = 'https://api.twitter.com/oauth2/token';
  authUrlFetch = OAuth2.withClientCredentials(
      tokenUrl, CONSUMER_KEY, CONSUMER_SECRET);
}

function sendTweet(status) {
  var service = accessProtectedResource(SERVICE_UPDATE_URL, "post");
  
  if (service.hasAccess()) {
    var url = 'https://api.twitter.com/1.1/statuses/update.json?include_entities=true&status=' + percentEncode(status);
    var response = service.fetch(url);
    //var result = JSON.parse(response.getContentText());
    
    return response;
  }
}


/**
 * Attempts to access a non-Google API using a constructed service
 * object.
 *
 * If your add-on needs access to non-Google APIs that require OAuth,
 * you need to implement this method. You can use the OAuth1 and
 * OAuth2 Apps Script libraries to help implement it.
 *
 * @param {String} url         The URL to access.
 * @param {String} method_opt  The HTTP method. Defaults to GET.
 * @param {Object} headers_opt The HTTP headers. Defaults to an empty
 *                             object. The Authorization field is added
 *                             to the headers in this method.
 * @return {HttpResponse} the result from the UrlFetchApp.fetch() call.
 */
function accessProtectedResource(url, method_opt, headers_opt) {
  var service = getOAuthService();
  var maybeAuthorized = service.hasAccess();
  if (maybeAuthorized) {
    // A token is present, but it may be expired or invalid. Make a
    // request and check the response code to be sure.

    // Make the UrlFetch request and return the result.
    var accessToken = service.getAccessToken();
    var method = method_opt || 'post';
    var headers = headers_opt || {};
    headers['Authorization'] =
        Utilities.formatString('Bearer %s', accessToken);
    var resp = UrlFetchApp.fetch(url, {
      'headers': headers,
      'method' : method,
      'muteHttpExceptions': true, // Prevents thrown HTTP exceptions.
    });

    var code = resp.getResponseCode();
    if (code >= 200 && code < 300) {
      return resp.getContentText("utf-8"); // Success
    } else if (code == 401 || code == 403) {
       // Not fully authorized for this action.
       maybeAuthorized = false;
    } else {
       // Handle other response codes by logging them and throwing an
       // exception.
       console.error("Backend server error (%s): %s", code.toString(),
                     resp.getContentText("utf-8"));
       throw ("Backend server error: " + code);
    }
  }

  if (!maybeAuthorized) {
    // Invoke the authorization flow using the default authorization
    // prompt card.
    CardService.newAuthorizationException()
        .setAuthorizationUrl(service.getAuthorizationUrl())
        .setResourceDisplayName("Display name to show to the user")
        .throwException();
  }
}

/**
 * Create a new OAuth service to facilitate accessing an API.
 * This example assumes there is a single service that the add-on needs to
 * access. Its name is used when persisting the authorized token, so ensure
 * it is unique within the scope of the property store. You must set the
 * client secret and client ID, which are obtained when registering your
 * add-on with the API.
 *
 * See the Apps Script OAuth2 Library documentation for more
 * information:
 *   https://github.com/googlesamples/apps-script-oauth2#1-create-the-oauth2-service
 *
 *  @return A configured OAuth2 service object.
 */
function getOAuthService() {
  
  return OAuth2.createService('SERVICE_NAME')
      .setAuthorizationBaseUrl('SERVICE_AUTH_URL')
      .setTokenUrl('SERVICE_AUTH_TOKEN_URL')
      .setClientId('CLIENT_ID')
      .setClientSecret('CLIENT_SECRET')
      .setScope('SERVICE_SCOPE_REQUESTS')
      .setCallbackFunction('authCallback')
      .setCache(CacheService.getUserCache())
      .setPropertyStore(PropertiesService.getScriptProperties())
}

/**
 * Boilerplate code to determine if a request is authorized and returns
 * a corresponding HTML message. When the user completes the OAuth2 flow
 * on the service provider's website, this function is invoked from the
 * service. In order for authorization to succeed you must make sure that
 * the service knows how to call this function by setting the correct
 * redirect URL.
 *
 * The redirect URL to enter is:
 * https://script.google.com/macros/d/<Apps Script ID>/usercallback
 *
 * See the Apps Script OAuth2 Library documentation for more
 * information:
 *   https://github.com/googlesamples/apps-script-oauth2#1-create-the-oauth2-service
 *
 *  @param {Object} callbackRequest The request data received from the
 *                  callback function. Pass it to the service's
 *                  handleCallback() method to complete the
 *                  authorization process.
 *  @return {HtmlOutput} a success or denied HTML message to display to
 *          the user. Also sets a timer to close the window
 *          automatically.
 */
function authCallback(callbackRequest) {
  var authorized = getOAuthService().handleCallback(callbackRequest);
  if (authorized) {
    return HtmlService.createHtmlOutput(
      'Success! <script>setTimeout(function() { top.window.close() }, 1);</script>');
  } else {
    return HtmlService.createHtmlOutput('Denied');
  }
}

/**
 * Unauthorizes the non-Google service. This is useful for OAuth
 * development/testing.  Run this method (Run > resetOAuth in the script
 * editor) to reset OAuth to re-prompt the user for OAuth.
 */
function resetOAuth() {
  getOAuthService().reset();
}

function main() {
  try {
      let result = sendTweet("Este va a ser un gran día!\n https://www.instagram.com/amos_oficialba/");
      Logger.log("Resultado: " + result);
  }
  catch(err) {
    console.log(err["stack"]);
  }
}
//只调用此函数一次,以初始化OAuth客户端。
函数initializeAuthClient(){
如果(OAuth2的类型==='undefined'){
var libUrl='1〕https://developers.google.com/google-ads/scripts/docs/examples/oauth20-library';
抛出错误('未找到OAuth2库。请复制OAuth2'+
'库从'+libUrl+'添加到此脚本底部');
}
var-tokenUrl=https://api.twitter.com/oauth2/token';
authUrlFetch=OAuth2.withClientCredentials(
令牌URL、消费者密钥、消费者密钥);
}
函数sendTweet(状态){
var service=accessProtectedResource(服务更新URL,“post”);
if(service.hasAccess()){
var url='1〕https://api.twitter.com/1.1/statuses/update.json?include_entities=true&status=“+百分比编码(状态);
var response=service.fetch(url);
//var result=JSON.parse(response.getContentText());
返回响应;
}
}
/**
*尝试使用构造的服务访问非Google API
*反对。
*
*如果您的插件需要访问需要OAuth的非Google API,
*您需要实现这个方法。您可以使用OAuth1和
*OAuth2应用程序脚本库来帮助实现它。
*
*@param{String}url要访问的url。
*@param{String}方法\u选择HTTP方法。默认设置为获取。
*@param{Object}头\u选择HTTP头。默认为空
*反对。将添加“授权”字段
*此方法中的标题。
*@return{HttpResponse}UrlFetchApp.fetch()调用的结果。
*/
函数accessProtectedResource(url、方法、标题){
var service=getOAuthService();
var maybeAuthorized=service.hasAccess();
如果(可授权){
//令牌存在,但可能已过期或无效。请创建一个令牌
//请求并检查响应代码以确保。
//发出UrlFetch请求并返回结果。
var accessToken=service.getAccessToken();
var方法=方法|opt||'post';
var headers=headers_opt | |{};
标题[“授权”]=
formatString('承载%s',accessToken);
var resp=UrlFetchApp.fetch(url{
“头”:头,
“方法”:方法,
“muteHttpExceptions”:true,//防止引发HTTP异常。
});
var code=resp.getResponseCode();
如果(代码>=200&&code<300){
return resp.getContentText(“utf-8”);//成功
}else if(代码==401 | |代码==403){
//未完全授权执行此操作。
maybeAuthorized=错误;
}否则{
//通过记录其他响应代码并抛出
//例外。
console.error(“后端服务器错误(%s):%s”),代码.toString(),
分别为getContentText(“utf-8”);
抛出(“后端服务器错误:+代码”);
}
}
如果(!可能被授权){
//使用默认授权调用授权流
//提示卡。
CardService.newAuthorizationException()
.setAuthorizationUrl(service.getAuthorizationUrl())
.setResourceDisplayName(“显示给用户的显示名称”)
.ThroweException();
}
}
/**
*创建新的OAuth服务以方便访问API。
*本例假设插件需要提供一个服务
*进入。在持久化授权令牌时使用其名称,因此请确保
*它在属性存储的范围内是唯一的。你必须设置
*客户机密和客户ID,在注册您的
*带有API的附加组件。
*
*有关更多信息,请参阅应用程序脚本OAuth2库文档
*资料:
*   https://github.com/googlesamples/apps-script-oauth2#1-创建-the-oauth2-service
*
*@返回已配置的OAuth2服务对象。
*/
函数getOAuthService(){
返回OAuth2.createService('SERVICE_NAME')
.setAuthorizationBaseUrl('SERVICE\u AUTH\u URL'))
.setTokenUrl('SERVICE\u AUTH\u TOKEN\u URL')
.setClientId('CLIENT_ID'))
.setClientSecret('CLIENT_SECRET')
.setScope(“服务范围请求”)
.setCallbackFunction('authCallback')
.setCache(CacheService.getUserCache())
.setPropertyStore(PropertiesService.getScriptProperties())
}
/**
*确定请求是否被授权并返回的样板代码
*对应的HTML消息。当用户完成OAuth2流时
*在服务提供商的网站上,从
*服务。为了使授权成功,您必须确保
*服务知道如何通过设置正确的
*重定向URL。
*
*要输入的重定向URL为:
* https://script.google.com/macros/d//usercallback
*
*有关更多信息,请参阅应用程序脚本OAuth2库文档
*资料:
*   https://github.com/googlesamples/apps-script-oauth2#1-创建-the-oauth2-service
*
*@param{Object}callbackRequest从
*回调函数。将其传递给服务中心
*handleCallback()方法来完成
*授权过程。
*@return{HtmlOutput}要显示的成功或被拒绝的HTML消息
*用户。还设置计时器以关闭窗口
*自动地。
*/
函数authCallback(callbackRequest){
弗吉尼亚州