Merge pull request #813 from altendorfme/kutt-it-shortlink-provider
Add kutt.it shortlink provider
This commit is contained in:
commit
4c8a9886cb
|
|
@ -104,3 +104,9 @@ POSTIZ_OAUTH_CLIENT_SECRET=""
|
|||
# DUB_TOKEN="" # Your self-hosted Dub API token
|
||||
# DUB_API_ENDPOINT="https://api.dub.co" # Your self-hosted Dub API endpoint
|
||||
# DUB_SHORT_LINK_DOMAIN="dub.sh" # Your self-hosted Dub domain
|
||||
|
||||
# SHORT_IO_SECRET_KEY="" # Your Short.io API secret key
|
||||
|
||||
# KUTT_API_KEY="" # Your Kutt.it API key
|
||||
# KUTT_API_ENDPOINT="https://kutt.it/api/v2" # Your self-hosted Kutt API endpoint
|
||||
# KUTT_SHORT_LINK_DOMAIN="kutt.it" # Your self-hosted Kutt domain
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
import { ShortLinking } from '@gitroom/nestjs-libraries/short-linking/short-linking.interface';
|
||||
|
||||
const KUTT_API_ENDPOINT = process.env.KUTT_API_ENDPOINT || 'https://kutt.it/api/v2';
|
||||
const KUTT_SHORT_LINK_DOMAIN = process.env.KUTT_SHORT_LINK_DOMAIN || 'kutt.it';
|
||||
|
||||
const getOptions = () => ({
|
||||
headers: {
|
||||
'X-API-Key': process.env.KUTT_API_KEY,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
export class Kutt implements ShortLinking {
|
||||
shortLinkDomain = KUTT_SHORT_LINK_DOMAIN;
|
||||
|
||||
async linksStatistics(links: string[]) {
|
||||
return Promise.all(
|
||||
links.map(async (link) => {
|
||||
const linkId = link.split('/').pop();
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${KUTT_API_ENDPOINT}/links/${linkId}/stats`,
|
||||
getOptions()
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
return {
|
||||
short: link,
|
||||
original: data.address || '',
|
||||
clicks: data.lastDay?.stats?.reduce((total: number, stat: any) => total + stat, 0)?.toString() || '0',
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
short: link,
|
||||
original: '',
|
||||
clicks: '0',
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async convertLinkToShortLink(id: string, link: string) {
|
||||
try {
|
||||
const response = await fetch(`${KUTT_API_ENDPOINT}/links`, {
|
||||
...getOptions(),
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
target: link,
|
||||
domain: this.shortLinkDomain,
|
||||
reuse: false,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data.link;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create short link: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
async convertShortLinkToLink(shortLink: string) {
|
||||
const linkId = shortLink.split('/').pop();
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${KUTT_API_ENDPOINT}/links/${linkId}/stats`,
|
||||
getOptions()
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data.address || '';
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get original link: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getAllLinksStatistics(
|
||||
id: string,
|
||||
page = 1
|
||||
): Promise<{ short: string; original: string; clicks: string }[]> {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${KUTT_API_ENDPOINT}/links?limit=100&skip=${(page - 1) * 100}`,
|
||||
getOptions()
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
const mapLinks = data.data?.map((link: any) => ({
|
||||
short: link.link,
|
||||
original: link.address,
|
||||
clicks: link.visit_count?.toString() || '0',
|
||||
})) || [];
|
||||
|
||||
if (mapLinks.length < 100) {
|
||||
return mapLinks;
|
||||
}
|
||||
|
||||
return [...mapLinks, ...(await this.getAllLinksStatistics(id, page + 1))];
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ 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';
|
||||
import { Kutt } from './providers/kutt';
|
||||
|
||||
const getProvider = (): ShortLinking => {
|
||||
if (process.env.DUB_TOKEN) {
|
||||
|
|
@ -13,6 +14,10 @@ const getProvider = (): ShortLinking => {
|
|||
return new ShortIo();
|
||||
}
|
||||
|
||||
if (process.env.KUTT_API_KEY) {
|
||||
return new Kutt();
|
||||
}
|
||||
|
||||
return new Empty();
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue