1+ import { createId } from "@/lib/api/create-id" ;
12import { linkCache } from "@/lib/api/links/cache" ;
2- import { redis } from "@/lib/upstash" ;
3- import { DUB_HEADERS } from "@dub/utils" ;
3+ import { encodeKeyIfCaseSensitive } from "@/lib/api/links/case-sensitivity" ;
4+ import { recordLink } from "@/lib/tinybird" ;
5+ import { prisma } from "@dub/prisma" ;
6+ import {
7+ DUB_HEADERS ,
8+ getUrlFromStringIfValid ,
9+ linkConstructorSimple ,
10+ } from "@dub/utils" ;
11+ import { waitUntil } from "@vercel/functions" ;
412import { NextRequest , NextResponse } from "next/server" ;
513import { parse } from "./parse" ;
614
15+ const BUFFER_WORKSPACE_ID = "cm05wnnpo000711ztj05wwdbu" ;
16+ const BUFFER_USER_ID = "cm05wnd49000411ztg2xbup0i" ;
17+ const BUFFER_FOLDER_ID = "fold_LIZsdjTgFVbQVGYSUmYAi5vT" ;
18+ const BUFFER_BITLY_API_KEY = process . env . BUFFER_BITLY_API_KEY ;
19+
720export const crawlBitly = async ( req : NextRequest ) => {
8- const { domain, fullKey } = parse ( req ) ;
21+ const { domain, fullKey : key } = parse ( req ) ;
922
10- // bitly doesn't support the following characters: ` ~ , . < > ; ‘ : “ / \ [ ] ^ { } ( ) = + ! * @ & $ £ ? % # |
23+ // bitly doesn't support the following characters: ` ~ , . < > ; ‘ : " / \ [ ] ^ { } ( ) = + ! * @ & $ £ ? % # |
1124 // @see : https://support.bitly.com/hc/en-us/articles/360030780892-What-characters-are-supported-when-customizing-links
1225 const invalidBitlyKeyRegex = / [ ` ~ , . < > ; ' : " / \\ [ \] ^ { } ( ) = + ! * @ & $ £ ? % # | ] / ;
1326
14- if ( fullKey && ! invalidBitlyKeyRegex . test ( fullKey ) ) {
15- const link = await fetchBitlyLink ( { domain, key : fullKey } ) ;
27+ if ( key && ! invalidBitlyKeyRegex . test ( key ) ) {
28+ const link = await fetchBitlyLink ( { domain, key } ) ;
1629 if ( link ) {
30+ const sanitizedUrl = getUrlFromStringIfValid ( link . long_url ) ;
31+ if ( sanitizedUrl ) {
32+ console . log (
33+ `[Bitly] Creating link on-demand: ${ domain } /${ key } (createdAt: ${ link . created_at } )` ,
34+ ) ;
35+ const encodedKey = encodeKeyIfCaseSensitive ( { domain, key } ) ;
36+ waitUntil (
37+ prisma . link
38+ . create ( {
39+ data : {
40+ id : createId ( { prefix : "link_" } ) ,
41+ domain,
42+ key : encodedKey ,
43+ url : sanitizedUrl ,
44+ shortLink : linkConstructorSimple ( { domain, key : encodedKey } ) ,
45+ projectId : BUFFER_WORKSPACE_ID ,
46+ userId : BUFFER_USER_ID ,
47+ folderId : BUFFER_FOLDER_ID ,
48+ createdAt : new Date ( link . created_at ) ,
49+ } ,
50+ } )
51+ . then ( ( data ) =>
52+ Promise . allSettled ( [
53+ // console log outputs
54+ recordLink ( data ) ,
55+ prisma . project . update ( {
56+ where : {
57+ id : BUFFER_WORKSPACE_ID ,
58+ } ,
59+ data : {
60+ linksUsage : { increment : 1 } ,
61+ } ,
62+ } ) ,
63+ ] ) ,
64+ ) ,
65+ ) ;
66+ }
67+
1768 return NextResponse . redirect ( link . long_url , {
1869 headers : DUB_HEADERS ,
1970 status : 302 ,
@@ -27,36 +78,25 @@ export const crawlBitly = async (req: NextRequest) => {
2778 "Vercel-CDN-Cache-Control" : "public, s-maxage=86400" ,
2879 "Vercel-Cache-Tag" : linkCache . _createStaticPagesCacheKeys ( {
2980 domain,
30- key : fullKey ,
81+ key,
3182 } ) ,
3283 } ,
3384 status : 302 ,
3485 } ) ;
3586} ;
3687
37- const BUFFER_WORKSPACE_ID = "cm05wnnpo000711ztj05wwdbu" ;
38-
3988async function fetchBitlyLink ( {
4089 domain,
4190 key,
4291} : {
4392 domain : string ;
4493 key : string ;
4594} ) {
46- const apiKey = await redis . get < string > ( `import:bitly:${ BUFFER_WORKSPACE_ID } ` ) ;
47-
48- if ( ! apiKey ) {
49- console . error (
50- `[Bitly] No API key found for workspace ${ BUFFER_WORKSPACE_ID } ` ,
51- ) ;
52- return null ;
53- }
54-
5595 const response = await fetch (
5696 `https://api-ssl.bitly.com/v4/bitlinks/${ domain } /${ key } ` ,
5797 {
5898 headers : {
59- Authorization : `Bearer ${ apiKey } ` ,
99+ Authorization : `Bearer ${ BUFFER_BITLY_API_KEY } ` ,
60100 } ,
61101 } ,
62102 ) ;
0 commit comments