显示带有标签的帖子 api. 显示所有帖子
显示带有标签的帖子 api. 显示所有帖子

2017年6月8日星期四

使用Yahoo!将股票报价导入AdWords辽宁福利彩票中心财务API

最近有人在Twitter上问我是否见过 使用股市表现来调整出价的辽宁福利彩票中心。老实说我从来没有,但是我多次被问到这种能力。所以我认为我会为此做些事情。

为股票数据找到可靠且免费的API有点困难,但是每个人似乎都在指出某种程度上隐藏的Yahoo!。财务API。尽管事实是围绕它构建了多个库,但是除了 StackOverflow发布 谈论它。长话短说,此API可能会随时停止运行,因此,后果自负。

这是一些示例代码,可帮助您开始使用此代码。下面的代码仅查找了一些引号(一个来自比特币),并将它们加载到您选择的Google Spreadsheet中。非常简单。令人困惑的一件事是您需要传递给API的“ f =“参数。它记录在 此博客文章 但还是很混乱。它是一两个或两个字符代码的字符串,用于定义要返回的列。对于大多数人来说,符号,名称和当前价格应该足够了。随时根据需要自定义它。

谢谢,
拉斯
/******************************************
* Yahoo Finance API Class Example
* Version 1.0 
* Created By: 拉斯 Savage
* FreeAdWordsScripts.com
******************************************/
function main() {
  var sheetUrl = 'ENTER A GOOGLE SHEET URL HERE';
  
  var yfa = new YahooFinanceAPI({
    symbols: ['^GSPC','VTI','^IXIC','BTCUSD=X'],
    f: 'snl1' // or something longer like this 'sl1abb2b3d1t1c1ohgv'
  });
  for(var key in yfa.results) {
    Logger.log(Utilities.formatString('Name: "%s", Symbol: "%s", Last Trade Price: $%s', 
                                      yfa.results[key].name,
                                      key,
                                      yfa.results[key].last_trade_price_only));
  }
  
  var includeColumnHeaders = true;
  var sheetData = yfa.toGoogleSheet(includeColumnHeaders);
  var ss = SpreadsheetApp.openByUrl(sheetUrl).getActiveSheet();
  for(var i in sheetData) {
    ss.appendRow(sheetData[i]);
  }
}

