tunnckoCore / ideas

:notebook: My centralized place for ideas, thoughts and todos. Raw, PoC implementations and so on... :star:
http://j.mp/1stW47C
6 stars 0 forks source link

gugl.now - url shortener based on Goo.gl #103

Open tunnckoCore opened 6 years ago

tunnckoCore commented 6 years ago

thin layer on top of goo.gl apy without needing api key.

A micro-service for creating, discoverying and expanding https://goo.gl shortlinks.

http://jsbin.com/qamewaxubi/edit?output - html demo

zeit/micro server

const { readFileSync } = require("fs");
const { parse } = require("url");
const microCors = require("micro-cors");
const { json, send, sendError } = require("micro");
const { router, get, post } = require("microrouter");
const microRequest = require("micro-request");
const redirect = require("micro-redirect");

/**
 * Settings
 */

const PROTOCOL = "http";
const ENDPOINT = "https://www.googleapis.com/urlshortener/v1";
const API_KEY = "your google api key";

/**
 * UTILS
 */

const requestPost = (url, data) => {
  return new Promise((resolve, reject) => {
    microRequest.post(url, { data }, (err, _, body) => {
      if (err) return reject(err);
      resolve(body);
    });
  });
};

const requestGet = x => {
  return new Promise((resolve, reject) => {
    microRequest(x, (err, _, body) => {
      if (err) return reject(err);
      resolve(body);
    });
  });
};

const createShortlink = () => `${ENDPOINT}/url?key=${API_KEY}`;
const expandShortlink = x => {
  const link = createShortlink();
  return `${link}&projection=FULL&shortUrl=${x}`;
};

const wrapper = (url, protocol) => async (req, res) => {
  const endpoint = `${protocol}://${req.headers.host}/api/v1/links`;
  return requestPost(endpoint, { url });
};

/**
 * Expose micro service
 */

const cors = microCors({ allowMethods: ["GET", "POST"] });

module.exports = cors(
  router(
    get("/", (req, res) => readFileSync("./index.html", "utf8")),
    get("/api/v1/shorten", async (req, res) => {
      if (req.query.url) {
        const { id: shortUrl, longUrl } = await requestPost(createShortlink(), {
          longUrl: req.query.url
        });
        const id = parse(shortUrl).path.slice(1);

        return { id, shortUrl, longUrl };
      }
    }),
    get("/api/v1/expand", async (req, res) => {
      const url = req.query.url;

      if (url && url.includes("goo.gl/") && url.length > 8) {
        const {
          id: shortUrl,
          longUrl,
          status,
          created,
          analytics
        } = await requestGet(expandShortlink(url));

        const result = {
          id: parse(shortUrl).path.slice(1),
          shortUrl,
          longUrl,
          created,
          analytics
        };

        if (status === "OK") {
          return result;
        }
      }
    }),
    get("/api/v1/find", async (req, res) => {
      if (req.query.id) {
        const host = req.headers.host;
        const short = `https://goo.gl/${req.query.id}`;
        const endpoint = `${PROTOCOL}://${host}/api/v1/expand?url=${short}`;
        const result = await requestGet(endpoint);

        return result ? send(res, 200, result) : send(res, 404);
      }
    })
  )
);
tunnckoCore commented 6 years ago

html index

<html>
  <head>
    <meta charset="utf-8">
    <title>GUGL NOW - micro service for shortening and expanding urls</title>

    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://tunnckocore.github.io/assets/css/style.css?v=f157ba07b19adf390d7a2d65b9c6c36868ecb1d2" rel="stylesheet">
  </head>
  <body>
      <div class="container-lg px-3 my-5 markdown-body">
      <h1>
        Welcome to <a href="https://github.com/tunnckoCore/gugl.now.sh">GUGL NOW</a>
      </h1>
      <p>
        A <a href="https://ghub.now.sh/micro">micro</a>-service for creating,
        discoverying and expanding <a href="https://goo.gl">https://goo.gl</a> shortlinks.
      </p>

      <div class="comment-body markdown-body" style="min-height: 620.142px;">
