fix: request errors and returning undefined

This commit is contained in:
Tobi Saputra 2025-05-13 18:26:55 +07:00
parent cb64f0585a
commit 80b5cbdc1d
3 changed files with 216 additions and 155 deletions

View File

@ -15,6 +15,7 @@ import {
StatisticsAuthorLiked, StatisticsAuthorLiked,
ImagesLiked ImagesLiked
} from "../../types/get/getUserLiked" } from "../../types/get/getUserLiked"
import retry from "async-retry"
export const getUserLiked = ( export const getUserLiked = (
username: string, username: string,
@ -215,22 +216,38 @@ const requestUserLiked = async (
url.searchParams.append("X-Bogus", xbogus) url.searchParams.append("X-Bogus", xbogus)
const xttparams = Tiktok.generateXTTParams(url.searchParams.toString()) const xttparams = Tiktok.generateXTTParams(url.searchParams.toString())
const { data } = await Axios.get(`${url.toString()}`, { return await retry(
headers: { async (bail, attempt) => {
"user-agent": try {
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35", const { data } = await Axios.get(url.toString(), {
cookie, headers: {
"x-tt-params": xttparams "user-agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35",
cookie,
"x-tt-params": xttparams
},
httpsAgent:
(proxy &&
(proxy.startsWith("http") || proxy.startsWith("https")
? new HttpsProxyAgent(proxy)
: proxy.startsWith("socks")
? new SocksProxyAgent(proxy)
: undefined)) ||
undefined
})
return data
} catch (error) {
if (attempt === 3) {
bail(error)
}
throw error
}
}, },
httpsAgent: {
(proxy && retries: 3,
(proxy.startsWith("http") || proxy.startsWith("https") minTimeout: 1000,
? new HttpsProxyAgent(proxy) maxTimeout: 5000,
: proxy.startsWith("socks") factor: 2
? new SocksProxyAgent(proxy) }
: undefined)) || )
undefined
})
return data
} }

View File