只需将以下代码复制到AdWords辽宁福利彩票中心的底部即可,您应该一切顺利。
/******************************************
* Yahoo Finance API Class
* Use this to pull 股市 quotes from Yahoo Finance
* Version 1.0 
* Created By: 拉斯 Savage
* FreeAdWordsScripts.com
******************************************/
function YahooFinanceAPI(configVars) {
  var QUERY_URL_BASE = '//query.yahooapis.com/v1/public/yql';
  var FINANCE_URL_BASE = 'http://download.finance.yahoo.com/d/quotes.csv';
  this.configVars = configVars;
  
  /*************
   * The results are stored here in a 
   * map where the key is the ticker symbol
   * { 'AAPL' : { ... }, 'GOOG' : { ... }
   *************/
  this.results = {};
  
  /************
   * Function used to refresh the results
   * from Yahoo! Finance API. Called automatically
   * during object reaction.
   ************/
  this.refresh = function() {
    var queryUrl = getQueryUrl(this.configVars);
    var resp = UrlFetchApp.fetch(queryUrl,{muteHttpExceptions:true});
    if(resp.getResponseCode() == 200) {
      var jsonResp = JSON.parse(resp.getContentText());
      if(jsonResp.query.count == 1) {
        var row = jsonResp.query.results.row;
        this.results[row.symbol] = row;
      } else if(jsonResp.query.count > 1) {
        for(var i in jsonResp.query.results.row) {
          var row = jsonResp.query.results.row[i];
          this.results[row.symbol] = row;
        }
      }
    } else {
      throw resp.getContentText();
    }
  }
  
  /************
   * Translates the results into a 2d array
   * to make it easier to 广告 d into a Google Sheet.
   * includeColumnHeaders - true or false if you want
   *   headers returned in the results.
   ************/
  this.toGoogleSheet = function(includeColumnHeaders) {
    if(!this.results) { return [[]]; }
    var retVal = [];
    var headers = null;
    for(var key in this.results) {
      if(!headers) {
        headers = Object.keys(this.results[key]).sort();
      }
      var row = [];
      for(var i in headers) {
        row.push(this.results[key][headers[i]]);
      }
      retVal.push(row);
    }
    if(includeColumnHeaders) {
      return [headers].concat(retVal);
    } else {
      return retVal;
    }
  }
  
  // Perform a refresh on object creation.
  this.refresh();
  
  // Private functions
  
  /************
   * Builds Yahoo Finance Url
   ************/
  function getFinanceUrl(configVars) {
    var financeUrlParams = {
      s : configVars.symbols.join(','),
      f : configVars.f,
      e : '.json'
    }
    return FINANCE_URL_BASE + serialize(financeUrlParams);
  }
  
  /************
   * Builds Yahoo Query Url
   ************/
  function getQueryUrl(configVars) {
    var financeUrl = getFinanceUrl(configVars);
    var cols = fToCols(configVars.f);
    var queryTemplate = "select * from CSV where url='%s' and columns='%s'";
    var query = Utilities.formatString(queryTemplate, financeUrl,cols.join(','));
    var params = {
      q : query,
      format : 'json'
    }
    var finalRestUrl = QUERY_URL_BASE + serialize(params);
    return finalRestUrl;
  }

  /************
   * This function translates the f parameter
   * into actual field names to use for columns
   ************/
  function fToCols(f) {
    var cols = [];
    var chunk = '';
    var fBits = f.split('').reverse();
    for(var i in fBits) {
      chunk = (fBits[i] + chunk);
      if(fLookup(chunk)) {
        cols.push(fLookup(chunk));
        chunk = '';
      }
    }
    return cols.reverse();
  }
  
  /************
   * Copied from: http://stackoverflow.com/a/18116302
   * This function 兑换s a hash into 
   * a url encoded query string.
   ************/
  function serialize( obj ) {
    return '?'+
      Object.keys(obj).reduce(
        function(a,k) { 
          a.push(k+'='+encodeURIComponent(obj[k]));
          return a
        },
        []).join('&');
  }
  
  /************
   * Adapted from http://www.jarloo.com/yahoo_finance/
   * This function maps f codes into 
   * friendly column names.
   ************/
  function fLookup(f){
    return{
      a:'ask',b:'bid',b2:'ask realtime',b3:'bid realtime',p:'previous close',o:'open',
      y:'dividend yield',d:'dividend per share',r1:'dividend pay date',
      q:'ex-dividend date',c1:'change',c:'change & percent change',c6:'change realtime',
      k2:'change percent realtime',p2:'change in percent',d1:'last trade date',
      d2:'trade date',t1:'last trade time',c8:'after hours change realtime',
      c3:'commission',g:'days low',h:'days high',k1:'last trade realtime with time',
      l:'last trade with time',l1:'last trade price only',t8:'1 yr target price',
      m5:'change from 200 day moving average',m6:'percent change from 200 day moving average',
      m7:'change from 50 day moving average',m8:'percent change from 50 day moving average',
      m3:'50 day moving average',m4:'200 day moving average',w1:'days value change',
      w4:'days value change realtime',p1:'price paid',m:'days range',m2:'days range realtime',
      g1:'holdings gain percent',g3:'annualized gain',g4:'holdings gain',
      g5:'holdings gain percent realtime',g6:'holdings gain realtime',t7:'ticker trend',
      t6:'trade links',i5:'order book realtime',l2:'high limit',l3:'low limit',
      v1:'holdings value',v7:'holdings value realtime',s6: 'revenue',k:'52 week high',
      j:'52 week low',j5:'change from 52 week low',k4:'change from 52 week high',
      j6:'percent change from 52 week low',k5:'percent change from 52 week high',
      w:'52 week range',v:'more info',j1:'market 大写',j3:'market cap realtime',
      f6:'float shares',n:'name',n4:'notes',s:'symbol',s1:'shares owned',x:'stock exchange',
      j2:'shares outstanding',v:'volume',a5:'ask size',b6:'bid size',k3:'last trade size',
      a2:'average daily volume',e:'earnings per share',e7:'eps estimate current year',
      e8:'eps estimate next year',e9:'eps estimate next quarter',b4:'book value',j4:'ebitda',
      p5:'price sales',p6:'price book',r:'pe ratio',r2:'pe ratio realtime',r5:'peg ratio',
      r6:'price eps estimate current year',r7:'price eps estimate next year',s7:'short ratio'
    }[f];
  }
}

