GoogleのURL短縮サービスが終了する(2019/3/30まで)そうで、Firebaseで代用するのが妥当なようです。
Webページから作成できるように、短縮URL作成用のページをさくっと作ってみましょう。
ダイナミックリンクドメインの作成
まずは、Firebaseコンソールから、自分用にダイナミックリンクドメインを作成します。
下記のような感じで、XXXXにサブドメイン名を割り当ててもらいます。
短縮URLはこのドメイン名をベースに生成されます。
Firebaseコンソールを開きます。
https://console.firebase.google.com/
いづれかのプロジェクトを選択します。作成していない場合は、プロジェクトを追加 を選択して作成します。
次に、左側のナビゲーションから、拡大 → Dynamic Links を選択します。
ドメインの追加 を選択します。(初めてここに来た方は、始めるボタンを押下すると、ドメインの追加が始まるはず)
ここで、好きな名前のサブドメイン名を指定します。せっかく短縮URLなので、なるべく短い方がよいかと思います。
次に、左側ナビゲーションの、Project Overviewの右側の歯車のマークを選択します。そうすると、ウェブAPIキーが表示されていますので、それをメモしておきます。
RESTfulサーバを立ち上げる
RESTful化します。
なぜ、RESTfulサーバを挟むか、API Keyがばれないように、です。
いつもながら、以下を参考にしてください。
SwaggerでRESTful環境を構築する
Swagger定義ファイルの該当部分の抜粋です。
paths:
/urlshorter:
post:
x-swagger-router-controller: routing
operationId: urlshorter
parameters:
- in: body
name: UrlShorter
required: true
schema:
$ref: '#/definitions/UrlShorterRequest'
responses:
200:
description: Success
schema:
type: object
definitions:
UrlShorterRequest:
type: object
required:
- targetUrl
properties:
targetUrl:
type: string
以下が、実装部分です。
var fetch = require('node-fetch');
const Response = require('../../helpers/response');
const FIREBASE_API_KEY = 【FirebaseのプロジェクトのウェブAPIキー】;
const DYNAMICLINKS_DOMAIN = 'https://【ダイナミックリンクのサブドメイン名】.page.link';
exports.handler = async (event, context, callback) => {
console.log(event);
if( event.path == '/urlshorter'){
var body = JSON.parse(event.body);
var url = decodeURIComponent(body.targetUrl);
var param = {
"dynamicLinkInfo": {
"domainUriPrefix" : DYNAMICLINKS_DOMAIN,
"link" : url
}
};
var url = 'https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=' + FIREBASE_API_KEY;
return fetch(url, {
method : 'POST',
body : JSON.stringify(param),
headers: { 'Content-Type': 'application/json' }
})
.then((response) => {
return response.json();
})
.then(json =>{
console.log(json);
return new Response( json );
});
}
}
ユーティリティも示しておきます。
class Response{
constructor(context){
this.statusCode = 200;
this.headers = {'Access-Control-Allow-Origin' : '*'};
if( context )
this.set_body(context);
else
this.body = "{}";
}
set_error(error){
this.body = JSON.stringify({"err": error});
return this;
}
set_body(content){
this.body = JSON.stringify(content);
return this;
}
get_body(){
return JSON.parse(this.body);
}
}
module.exports = Response;
以下の部分を各人の内容に合わせて修正してください。
【FirebaseのプロジェクトのウェブAPIキー】;
【ダイナミックリンクのサブドメイン名】
(参考)
https://firebase.google.com/docs/reference/dynamic-links/link-shortener
フロントWebページの作成
HTML部分です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com 'unsafe-eval' 'unsafe-inline'; style-src * 'unsafe-inline'; media-src *; img-src * data: content: blob:;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<title>短縮URL</title>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="top" class="container">
<h1>短縮URL</h1>
<div class="form-group">
<label>targetUrl</label>
<input type="text" class="form-control" v-model="target_url">
<button class="btn btn-primary" v-on:click="make_shorturl()">短縮URLの生成
</div>
</button>
<br>
<生成結果>
<div class="form-group">
<label>短縮URL:</label> {{shorter_url}}
</div>
ホワイトリストの変更はこちら<br>
<a href="https://console.firebase.google.com/">Firerebaseコンソール</a>
</div>
<script src="js/start.js"></script>
</body>
Javascript部分です。
const base_url = 【RESTfulサーバのURL】;
var vue_options = {
el: "#top",
data: {
target_url: '',
shorter_url: ''
},
computed: {
},
methods: {
make_shorturl: function(){
var param = {
targetUrl: this.target_url
};
this.shorter_url = '';
do_post(base_url + '/urlshorter', param)
.then( json =>{
console.log(json);
if( json.error ){
alert(json.error.message);
return;
}
this.shorter_url = json.shortLink;
})
.catch(error =>{
alert(error);
});
}
},
mounted: function(){
}
};
var vue = new Vue( vue_options );
function do_post(url, body){
const headers = new Headers( { "Content-Type" : "application/json; charset=utf-8" } );
return fetch(url, {
method : 'POST',
body : JSON.stringify(body),
headers: headers
})
.then((response) => {
return response.json();
});
}
以下の部分を環境に合わせて修正してください。
【RESTfulサーバのURL】
実際に短縮URLを生成してみる
さていよいよ、短縮URLを作成しましょう。
その前に、ホワイトリストURLを登録する必要があります。
自由に短縮URLを作れるのではなく、ホワイトリストに指定したURLだけ、短縮URLが作成できます。ホワイトリストは、正規表現に似た記法でワイルドカードっぽく指定が可能です。
さきほどの、Dynamic Linksのページにおいて、「新しいダイナミックリンク」ボタンの右隣に、「・・・」があり、それを選択すると、「URLパターンのホワイトリスト登録」というメニューが表示されます。
記載例は、詳細のリンク先を見ればだいたいわかります。難しくはないです。
さて、これで準備が整いました。
フロントWebページを開きます。
targetUrlのテキストボックスに、短縮したいURLを指定します。また、URLに続けて?に続くパラメータを指定することが可能です。
短縮URLの生成ボタンを押下すると、めでたく、<生成結果>短縮URLのところに、以下のようなURLが生成されているのがわかります。
https://【サブドメイン名】.page.link/XXXXXXXXXXXX
XXXXXXXXは、乱数であり、内容や長さは、入力したtargetUrlの内容や長さによって変わります。
ためしに生成された短縮URLをブラウザで開くと、targetUrlのページが表示されることがわかるかと思います。
以上です。