@ -10,6 +10,7 @@ import { HttpsProxyAgent } from "https-proxy-agent"
import { SocksProxyAgent } from "socks-proxy-agent" import { SocksProxyAgent } from "socks-proxy-agent"
import { TiktokService } from "../../services/tiktokService" import { TiktokService } from "../../services/tiktokService"
import { StalkUser } from "../get/getProfile" import { StalkUser } from "../get/getProfile"
import retry from "async-retry"
export const getUserPosts = ( export const getUserPosts = (
username: string, username: string,
@ -58,14 +59,17 @@ const parseUserPosts = async (
let cursor = 0 let cursor = 0
const posts: Posts[] = [] const posts: Posts[] = []
let counter = 0 let counter = 0
const Tiktok = new TiktokService()
const xttparams = Tiktok.generateXTTParams(
_xttParams(secUid, cursor, postLimit)
)
while (hasMore) { while (hasMore) {
let result: any | null = null let result: any | null = null
// Prevent missing response posts // Prevent missing response posts
for (let i = 0; i < 30; i++) { result = await requestUserPosts(proxy, xttparams)
result = await requestUserPosts(secUid, cursor, postLimit, proxy)
if (result !== "") break
}
// Validate // Validate
if (result === "") { if (result === "") {
@ -161,33 +165,51 @@ const parseUserPosts = async (
} }
const requestUserPosts = async ( const requestUserPosts = async (
secUid: string, proxy?: string,
cursor: number = 0, xttparams: string = ""
count: number = 30,
proxy?: string
): Promise<any> => { ): Promise<any> => {
const Tiktok = new TiktokService() return retry(
async (bail, attempt) => {
const { data } = await Axios.get( try {
`${_tiktokGetPosts(_getUserPostsParams())}`, const { data } = await Axios.get(
{ `${_tiktokGetPosts(_getUserPostsParams())}`,
headers: { {
"user-agent": headers: {
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35", "user-agent":
"X-tt-params": Tiktok.generateXTTParams( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35",
_xttParams(secUid, cursor, count) "x-tt-params": xttparams
},
httpsAgent:
(proxy &&
(proxy.startsWith("http") || proxy.startsWith("https")
? new HttpsProxyAgent(proxy)
: proxy.startsWith("socks")
? new SocksProxyAgent(proxy)
: undefined)) ||
undefined
}
) )
}, console.log(data)
httpsAgent: return data
(proxy && } catch (error) {
(proxy.startsWith("http") || proxy.startsWith("https") if (
? new HttpsProxyAgent(proxy) error.response?.status === 400 ||
: proxy.startsWith("socks") error.response?.data?.statusCode === 10201
? new SocksProxyAgent(proxy) ) {
: undefined)) || bail(new Error("Video not found!"))
undefined return
}
throw error
}
},
{
retries: 3,
minTimeout: 1000,
maxTimeout: 5000,
factor: 2,
onRetry: (error, attempt) => {
console.log(`Retry attempt ${attempt} due to: ${error}`)
}
} }
) )
return data
} }

View File

@ -4,6 +4,7 @@ import { _liveSearchParams, _videoSearchParams } from "../../constants/params"
import { SocksProxyAgent } from "socks-proxy-agent" import { SocksProxyAgent } from "socks-proxy-agent"
import { HttpsProxyAgent } from "https-proxy-agent" import { HttpsProxyAgent } from "https-proxy-agent"
import { TiktokService } from "../../services/tiktokService" import { TiktokService } from "../../services/tiktokService"
import retry from "async-retry"
import { import {
TiktokVideoSearchResponse, TiktokVideoSearchResponse,
AuthorVideoSearch, AuthorVideoSearch,
@ -36,119 +37,140 @@ export const SearchVideo = async (
}) })
} }
const Tiktok = new TiktokService() try {
const url = new URL( const data = await requestVideoSearch(keyword, page, cookie, proxy)
_tiktokSearchVideoFull(_videoSearchParams(keyword, page))
)
const signature = Tiktok.generateSignature(url)
url.searchParams.append("_signature", signature)
const xbogus = Tiktok.generateXBogus(url, signature)
url.searchParams.append("X-Bogus", xbogus)
Axios(_tiktokSearchVideoFull(_videoSearchParams(keyword, page)), { // Cookie Invalid
method: "GET", if (data.status_code === 2483)
headers: { return resolve({ status: "error", message: "Invalid cookie!" })
"User-Agent": // Another Error
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", if (data.status_code !== 0)
cookie: return resolve({
typeof cookie === "object" status: "error",
? cookie.map((v: any) => `${v.name}=${v.value}`).join("; ") message:
: cookie data.status_msg ||
}, "An error occurred! Please report this issue to the developer."
httpsAgent:
(proxy &&
(proxy.startsWith("http") || proxy.startsWith("https")
? new HttpsProxyAgent(proxy)
: proxy.startsWith("socks")
? new SocksProxyAgent(proxy)
: undefined)) ||
undefined
})
.then(({ data }) => {
// Cookie Invalid
if (data.status_code === 2483)
return resolve({ status: "error", message: "Invalid cookie!" })
// Another Error
if (data.status_code !== 0)
return resolve({
status: "error",
message:
data.status_msg ||
"An error occurred! Please report this issue to the developer."
})
if (!data.item_list)
return resolve({ status: "error", message: "Video not found!" })
const result: VideoSearchResult[] = []
data.item_list.forEach((v: any) => {
const video: VideoSearch = {
id: v.video.id,
ratio: v.video.ratio,
cover: v.video.cover,
originCover: v.video.originCover,
dynamicCover: v.video.dynamicCover,
playAddr: v.video.playAddr,
downloadAddr: v.video.downloadAddr,
format: v.video.format
}
const stats: StatisticsVideoSearch = {
diggCount: v.stats.diggCount,
shareCount: v.stats.shareCount,
commentCount: v.stats.commentCount,
playCount: v.stats.playCount,
collectCount: v.stats.collectCount
}
const author: AuthorVideoSearch = {
id: v.author.id,
uniqueId: v.author.uniqueId,
nickname: v.author.nickname,
avatarThumb: v.author.avatarThumb,
avatarMedium: v.author.avatarMedium,
avatarLarger: v.author.avatarLarger,
signature: v.author.signature,
verified: v.author.verified,
secUid: v.author.secUid,
openFavorite: v.author.openFavorite,
privateAccount: v.author.privateAccount,
isADVirtual: v.author.isADVirtual,
tiktokSeller: v.author.ttSeller,
isEmbedBanned: v.author.isEmbedBanned
}
const music: MusicVideoSearch = {
id: v.music.id,
title: v.music.title,
playUrl: v.music.playUrl,
coverThumb: v.music.coverThumb,
coverMedium: v.music.coverMedium,
coverLarge: v.music.coverLarge,
authorName: v.music.authorName,
original: v.music.original,
album: v.music.album,
duration: v.music.duration,
isCopyrighted: v.music.isCopyrighted
}
result.push({
id: v.id,
desc: v.desc,
createTime: v.createTime,
author,
stats,
video,
music
})
}) })
if (!data.item_list)
return resolve({ status: "error", message: "Video not found!" })
resolve({ const result: VideoSearchResult[] = []
status: "success", data.item_list.forEach((v: any) => {
result, const video: VideoSearch = {
page, id: v.video.id,
totalResults: result.length ratio: v.video.ratio,
cover: v.video.cover,
originCover: v.video.originCover,
dynamicCover: v.video.dynamicCover,
playAddr: v.video.playAddr,
downloadAddr: v.video.downloadAddr,
format: v.video.format
}
const stats: StatisticsVideoSearch = {
likeCount: v.stats.diggCount,
shareCount: v.stats.shareCount,
commentCount: v.stats.commentCount,
playCount: v.stats.playCount,
collectCount: v.stats.collectCount
}
const author: AuthorVideoSearch = {
id: v.author.id,
uniqueId: v.author.uniqueId,
nickname: v.author.nickname,
avatarThumb: v.author.avatarThumb,
avatarMedium: v.author.avatarMedium,
avatarLarger: v.author.avatarLarger,
signature: v.author.signature,
verified: v.author.verified,
secUid: v.author.secUid,
openFavorite: v.author.openFavorite,
privateAccount: v.author.privateAccount,
isADVirtual: v.author.isADVirtual,
tiktokSeller: v.author.ttSeller,
isEmbedBanned: v.author.isEmbedBanned
}
const music: MusicVideoSearch = {
id: v.music.id,
title: v.music.title,
playUrl: v.music.playUrl,
coverThumb: v.music.coverThumb,
coverMedium: v.music.coverMedium,
coverLarge: v.music.coverLarge,
authorName: v.music.authorName,
original: v.music.original,
album: v.music.album,
duration: v.music.duration,
isCopyrighted: v.music.isCopyrighted
}
result.push({
id: v.id,
desc: v.desc,
createTime: v.createTime,
author,
stats,
video,
music
}) })
}) })
.catch((e) => {
resolve({ status: "error", message: e.message }) resolve({
status: "success",
result,
page,
totalResults: result.length
}) })
} catch (e) {
resolve({ status: "error", message: e.message })
}
}) })
const requestVideoSearch = async (
keyword: string,
page: number,
cookie: string | any[],
proxy?: string
): Promise<any> => {
return retry(
async (bail, attempt) => {
try {
const { data } = await Axios(
_tiktokSearchVideoFull(_videoSearchParams(keyword, page)),
{
method: "GET",
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0",
cookie:
typeof cookie === "object"
? cookie.map((v: any) => `${v.name}=${v.value}`).join("; ")
: cookie
},
httpsAgent:
(proxy &&
(proxy.startsWith("http") || proxy.startsWith("https")
? new HttpsProxyAgent(proxy)
: proxy.startsWith("socks")
? new SocksProxyAgent(proxy)
: undefined)) ||
undefined
}
)
return data
} catch (error) {
throw error
}
},
{
retries: 3,
minTimeout: 1000,
maxTimeout: 5000,
factor: 2,
onRetry: (error, attempt) => {
console.log(`Retry attempt ${attempt} due to: ${error}`)
}
}
)
}