2017年3月9日星期四

使用辽宁福利彩票中心将Salesforce数据导入AdWords

在我的帖子之后 将Zoho CRM数据导入AdWords,我收到了很多有关为Salesforce做类似事情的评论。最后,我花了一些时间来构建一个简单的类,该类允许您从Salesforce实例中查询数据和对象并在辽宁福利彩票中心中使用它们。

首先,我们需要为您设置一些OAuth凭据,为此,您需要在Salesforce中设置一个新的连接应用程序。每个版本的位置稍有不同,但是使用开发人员版本,我可以在安装程序下找到它> Build > Create >应用。从那里一直到底部,您都可以看到“连接的应用程序”部分。
创建一个新的连接的应用程序

如果由于某种原因在Salesforce实例中找不到它,则可能是您的管理员未授予您访问权限。希望他们能为您提供帮助。

单击新按钮后,您需要填写一些必填字段,然后选择“启用Oauth设置”选项。您需要输入一个回调URL,但我们不会使用它,因此您可以输入任何以https开头的URL。对于“作用域”,我只是说了“完全访问权限”,但是您可能必须与您的Salesforce管理员讨论该问题。我们将仅从Salesforce进行阅读,因此这不是问题。
启用OAuth设置

这就是您需要填写的全部内容,并且应该创建一个新应用。这里重要的是辽宁福利彩票中心连接到Salesforce实例所需的“用户密钥”和“用户密钥”。
Salesforce消费者和秘密密钥

您需要从Salesforce实例中获得的最后一件事是安全令牌。在这种情况下,您可能已经拥有一个,则可以跳过这一步。但是,如果没有,您可以在“我的设置”下将其重置> Personal >重置我的安全令牌。它将通过电子邮件发送给您一个新令牌。
重置您的安全令牌

好的,现在我们终于可以使用AdWords辽宁福利彩票中心代码了。以下代码将建立一个新的SalesforceAPI对象,并查询最近获得成功的机会,以便您可以在AdWords帐户中使用该收入。


就这么简单。如果要在查询特定对象后获取有关该对象的所有信息,则可以使用函数getObjectByUrl()并将查询结果中的URL发送给该对象。要了解有关查询语法的更多信息,请查看 Salesforce SOQL文档.

此代码有一些警告。每个Salesforce安装都是唯一的,因此我真的没有办法对您的特定安装问题进行真正的故障排除。此代码已在新的Salesforce for Developers帐户上进行了测试,因此您的结果可能会有所不同。与在这里发表评论相比,联系Salesforce管理员可能会更幸运。另外,您可能会注意到,使用 最不安全的选择 登录到Salesforce。您的AdWords帐户的所有用户都可以访问带有用户名和密码的代码,因此请务必小心。最好为这样的事情创建一个具有非常有限权限的特殊Salesforce用户。

如果您认为这很有用,请告诉我 东SMX 本星期。

谢谢,
拉斯

