読者です 読者をやめる 読者になる 読者になる

技術のメモ帳

気が向いたときに書いてます

[GAS]SpreadSheetで短縮URLを出力する関数(goo.gl編)

Google Apps Script

SpreadSheetで指定したセルの文字列(URL)の、短縮URLを出力するGoogle Apps Scriptの関数です。

SpreadSheetを新規作成し、[ツール]→[スクリプトエディタ]から、エディタを起動します。

エディタ起動後、次の関数を入力し、保存します。

function shortenUrl(longUrl) {
  var regexp = /^(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)$/;
  if (typeof longUrl != 'string' || !regexp.test(longUrl)) return null;
  try {
    return UrlShortener.Url.insert({ longUrl: longUrl }).id;
  } catch(e) {
    return e.toString();
  }
}

実行前に、UrlShorterは拡張サービスのため、[リソース]→[ライブラリ]から、有効化する必要があります。

併せて、Google デベロッパーコンソールからもAPIを有効化します。

動作確認(問題発生)

SpreadSheetから関数を実行すると、次の例外が出力されます。

Exception: Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.

スクリプトエディター上からは、問題がなかったのですが、どういうことか調べてみると、SpreadSheetから利用する自作関数の場合、利用できるサービスに制限があるとのこと。

具体的には、以下のリンク先で表示されているものだけが利用できるみたいです。

Custom Functions in Google Sheets | Apps Script | Google Developers

対策

UrlFetchAppは利用できるので、UrlShortenerのAPIから取得するのが正解なようです。

なお、事前にデベロッパーコンソールよりAPIキーを取得し、スクリプトプロパティにGOOGLE_API_KEYとして保存しておきます。

最終的なコードは、次のようになりました。

/**
 * Returns a shortened URL of the input.
 *
 * @param {string} longUrl The long URL to shorten.
 * @return The shortened url.
 */
function shortenUrl(longUrl) {
  var regexp = /^(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)$/;
  if (typeof longUrl != 'string' || !regexp.test(longUrl)) return null;

  try {
    var response = UrlShortenerService(longUrl);
    return response.id;
  } catch(e) {
    return e.toString();
  }
}

/**
 * Returns a analytics of the short URL.
 *
 * @param {string} shortUrl
 * @param {string} period : allTime, month, week, day and more
 * @param {string} kind   : shortUrlClicks, longUrlClicks
 * @return click count
 */
function analyzeShortUrl(shortUrl, period, kind) {
  var regexp = /^https?:\/\/goo.gl\/.+$/;
  if (typeof shortUrl != 'string' || !regexp.test(shortUrl)) return null;

  try {
    var response = UrlAnalyticsService(shortUrl);
    return response.analytics[period][kind].toString();
  } catch(e) {
    return e.toString();
  }
}

function UrlShortenerService(longUrl) {
  var apiKey  = PropertiesService.getScriptProperties().getProperty('GOOGLE_API_KEY'),
      apiUrl  = 'https://www.googleapis.com/urlshortener/v1/url?key='+apiKey,
      payload = { longUrl: longUrl },
      options = {
        method: 'POST',
        contentType: 'application/json',
        payload: JSON.stringify(payload),
        muteHttpExceptions: true
      },
      response = UrlFetchApp.fetch(apiUrl, options);
  if (response.getResponseCode() !== 200) {
    throw new Error('Unable to UrlShortenerAPI');
  } else {
    return JSON.parse(response);
  }
}

function UrlAnalyticsService(shortUrl) {
  var apiKey   = PropertiesService.getScriptProperties().getProperty('GOOGLE_API_KEY'),
      apiUrl   = 'https://www.googleapis.com/urlshortener/v1/url?shortUrl='+shortUrl+'&projection=ANALYTICS_CLICKS&key='+apiKey,
      response = UrlFetchApp.fetch(apiUrl);
  if (response.getResponseCode() !== 200) {
    throw new Error('Unable to UrlShortenerAPI');
  } else {
    return JSON.parse(response);
  }
}

ついでに、クリック回数を取得する関数 analyzeShortUrl も書いてみました。

動作確認

問題なく動作しました。

キャンペーン関連やSNSでのPR等で発行したURLの状況を調べるのに便利そうですね。

追記(2015.9.25)

bit.lyの場合の実装サンプルも作成しました。

参考リンク