<h2>Shortening long url</h2>
<p><strong>GET request:</strong> <code>/api/v1/shorten?url=&lt;LONG URL HERE&gt;</code><br>
<strong>example:</strong> <a href="/api/v1/shorten?url=https://www.facebook.com/tunnckoCore" rel="nofollow">/api/v1/shorten?url=https://www.facebook.com/tunnckoCore</a><br>
<strong>response:</strong></p>
<div class="highlight highlight-source-json"><pre>{
  <span class="pl-s"><span class="pl-pds">"</span>id<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>up3mjD<span class="pl-pds">"</span></span>,
  <span class="pl-s"><span class="pl-pds">"</span>shortUrl<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>https://goo.gl/up3mjD<span class="pl-pds">"</span></span>,
  <span class="pl-s"><span class="pl-pds">"</span>longUrl<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>https://www.facebook.com/tunnckoCore<span class="pl-pds">"</span></span>
}</pre></div>
<h2>Expanding short url</h2>
<blockquote>The response object also has `analytics` and `created` propeties as seen at
  <a href="https://developers.google.com/url-shortener/v1/getting_started#url_analytics">goo.gl
    Shortener documentation</a>.
</blockquote>
<p><strong>GET request:</strong> <code>/api/v1/expand?url=&lt;goo.gl SHORT URL&gt;</code><br>
<strong>example:</strong> <a href="/api/v1/expand?url=https://goo.gl/fbsS" rel="nofollow">/api/v1/expand?url=https://goo.gl/fbsS</a><br>
<strong>response:</strong></p>
<div class="highlight highlight-source-json"><pre>{
  <span class="pl-s"><span class="pl-pds">"</span>id<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>fbsS<span class="pl-pds">"</span></span>,
  <span class="pl-s"><span class="pl-pds">"</span>shortUrl<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>https://goo.gl/fbsS<span class="pl-pds">"</span></span>,
  <span class="pl-s"><span class="pl-pds">"</span>longUrl<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>http://www.google.com/<span class="pl-pds">"</span></span>
}</pre></div>

<h2>Finding by ID</h2>
<blockquote>The response object also has `analytics` and `created` propeties as seen at
  <a href="https://developers.google.com/url-shortener/v1/getting_started#url_analytics">goo.gl
    Shortener documentation</a>.
</blockquote>
<p><strong>GET request:</strong> <code>/api/v1/find?id=&lt;short id&gt;</code><br>
<strong>example:</strong> <a href="/api/v1/find?id=tbMhrs" rel="nofollow">/api/v1/find?id=tbMhrs</a>
<em>(streaming video over IPFS)</em><br>
<strong>response:</strong></p>
<div class="highlight highlight-source-json"><pre>{
  <span class="pl-s"><span class="pl-pds">"</span>id<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>tbMhrs<span class="pl-pds">"</span></span>,
  <span class="pl-s"><span class="pl-pds">"</span>shortUrl<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>https://goo.gl/tbMhrs<span class="pl-pds">"</span></span>,
  <span class="pl-s"><span class="pl-pds">"</span>longUrl<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>https://ipfs.io/ipfs/Qmem4exur6JCXTkJuc4XSYttEzFJg1U6RejgKrot7DNuCB<span class="pl-pds">"</span></span>
}</pre></div>

      <h2>Why? And limits</h2>
      <p>
        We need more simpler API and service with already given API KEY.<br>
        The limits of the API are as defined at
        <a href="https://developers.google.com/url-shortener/v1/getting_started#quota">Quotas Section</a>.
      </p>
      <div class="footer border-top border-gray-light mt-5 pt-3 text-right text-gray">
        Copyright (c) 2018-present <a href="https://i.am.charlike.online">Charlike Mike Reagent</a>
          <code>&lt;open.source.charlike@gmail.com&gt;</code>. MIT License.
          <a href="https://github.com/tunnckoCore/gugl.now.sh">Source code</a>.
      </div>
      </div>
      <!-- <p>
        Copyright (c) 2018-present <a href="https://i.am.charlike.online">Charlike Mike Reagent</a>
        <code>&lt;open.source.charlike@gmail.com&gt;</code>
      </p> -->
    </div>
  </body>

  </html>
tunnckoCore commented 6 years ago

Sadly... we should reconsider, since Google is dropping that service ;/ ;((