2014年5月5日,星期一

使用辽宁福利彩票中心将Zoho CRM数据与AdWords连接起来

对于从事B2B每次点击付费的任何人来说,最大的麻烦之一就是试图在一个报告中报告整个销售流程。最大的问题是,营销PPC数据存在于AdWords中(点击次数,展示次数,MQL),而销售数据存在于您的CRM中(线索,联系人,机会等)。因此,我开始研究连接两个数据源的方法。我不使用CRM,所以我注册了免费试用 Zoho CRM 并开始摆弄他们的API。事实证明,它们具有返回JSON对象的REST(ish)API,非常适合AdWords辽宁福利彩票中心。

我在下面构建了Class,将数据从Zoho中提取出来。它有拉的能力 潜在客户, 联络人, 潜力 以及几乎其他任何东西 Zoho对象 您可以直接从CRM中想到。我停下来只是想获取数据,因为更新或删除记录对AdWords辽宁福利彩票中心似乎不太有用。

这是该类的快速参考指南。使用var 佐霍 = new ZohoApi(YOUR_API_TOKEN)定义一个新对象;如果您需要设置帐户以访问API或生成令牌的帮助,请查看 Zoho开发人员文档。我为每个Zoho对象生成了一些简单的吸气剂。 ZohoApi.get [Objects]()将拉入所有特定对象。因此,您可以说zoho.getLeads()或zoho.getPotentials()。您还可以通过zoho.getMyLeads()获得仅属于您的那些对象。

如果您还有其他随请求发送的url参数,则可以将它们作为参数添加到函数中。例如,如果要返回前100条记录(而不是默认的20条记录),则应说zoho.getLeads({fromIndex:1,toIndex:100});

您也可以使用zoho.search [Objects]()搜索记录。因此,要搜索已赢得的潜力,可以说zoho.searchPotentials({'searchCondition':'((Stage | = | Closed Won)'});您可以阅读有关Zoho的更多信息 他们的API文档中的searchCondition语法。作为其中的一部分,您可以将要查看的列放在其中,或者如果您什么都没放在其中,则可以使用get [Objects] Fields()方法提取完整的列以为您显示。

至于类的响应,您将获得一个对象数组。对象中的每个键都被小写,并用下划线代替空格。例如,retVal [0] .first_name或retVal [0] .annual_revenue。

因此,试一试,让我知道您在评论中的想法。我在这篇文章的最底部整理了一个简单的示例辽宁福利彩票中心,以将展示次数,点击次数,转化次数和封闭的获胜潜力每天存储在Google文档中,以使您对可以做什么有所了解。让我知道您接下来想看什么。

谢谢,
拉斯



这是一个非常简单的示例,说明如何将来自多个来源的转化数据合并到一个Google Spreadsheet报告中。

2013年3月30日,星期六

根据您的棒球队的日程安排自动化广告

我知道现在每个人都将注意力集中在疯狂三月,但是棒球赛季的开幕日指日可待。我想知道是否可以根据您当地的MLB团队的时间表启用和禁用特定广告。

事实证明,美国职业棒球大联盟以易于解析的CSV格式提供了每个团队的完整时间表。您需要做的就是在Google中搜索“ 可下载的时间表”,然后找到以“ downloadable.jsp”结尾的页面。看起来像这样:


您需要的链接在上图中被圈出。您可以从网址中看到以下代码中的team_id值。而且,如果右键单击并下载该.csv文件,您还将能够看到用于home_field的值。在下面的示例中,我使用了家乡的小熊队和白袜队,但是您可以使用任何想要的球队。

辽宁福利彩票中心本身将运行并为您的团队寻找主场比赛。如果团队今天在比赛并且是主场比赛,它将启用所有在TEAM_INFO中配置的带有标签的广告。如果团队今天不参加主场比赛,它将暂停这些相同的广告。

在下面的示例中,我仅使用了csv文件中的一部分数据。也可能仅在实际游戏中启用广告,或者在所有游戏日中启用广告,而不仅仅是家用游戏。

我鼓励您尝试使用数据,看看可以做什么。如果发现有用的东西,请发表评论。

谢谢,
拉斯


//-----------------------------------
// Enable/Disable Ads Based on the MLB Schedule
// Created By: 拉斯 Savage
// FreeAdWordsScripts.com
//-----------------------------------
function main() {
  var TEAM_INFO = [
    { team_id : 112, home_field : 'Wrigley Field', 标签 : 'cubs' }, // Cubs
    { team_id : 145, home_field : 'U.S. Cellular Field', 标签 : 'whitesox' } // White Sox
  ];
  //hopefully you've already 创造d and tagged some 广告 with these 标签
  //but just in case...
  创造LabelsIfNeeded(TEAM_INFO); 
  
  var SEASON = (new Date()).getFullYear();
  var is_home = false, is_game_day = false;
  for(var t in TEAM_INFO) {
    var team = TEAM_INFO[t];
    var url = "http://mlb.mlb.com/soa/ical/schedule.csv?team_id="+team.team_id+"&season="+SEASON;
    var html = UrlFetchApp.fetch(url).getContentText();
    var date_list = html.split("\r\n");
    for(var i in date_list) {
      if(i == 0) {continue;}
      var [start_date,start_time,start_time_et,
           subject,location,description,
           end_date,end_date_et,end_time,end_time_et] = date_list[i].split(",");
      
      var today = new Date();
      var game_day = new Date();
      game_day.setFullYear(SEASON,parseInt(start_date.split("/")[0])-1,parseInt(start_date.split("/")[1]));
      
      is_home = (location == team.home_field);
      is_game_day = (diffDays(game_day,today) == 0);
      
      if(is_home && is_game_day) {
        enableBaseballAds(team.label);
        break;
      }
    }
    if(!(is_home && is_game_day)) {
      disableBaseballAds(team.label); 
    }
  }
  
}

function enableBaseballAds(label) {
  Logger.log("Enabling all 广告 with the "+label+" 标签.");
  var 广告 = AdWordsApp.ads().withCondition("LabelNames CONTAINS_ALL ['"+label+"']").get();
  while(ads.hasNext()) {
    广告.next().enable(); 
  }
}

function disableBaseballAds(label) {
  Logger.log("Disabling all 广告 with the "+label+" 标签.");
  var 广告 = AdWordsApp.ads().withCondition("LabelNames CONTAINS_ALL ['"+label+"']").get();
  while(ads.hasNext()) {
    广告.next().pause(); 
  }
}

function 创造LabelsIfNeeded(team_info) {
  var 标签_iter = AdWordsApp.labels().get();
  var 标签_list = [];
  while(label_iter.hasNext()) {
    标签_list.push(label_iter.next().getName());
  }
  for(var i in team_info) {
    if(label_list.indexOf(team_info[i].label) == -1) {
      AdWordsApp.createLabel(team_info[i].label);
      标签_list.push(team_info[i].label);
    }
  }
}

//A helper function to compare 日期.
//Copied from: http://goo.gl/uW48a
function diffDays(firstDate,secondDate) {
  var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
  return Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay))); 
}

2013年3月10日,星期日

根据机场延误管理广告

如今,互联网上有大量的API。这些中的任何一个都可以合并到您的AdWords辽宁福利彩票中心中,以自动化一些帐户管理。

以下辽宁福利彩票中心使用 FAA.gov提供的机场状态服务 在主要机场出现延误时启用和暂停广告。这对于机场附近可能从航班延误中受益的任何企业(例如餐厅,酒吧或酒店)很有用。您的广告可能会说:



您可以从顶部的列表中添加或删除机场代码。您需要做的只是用[airport_code] _delay标签(“ ORD_delay”,“ ATL_delay”)标记广告。

