From 9c10d0f1a65c1a9288e32a28eb39b4be9030daa7 Mon Sep 17 00:00:00 2001 From: Aniket Kumar Ghosh Date: Sun, 19 Jan 2025 14:57:13 +0530 Subject: [PATCH 1/2] short.io integration is in progress. --- .../src/short-linking/providers/short.io.ts | 85 +++++++++++++++++++ .../src/short-linking/short.link.service.ts | 5 ++ 2 files changed, 90 insertions(+) create mode 100644 libraries/nestjs-libraries/src/short-linking/providers/short.io.ts diff --git a/libraries/nestjs-libraries/src/short-linking/providers/short.io.ts b/libraries/nestjs-libraries/src/short-linking/providers/short.io.ts new file mode 100644 index 00000000..f94e9049 --- /dev/null +++ b/libraries/nestjs-libraries/src/short-linking/providers/short.io.ts @@ -0,0 +1,85 @@ +import { ShortLinking } from '@gitroom/nestjs-libraries/short-linking/short-linking.interface'; + + +const options = { + headers: { + Authorization: `Bearer ${process.env.SHORT_IO_SECRET_KEY}`, + 'Content-Type': 'application/json', + }, +}; + +export class ShortIo implements ShortLinking { + shortLinkDomain = 'aniket.short.gy'; + + async linksStatistics ( links: string[] ) { + return Promise.all( + links.map(async (link) => { + const url = `https://api.short.io/links/expand?domain=${this.shortLinkDomain}&path=${link.split('/').pop()}`; + const response = await ( fetch( url, options ) + .then( res => res.json() ) ); + + const linkStatisticsUrl = `https://statistics.short.io/statistics/link/${response.id}?period=last30&tz=UTC`; + + const statResponse = await ( fetch( linkStatisticsUrl, options ).then( ( res ) => res.json() ) ); + + return { + short: response.shortURL, + original: response.originalURL, + clicks: statResponse.totalClicks, + }; + }) + ); + } + + async convertLinkToShortLink(id: string, link: string) { + return ( + await ( + await fetch(`https://api.dub.co/links`, { + ...options, + method: 'POST', + body: JSON.stringify({ + url: link, + tenantId: id, + domain: this.shortLinkDomain, + }), + }) + ).json() + ).shortLink; + } + + async convertShortLinkToLink(shortLink: string) { + return await ( + await ( + await fetch( + `https://api.dub.co/links/info?domain=${shortLink}`, + options + ) + ).json() + ).url; + } + + // recursive functions that gets maximum 100 links per request if there are less than 100 links stop the recursion + async getAllLinksStatistics( + id: string, + page = 1 + ): Promise<{ short: string; original: string; clicks: string }[]> { + const response = await ( + await fetch( + `https://api.dub.co/links?tenantId=${id}&page=${page}&pageSize=100`, + options + ) + ).json(); + + const mapLinks = response.links.map((link: any) => ({ + short: link, + original: response.url, + clicks: response.clicks, + })); + + if (mapLinks.length < 100) { + return mapLinks; + } + + return [...mapLinks, ...(await this.getAllLinksStatistics(id, page + 1))]; + } +} diff --git a/libraries/nestjs-libraries/src/short-linking/short.link.service.ts b/libraries/nestjs-libraries/src/short-linking/short.link.service.ts index cdff93ce..4815e7f2 100644 --- a/libraries/nestjs-libraries/src/short-linking/short.link.service.ts +++ b/libraries/nestjs-libraries/src/short-linking/short.link.service.ts @@ -2,12 +2,17 @@ import { Dub } from '@gitroom/nestjs-libraries/short-linking/providers/dub'; import { Empty } from '@gitroom/nestjs-libraries/short-linking/providers/empty'; import { ShortLinking } from '@gitroom/nestjs-libraries/short-linking/short-linking.interface'; import { Injectable } from '@nestjs/common'; +import { ShortIo } from './providers/short.io'; const getProvider = (): ShortLinking => { if (process.env.DUB_TOKEN) { return new Dub(); } + if ( process.env.SHORT_IO_SECRET_KEY ) { + return new ShortIo(); + } + return new Empty(); }; From 4d9ef69476968a30413dfab0d4f575122e978f5e Mon Sep 17 00:00:00 2001 From: Aniket Kumar Ghosh Date: Sun, 19 Jan 2025 16:54:10 +0530 Subject: [PATCH 2/2] code implementation complete. --- .../src/short-linking/providers/short.io.ts | 56 ++++++++++--------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/libraries/nestjs-libraries/src/short-linking/providers/short.io.ts b/libraries/nestjs-libraries/src/short-linking/providers/short.io.ts index f94e9049..585d73dc 100644 --- a/libraries/nestjs-libraries/src/short-linking/providers/short.io.ts +++ b/libraries/nestjs-libraries/src/short-linking/providers/short.io.ts @@ -9,7 +9,7 @@ const options = { }; export class ShortIo implements ShortLinking { - shortLinkDomain = 'aniket.short.gy'; + shortLinkDomain = 'short.io'; async linksStatistics ( links: string[] ) { return Promise.all( @@ -31,31 +31,31 @@ export class ShortIo implements ShortLinking { ); } - async convertLinkToShortLink(id: string, link: string) { - return ( - await ( - await fetch(`https://api.dub.co/links`, { - ...options, - method: 'POST', - body: JSON.stringify({ - url: link, - tenantId: id, - domain: this.shortLinkDomain, - }), - }) - ).json() - ).shortLink; + async convertLinkToShortLink ( id: string, link: string ) { + const response = await fetch( `https://api.short.io/links`, { + ...options, + method: 'POST', + body: JSON.stringify( { + url: link, + tenantId: id, + domain: this.shortLinkDomain, + originalURL: link + + } ), + } ).then( ( res ) => res.json() ); + + return response.shortURL; } async convertShortLinkToLink(shortLink: string) { - return await ( - await ( + return await( + await( await fetch( - `https://api.dub.co/links/info?domain=${shortLink}`, + `https://api.short.io/links/expand?domain=${this.shortLinkDomain}&path=${shortLink.split('/').pop()}`, options ) ).json() - ).url; + ).originalURL; } // recursive functions that gets maximum 100 links per request if there are less than 100 links stop the recursion @@ -65,16 +65,22 @@ export class ShortIo implements ShortLinking { ): Promise<{ short: string; original: string; clicks: string }[]> { const response = await ( await fetch( - `https://api.dub.co/links?tenantId=${id}&page=${page}&pageSize=100`, + `https://api.short.io/api/links?domain_id=${id}&limit=150`, options ) ).json(); - const mapLinks = response.links.map((link: any) => ({ - short: link, - original: response.url, - clicks: response.clicks, - })); + const mapLinks = response.links.map(async ( link: any ) => { + const linkStatisticsUrl = `https://statistics.short.io/statistics/link/${response.id}?period=last30&tz=UTC`; + + const statResponse = await(fetch(linkStatisticsUrl, options).then((res) => res.json())); + + return { + short: link, + original: response.url, + clicks: statResponse.totalClicks, + }; + } ); if (mapLinks.length < 100) { return mapLinks;