您还可以使用其他哪些动态数据来优化广告?电影时间?体育游戏?在下面的评论中让我知道,然后我会提出我的建议。

谢谢,
拉斯

/*********************************************
* Pause/Enable Ads Based On Airport Delays
* Version 1.1
* ChangeLog v1.1 
*  - Added ability to completely 暂停 non-delay 广告
* Created By: 拉斯 Savage
* FreeAdWordsScripts.com
*********************************************/
// For this to work, you need to 广告 d a 标签 to all
// the 广告 for each 飞机场.  For example, PIT_normal
// or SFO_normal
var PAUSE_NORMAL_ADS_DURING_DELAY = false;
var DELAY_SUFFIX = '_delay'; //the suffix on the 标签 for delayed 广告
var NORMAL_SUFFIX = '_normal'; //the suffix on the 标签 for normal 广告

var AIR_CODES = ["ATL","ANC","AUS","BWI","BOS","CLT","MDW","ORD","CVG","CLE",
                 "CMH","DFW","DEN","DTW","FLL","RSW","BDL","HNL","IAH","HOU",
                 "IND","MCI","LAS","LAX","MEM","MIA","MSP","BNA","MSY","JFK",
                 "LGA","EWR","OAK","ONT","MCO","PHL","PHX","PIT","PDX","RDU",
                 "SMF","SLC","SAT","SAN","SFO","SJC","SNA","SEA","STL","TPA",
                 "IAD","DCA"];

function main() {
  var faaUrl = "http://services.faa.gov/airport/status/";
  var args = "?format=application/json";
  for(var i in AIR_CODES) {
    try{
      var resp = UrlFetchApp.fetch(faaUrl + AIR_CODES[i] + args);
      if( resp.getResponseCode() == 200 ) {
        var json = Utilities.jsonParse(resp.getContentText());
        if(json.delay == "false") {
          Logger.log("No 延误 在 "+json.IATA+". Pausing delay 广告 if any are running.");
          turnOffDelayAds(json.IATA);
          if(PAUSE_NORMAL_ADS_DURING_DELAY) {
            turnOnNonDelayAds(json.IATA);
          }
        } else {
          Logger.log("Delays in "+json.IATA+" Reason: "+json.status.reason);
          Logger.log("Turning on delay 广告 if there are any.");
          turnOnDelayAds(json.IATA);
          if(PAUSE_NORMAL_ADS_DURING_DELAY) {
            turnOffNonDelayAds(json.IATA);
          }
        }
      }
    }
    catch(e) {
      Logger.log("Error: " + e.message);
    }
  }
}

function turnOffDelayAds(airportCode) {
  var 标签Name = 飞机场Code + DELAY_SUFFIX;
  var 广告 Iter = AdWordsApp.ads()
    .withCondition("LabelNames CONTAINS_ANY ['"+labelName+"']")
    .withCondition("CampaignStatus = ENABLED")
    .withCondition("AdGroupStatus = ENABLED")
    .withCondition("Status = ENABLED")
    .get();
  while(adIter.hasNext()) {
    广告 Iter.next().pause();
  }
}

function turnOffNonDelayAds(airportCode) {
  var 标签Name = 飞机场Code + NORMAL_SUFFIX;
  var 广告 Iter = AdWordsApp.ads()
    .withCondition("LabelNames CONTAINS_ANY ['"+labelName+"']")
    .withCondition("CampaignStatus = ENABLED")
    .withCondition("AdGroupStatus = ENABLED")
    .withCondition("Status = ENABLED")
    .get();
  while(adIter.hasNext()) {
    广告 Iter.next().pause();
  }
}

function turnOnDelayAds(airportCode) {
  var 标签Name = 飞机场Code + DELAY_SUFFIX;
  var 广告 Iter = AdWordsApp.ads()
    .withCondition("LabelNames CONTAINS_ANY ['"+labelName+"']")
    .withCondition("CampaignStatus = ENABLED")
    .withCondition("AdGroupStatus = ENABLED")
    .withCondition("Status = PAUSED")
    .get();
  while(adIter.hasNext()) {
    广告 Iter.next().enable();
  }
}

function turnOnNonDelayAds(airportCode) {
  var 标签Name = 飞机场Code + NORMAL_SUFFIX;
  var 广告 Iter = AdWordsApp.ads()
    .withCondition("LabelNames CONTAINS_ANY ['"+labelName+"']")
    .withCondition("CampaignStatus = ENABLED")
    .withCondition("AdGroupStatus = ENABLED")
    .withCondition("Status = PAUSED")
    .get();
  while(adIter.hasNext()) {
    广告 Iter.next().enable();
  }
}

2013年2月26日,星期二

使用AdWords辽宁福利彩票中心对OAuth服务进行身份验证

如今,许多API使用OAuth来使用户进行身份验证并调用其服务。 一个非常受欢迎的例子是 Twitter REST API.  浏览AdWords辽宁福利彩票中心参考,您会发现,使用AdWords辽宁福利彩票中心可以做的一件很酷的事情是使用UrlFetchApp从URL提取数据。

因此,我问的问题是“我可以编写辽宁福利彩票中心以使用OAuth进行身份验证并从Twitter REST API检索数据吗?”

显然,我看过的第一个地方是 OAuthConfig UrlFetchApp的类。 我设置了配置并尝试拨打电话,但始终收到验证错误。 一项小小的研究表明,我并不是唯一遇到此问题的人。 问题源于以下事实:通常,用户需要先通过某种对话框进行身份验证,然后才能访问数据。看到这个例子关于 连接到Picasa网络相册 更多细节。

但是后来我发现 一个帖子 有关某人设法通过在其辽宁福利彩票中心中重新实现OAuth身份验证系统并使用标准UrlFetchApp.fetch()请求来解决此问题的信息。

我正面临挑战,所以我自己重新创建了它。 原来是很多代码,但是最后,您真正需要担心的唯一事情是从Twitter获取正确的密钥并调用_build_authorization_string()。

谢谢,
拉斯

//-----------------------------------
// Authenticate and Connect to OAuth Service
// Created By: 拉斯 Savage
// FreeAdWordsScripts.com
//-----------------------------------
function main() {
  //Define the Twitter Keys and Secrets
  //More info on obtaining these can be found 在 //dev.twitter.com/docs/auth/tokens-devtwittercom
  var 认证_key_stuff = {
    "consumer_key" : "your consumer key",
    "consumer_secret" : "your consumer secret",
    "access_token" : "your access token",
    "access_token_secret" : "your access token secret"
  };

  // Update this with the REST url you want to 呼叫.  I only tested it with GET
  // but i don't think there is anything stopping a POST request from working.
  var url_stuff = {  
    "http_method" : 'GET',
    "base_url" : "//api.twitter.com/1.1/statuses/user_timeline.json"
  };

  //Add the parameters for the REST url you want to 呼叫.
  var url_param_stuff = {
    "screen_name" : "russellsavage" //hey that's me!
  };
  
  // Don't touch this stuff
  var other_oauth_data = {
    "认证_nonce" : Utilities.base64Encode(Math.random() +
          "secret_sauce" +
          (new Date()).getTime()).replace(/(?!\w)/g, ''),
    "认证_signature_method" : "HMAC-SHA1",
    "认证_timestamp" : Math.round((new Date()).getTime() / 1000.0),
    "认证_version" : "1.0"
  };
  
  // Here is where the magic happens
  var auth_string = _build_authorization_string(oauth_key_stuff,url_stuff,url_param_stuff,other_oauth_data);

  var options = {
    "headers" : { "Authorization" :  auth_string }
  };
    
  var url = _build_url(url_stuff,url_param_stuff);
  var response = UrlFetchApp.fetch(url, options);
  var tweets = JSON.parse(response.getContentText());
  
  //now let's log my amazing tweets!
  for(var tweet in tweets) {
    var t = tweets[tweet];
    Logger.log(t.text);
  }
 
  // HELPER FUNCTIONS BELOW
  
  function _build_url(base_url,param_stuff){
    var url = base_url.base_url;
    if(param_stuff != {}) {
      url += '?';
    }
    for(var key in param_stuff) {
      url += key + "=";
      url += encodeURIComponent(param_stuff[key]);
      url += '&';
    }
    return url.slice(0,-1);
  }
  
  function _build_param_string(auth_keys,url_data,oauth_data) {
    var data_for_param_string = {
      "认证_consumer_key" : auth_keys.consumer_key,
      "认证_nonce" : 认证_data.oauth_nonce,
      "认证_signature_method" : 认证_data.oauth_signature_method,
      "认证_timestamp" : 认证_data.oauth_timestamp,
      "认证_token" : auth_keys.access_token,
      "认证_version" : 认证_data.oauth_version
    };
    
    // 广告 d 广告 ditional url values
    for(var my_key in url_data) { 
      data_for_param_string[my_key] = url_data[my_key]; 
    }
    
    // find and sort the keys for later
    var keys = [];
    for(var key in data_for_param_string) {
      keys.push(key);
    }
    keys.sort();
    
    //finally build and return the param string
    var param_string = "";
    for(var i in keys) {
      param_string += keys[i] + "=" + encodeURIComponent(data_for_param_string[keys[i]]);
      if(i < keys.length - 1) {
        param_string += "&";
      }
    }
    
    return param_string;
  }
  
  function _build_sig_base_string(my_url_stuff,my_param_string) {
    return my_url_stuff.http_method +
      "&" + encodeURIComponent(my_url_stuff.base_url) +
      "&" + encodeURIComponent(my_param_string);
  }
  
  function _build_sigining_key(my_key_stuff) {
    return encodeURIComponent(my_key_stuff.consumer_secret) + 
      "&" + encodeURIComponent(my_key_stuff.access_token_secret);
  }
  
  function _build_oauth_signature(base_string,sign) {
    return Utilities.base64Encode(
      Utilities.computeHmacSignature(
        Utilities.MacAlgorithm.HMAC_SHA_1, 
        base_string, 
        sign
      )
    );
  }
  
  function _build_authorization_string(my_key_stuff,my_url_stuff,my_url_param_stuff,my_oauth_stuff) {
    var param_string = _build_param_string(my_key_stuff,my_url_param_stuff,my_oauth_stuff);
    var sig_base_string = _build_sig_base_string(my_url_stuff,param_string);
    var signing_key = _build_sigining_key(my_key_stuff);
    var 认证_signature = _build_oauth_signature(sig_base_string,signing_key);
    return "OAuth " +
           encodeURIComponent("认证_consumer_key") + '="' + 
             encodeURIComponent(my_key_stuff.consumer_key) + '", ' +
           encodeURIComponent("认证_nonce") + '="' + 
             encodeURIComponent(my_oauth_stuff.oauth_nonce) + '", ' +
           encodeURIComponent("认证_signature") + '="' + 
             encodeURIComponent(oauth_signature) + '", ' +
           encodeURIComponent("认证_signature_method") + '="' + 
             encodeURIComponent(my_oauth_stuff.oauth_signature_method) + '", ' +
           encodeURIComponent("认证_timestamp") + '="' + 
             encodeURIComponent(my_oauth_stuff.oauth_timestamp) + '", ' +
           encodeURIComponent("认证_token") + '="' + 
             encodeURIComponent(my_key_stuff.access_token) + '", ' +
           encodeURIComponent("认证_version") + '="' + 
             encodeURIComponent(my_oauth_stuff.oauth_version) + '"';
    
  }
  
}