@nxgiang/tiktok-api 1.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/CHANGELOG.md +492 -0
  2. package/CODE_OF_CONDUCT.md +128 -0
  3. package/CONTRIBUTING.md +95 -0
  4. package/LICENSE +201 -0
  5. package/README.md +1663 -0
  6. package/bun.lock +367 -0
  7. package/helper/signature.js +390 -0
  8. package/helper/webmssdk.js +4586 -0
  9. package/helper/xbogus.js +563 -0
  10. package/install.sh +51 -0
  11. package/lib/cli/index.d.ts +2 -0
  12. package/lib/cli/index.js +809 -0
  13. package/lib/constants/api.d.ts +22 -0
  14. package/lib/constants/api.js +39 -0
  15. package/lib/constants/headers.d.ts +2 -0
  16. package/lib/constants/headers.js +5 -0
  17. package/lib/constants/index.d.ts +23 -0
  18. package/lib/constants/index.js +26 -0
  19. package/lib/constants/params.d.ts +19 -0
  20. package/lib/constants/params.js +531 -0
  21. package/lib/index.d.ts +93 -0
  22. package/lib/index.js +137 -0
  23. package/lib/lib/logger.d.ts +8 -0
  24. package/lib/lib/logger.js +25 -0
  25. package/lib/services/cookieManager.d.ts +10 -0
  26. package/lib/services/cookieManager.js +51 -0
  27. package/lib/services/downloadManager.d.ts +5 -0
  28. package/lib/services/downloadManager.js +188 -0
  29. package/lib/services/tiktokService.d.ts +14 -0
  30. package/lib/services/tiktokService.js +78 -0
  31. package/lib/types/common.d.ts +65 -0
  32. package/lib/types/common.js +2 -0
  33. package/lib/types/cookieManager.d.ts +13 -0
  34. package/lib/types/cookieManager.js +2 -0
  35. package/lib/types/downloader/musicaldownDownloader.d.ts +27 -0
  36. package/lib/types/downloader/musicaldownDownloader.js +2 -0
  37. package/lib/types/downloader/ssstikDownloader.d.ts +30 -0
  38. package/lib/types/downloader/ssstikDownloader.js +2 -0
  39. package/lib/types/downloader/tiktokApiDownloader.d.ts +38 -0
  40. package/lib/types/downloader/tiktokApiDownloader.js +2 -0
  41. package/lib/types/get/getCollection.d.ts +53 -0
  42. package/lib/types/get/getCollection.js +2 -0
  43. package/lib/types/get/getComments.d.ts +26 -0
  44. package/lib/types/get/getComments.js +2 -0
  45. package/lib/types/get/getMusicDetail.d.ts +49 -0
  46. package/lib/types/get/getMusicDetail.js +2 -0
  47. package/lib/types/get/getMusicVideos.d.ts +93 -0
  48. package/lib/types/get/getMusicVideos.js +2 -0
  49. package/lib/types/get/getPlaylist.d.ts +65 -0
  50. package/lib/types/get/getPlaylist.js +2 -0
  51. package/lib/types/get/getProfile.d.ts +71 -0
  52. package/lib/types/get/getProfile.js +2 -0
  53. package/lib/types/get/getTrendings.d.ts +61 -0
  54. package/lib/types/get/getTrendings.js +2 -0
  55. package/lib/types/get/getUserLiked.d.ts +90 -0
  56. package/lib/types/get/getUserLiked.js +2 -0
  57. package/lib/types/get/getUserPosts.d.ts +68 -0
  58. package/lib/types/get/getUserPosts.js +2 -0
  59. package/lib/types/get/getUserReposts.d.ts +104 -0
  60. package/lib/types/get/getUserReposts.js +2 -0
  61. package/lib/types/search/index.d.ts +15 -0
  62. package/lib/types/search/index.js +2 -0
  63. package/lib/types/search/liveSearch.d.ts +48 -0
  64. package/lib/types/search/liveSearch.js +2 -0
  65. package/lib/types/search/userSearch.d.ts +32 -0
  66. package/lib/types/search/userSearch.js +2 -0
  67. package/lib/types/search/videoSearch.d.ts +62 -0
  68. package/lib/types/search/videoSearch.js +2 -0
  69. package/lib/utils/downloader/musicaldownDownloader.d.ts +2 -0
  70. package/lib/utils/downloader/musicaldownDownloader.js +193 -0
  71. package/lib/utils/downloader/ssstikDownloader.d.ts +2 -0
  72. package/lib/utils/downloader/ssstikDownloader.js +177 -0
  73. package/lib/utils/downloader/tiktokAPIDownloader.d.ts +3 -0
  74. package/lib/utils/downloader/tiktokAPIDownloader.js +221 -0
  75. package/lib/utils/get/getCollection.d.ts +7 -0
  76. package/lib/utils/get/getCollection.js +113 -0
  77. package/lib/utils/get/getComments.d.ts +2 -0
  78. package/lib/utils/get/getComments.js +139 -0
  79. package/lib/utils/get/getMusicDetail.d.ts +2 -0
  80. package/lib/utils/get/getMusicDetail.js +68 -0
  81. package/lib/utils/get/getMusicVideos.d.ts +2 -0
  82. package/lib/utils/get/getMusicVideos.js +249 -0
  83. package/lib/utils/get/getPlaylist.d.ts +7 -0
  84. package/lib/utils/get/getPlaylist.js +115 -0
  85. package/lib/utils/get/getProfile.d.ts +2 -0
  86. package/lib/utils/get/getProfile.js +92 -0
  87. package/lib/utils/get/getTrendings.d.ts +7 -0
  88. package/lib/utils/get/getTrendings.js +120 -0
  89. package/lib/utils/get/getUserLiked.d.ts +2 -0
  90. package/lib/utils/get/getUserLiked.js +204 -0
  91. package/lib/utils/get/getUserPosts.d.ts +2 -0
  92. package/lib/utils/get/getUserPosts.js +199 -0
  93. package/lib/utils/get/getUserRepost.d.ts +2 -0
  94. package/lib/utils/get/getUserRepost.js +239 -0
  95. package/lib/utils/search/liveSearch.d.ts +2 -0
  96. package/lib/utils/search/liveSearch.js +99 -0
  97. package/lib/utils/search/userSearch.d.ts +2 -0
  98. package/lib/utils/search/userSearch.js +76 -0
  99. package/lib/utils/search/videoSearch.d.ts +2 -0
  100. package/lib/utils/search/videoSearch.js +140 -0
  101. package/lib/utils/urlExtractors.d.ts +3 -0
  102. package/lib/utils/urlExtractors.js +37 -0
  103. package/lib/utils/validator.d.ts +1 -0
  104. package/lib/utils/validator.js +13 -0
  105. package/package.json +60 -0
  106. package/test/collection-test.ts +73 -0
  107. package/test/comments-test.ts +54 -0
  108. package/test/downloader-v1-test.ts +49 -0
  109. package/test/downloader-v2-test.ts +47 -0
  110. package/test/downloader-v3-test.ts +35 -0
  111. package/test/music-detail-test.ts +97 -0
  112. package/test/music-videos-test.ts +86 -0
  113. package/test/playlist-test.ts +48 -0
  114. package/test/profile-test.ts +49 -0
  115. package/test/search-live-test.ts +42 -0
  116. package/test/search-user-test.ts +46 -0
  117. package/test/search-video-test.ts +53 -0
  118. package/test/trending-test.ts +128 -0
  119. package/test/userliked-test.ts +65 -0
  120. package/test/userposts-test.ts +56 -0
  121. package/test/userreposts-test.ts +57 -0
  122. package/tobyg74-tiktok-api-1.3.7.tgz +0 -0
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SSSTik = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const async_retry_1 = __importDefault(require("async-retry"));
9
+ const cheerio_1 = require("cheerio");
10
+ const api_1 = require("../../constants/api");
11
+ const https_proxy_agent_1 = require("https-proxy-agent");
12
+ const socks_proxy_agent_1 = require("socks-proxy-agent");
13
+ const constants_1 = require("../../constants");
14
+ const TIKTOK_URL_REGEX = /https:\/\/(?:m|t|www|vm|vt|lite)?\.?tiktok\.com\/((?:.*\b(?:(?:usr|v|embed|user|video|photo)\/|\?shareId=|\&item_id=)(\d+))|\w+)/;
15
+ const USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0";
16
+ const createProxyAgent = (proxy) => {
17
+ if (!proxy)
18
+ return {};
19
+ const isHttpProxy = proxy.startsWith("http") || proxy.startsWith("https");
20
+ const isSocksProxy = proxy.startsWith("socks");
21
+ if (!isHttpProxy && !isSocksProxy)
22
+ return {};
23
+ return {
24
+ httpsAgent: isHttpProxy
25
+ ? new https_proxy_agent_1.HttpsProxyAgent(proxy)
26
+ : new socks_proxy_agent_1.SocksProxyAgent(proxy)
27
+ };
28
+ };
29
+ const validateTikTokUrl = (url) => {
30
+ return TIKTOK_URL_REGEX.test(url);
31
+ };
32
+ const extractTTValue = (html) => {
33
+ const regex = /s_tt\s*=\s*["']([^"']+)["']/;
34
+ const match = html.match(regex);
35
+ return match ? match[1] : null;
36
+ };
37
+ const parseAuthor = ($) => ({
38
+ avatar: $("img.result_author").attr("src") || "",
39
+ nickname: $("h2").text().trim()
40
+ });
41
+ const parseStatistics = ($) => ({
42
+ likeCount: $("#trending-actions > .justify-content-start").text().trim(),
43
+ commentCount: $("#trending-actions > .justify-content-center").text().trim(),
44
+ shareCount: $("#trending-actions > .justify-content-end").text().trim()
45
+ });
46
+ const parseImages = ($) => {
47
+ const images = [];
48
+ $("ul.splide__list > li").each((_, img) => {
49
+ const href = $(img).find("a").attr("href");
50
+ if (href)
51
+ images.push(href);
52
+ });
53
+ return images;
54
+ };
55
+ const createImageResponse = ($, author, statistics, images, music) => ({
56
+ type: "image",
57
+ desc: $("p.maintext").text().trim(),
58
+ author,
59
+ statistics,
60
+ images,
61
+ ...(music && { music: { playUrl: [music] } })
62
+ });
63
+ const createVideoResponse = ($, author, statistics, video, music) => ({
64
+ type: "video",
65
+ desc: $("p.maintext").text().trim(),
66
+ author,
67
+ statistics,
68
+ video: { playAddr: [video] },
69
+ ...(music && { music: { playUrl: [music] } })
70
+ });
71
+ const createMusicResponse = (music, direct) => ({
72
+ type: "music",
73
+ music: { playUrl: [music] },
74
+ direct: direct || ""
75
+ });
76
+ const fetchTT = async (proxy) => {
77
+ try {
78
+ const { data } = await (0, axios_1.default)(api_1._ssstikurl, {
79
+ method: "GET",
80
+ headers: { "User-Agent": USER_AGENT },
81
+ ...createProxyAgent(proxy)
82
+ });
83
+ const ttValue = extractTTValue(data);
84
+ if (!ttValue) {
85
+ return {
86
+ status: "error",
87
+ message: constants_1.ERROR_MESSAGES.NETWORK_ERROR
88
+ };
89
+ }
90
+ return {
91
+ status: "success",
92
+ result: ttValue
93
+ };
94
+ }
95
+ catch (error) {
96
+ return {
97
+ status: "error",
98
+ message: error instanceof Error ? error.message : constants_1.ERROR_MESSAGES.NETWORK_ERROR
99
+ };
100
+ }
101
+ };
102
+ const SSSTik = async (url, proxy) => {
103
+ try {
104
+ if (!validateTikTokUrl(url)) {
105
+ return {
106
+ status: "error",
107
+ message: constants_1.ERROR_MESSAGES.INVALID_URL
108
+ };
109
+ }
110
+ const tt = await fetchTT(proxy);
111
+ if (tt.status !== "success") {
112
+ return {
113
+ status: "error",
114
+ message: tt.message
115
+ };
116
+ }
117
+ const response = await (0, async_retry_1.default)(async () => {
118
+ const res = await (0, axios_1.default)(api_1._ssstikapi, {
119
+ method: "POST",
120
+ headers: {
121
+ "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
122
+ Origin: api_1._ssstikurl,
123
+ Referer: `${api_1._ssstikurl}/en`,
124
+ "User-Agent": USER_AGENT
125
+ },
126
+ data: new URLSearchParams({
127
+ id: url,
128
+ locale: "en",
129
+ tt: tt.result
130
+ }),
131
+ ...createProxyAgent(proxy)
132
+ });
133
+ if (res.status === 200 && res.data) {
134
+ return res.data;
135
+ }
136
+ throw new Error(constants_1.ERROR_MESSAGES.NETWORK_ERROR);
137
+ }, {
138
+ retries: 20,
139
+ minTimeout: 200,
140
+ maxTimeout: 1000
141
+ });
142
+ const $ = (0, cheerio_1.load)(response);
143
+ const author = parseAuthor($);
144
+ const statistics = parseStatistics($);
145
+ const video = $("a.without_watermark").attr("href");
146
+ const music = $("a.music").attr("href");
147
+ const direct = $("a.music_direct").attr("href");
148
+ const images = parseImages($);
149
+ let result;
150
+ if (images.length > 0) {
151
+ result = createImageResponse($, author, statistics, images, music);
152
+ }
153
+ else if (video) {
154
+ result = createVideoResponse($, author, statistics, video, music);
155
+ }
156
+ else if (music) {
157
+ result = createMusicResponse(music, direct);
158
+ }
159
+ else {
160
+ return {
161
+ status: "error",
162
+ message: constants_1.ERROR_MESSAGES.NETWORK_ERROR
163
+ };
164
+ }
165
+ return {
166
+ status: "success",
167
+ result
168
+ };
169
+ }
170
+ catch (error) {
171
+ return {
172
+ status: "error",
173
+ message: error instanceof Error ? error.message : constants_1.ERROR_MESSAGES.NETWORK_ERROR
174
+ };
175
+ }
176
+ };
177
+ exports.SSSTik = SSSTik;
@@ -0,0 +1,3 @@
1
+ import { TiktokAPIResponse } from "../../types/downloader/tiktokApiDownloader";
2
+ export declare const handleRedirect: (url: string, proxy?: string) => Promise<string>;
3
+ export declare const TiktokAPI: (url: string, proxy?: string, showOriginalResponse?: boolean) => Promise<TiktokAPIResponse>;
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TiktokAPI = exports.handleRedirect = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const async_retry_1 = __importDefault(require("async-retry"));
9
+ const api_1 = require("../../constants/api");
10
+ const params_1 = require("../../constants/params");
11
+ const https_proxy_agent_1 = require("https-proxy-agent");
12
+ const socks_proxy_agent_1 = require("socks-proxy-agent");
13
+ const constants_1 = require("../../constants");
14
+ const TIKTOK_URL_REGEX = /https:\/\/(?:m|t|www|vm|vt|lite)?\.?tiktok\.com\/((?:.*\b(?:(?:usr|v|embed|user|video|photo)\/|\?shareId=|\&item_id=)(\d+))|\w+)/;
15
+ const USER_AGENT = "com.zhiliaoapp.musically/300904 (2018111632; U; Android 10; en_US; Pixel 4; Build/QQ3A.200805.001; Cronet/58.0.2991.0)";
16
+ const createProxyAgent = (proxy) => {
17
+ if (!proxy)
18
+ return {};
19
+ const isHttpProxy = proxy.startsWith("http") || proxy.startsWith("https");
20
+ const isSocksProxy = proxy.startsWith("socks");
21
+ if (!isHttpProxy && !isSocksProxy)
22
+ return {};
23
+ return {
24
+ httpsAgent: isHttpProxy
25
+ ? new https_proxy_agent_1.HttpsProxyAgent(proxy)
26
+ : new socks_proxy_agent_1.SocksProxyAgent(proxy)
27
+ };
28
+ };
29
+ const validateTikTokUrl = (url) => {
30
+ return TIKTOK_URL_REGEX.test(url);
31
+ };
32
+ const extractVideoId = (responseUrl) => {
33
+ const matches = responseUrl.match(/\d{17,21}/g);
34
+ return matches ? matches[0] : null;
35
+ };
36
+ const parseStatistics = (content) => ({
37
+ commentCount: content.statistics.comment_count,
38
+ likeCount: content.statistics.digg_count,
39
+ shareCount: content.statistics.share_count,
40
+ playCount: content.statistics.play_count,
41
+ downloadCount: content.statistics.download_count
42
+ });
43
+ const parseAuthor = (content) => ({
44
+ uid: content.author.uid,
45
+ username: content.author.unique_id,
46
+ uniqueId: content.author.unique_id,
47
+ nickname: content.author.nickname,
48
+ signature: content.author.signature,
49
+ region: content.author.region,
50
+ avatarThumb: content.author?.avatar_thumb?.url_list || [],
51
+ avatarMedium: content.author?.avatar_medium?.url_list || [],
52
+ url: `${api_1._tiktokDesktopUrl}/@${content.author.unique_id}`
53
+ });
54
+ const parseMusic = (content) => ({
55
+ id: content.music.id,
56
+ title: content.music.title,
57
+ author: content.music.author,
58
+ album: content.music.album,
59
+ playUrl: content.music?.play_url?.url_list || [],
60
+ coverLarge: content.music?.cover_large?.url_list || [],
61
+ coverMedium: content.music?.cover_medium?.url_list || [],
62
+ coverThumb: content.music?.cover_thumb?.url_list || [],
63
+ duration: content.music.duration,
64
+ isCommerceMusic: content.music.is_commerce_music,
65
+ isOriginalSound: content.music.is_original_sound,
66
+ isAuthorArtist: content.music.is_author_artist
67
+ });
68
+ const parseVideo = (content) => ({
69
+ ratio: content.video.ratio,
70
+ duration: content.video.duration,
71
+ playAddr: content.video?.play_addr?.url_list || [],
72
+ downloadAddr: content.video?.download_addr?.url_list || [],
73
+ cover: content.video?.cover?.url_list || [],
74
+ dynamicCover: content.video?.dynamic_cover?.url_list || [],
75
+ originCover: content.video?.origin_cover?.url_list || []
76
+ });
77
+ const parseTiktokData = (ID, data) => {
78
+ const content = data?.aweme_list?.find((v) => v.aweme_id === ID);
79
+ if (!content)
80
+ return { content: null };
81
+ return {
82
+ content,
83
+ statistics: parseStatistics(content),
84
+ author: parseAuthor(content),
85
+ music: parseMusic(content)
86
+ };
87
+ };
88
+ const fetchTiktokData = async (ID, proxy) => {
89
+ try {
90
+ const response = await (0, async_retry_1.default)(async () => {
91
+ const res = await (0, axios_1.default)((0, api_1._tiktokvFeed)((0, params_1._tiktokApiParams)({ aweme_id: ID })), {
92
+ method: "OPTIONS",
93
+ headers: { "User-Agent": USER_AGENT },
94
+ ...createProxyAgent(proxy)
95
+ });
96
+ if (res.data && res.data.status_code === 0) {
97
+ return res.data;
98
+ }
99
+ throw new Error(constants_1.ERROR_MESSAGES.NETWORK_ERROR);
100
+ }, {
101
+ retries: 20,
102
+ minTimeout: 200,
103
+ maxTimeout: 1000
104
+ });
105
+ return parseTiktokData(ID, response);
106
+ }
107
+ catch (error) {
108
+ console.error("Error fetching TikTok data:", error);
109
+ return null;
110
+ }
111
+ };
112
+ const createImageResponse = (content, author, statistics, music) => ({
113
+ status: "success",
114
+ result: {
115
+ type: "image",
116
+ id: content.aweme_id,
117
+ createTime: content.create_time,
118
+ desc: content.desc,
119
+ isTurnOffComment: content.item_comment_settings === 3,
120
+ hashtag: content.text_extra
121
+ .filter((x) => x.hashtag_name !== undefined)
122
+ .map((v) => v.hashtag_name),
123
+ isADS: content.is_ads,
124
+ author,
125
+ statistics,
126
+ images: content.image_post_info.images?.map((v) => v?.display_image?.url_list[0]) || [],
127
+ music
128
+ }
129
+ });
130
+ const createVideoResponse = (content, author, statistics, music) => ({
131
+ status: "success",
132
+ result: {
133
+ type: "video",
134
+ id: content.aweme_id,
135
+ createTime: content.create_time,
136
+ desc: content.desc,
137
+ isTurnOffComment: content.item_comment_settings === 3,
138
+ hashtag: content.text_extra
139
+ .filter((x) => x.hashtag_name !== undefined)
140
+ .map((v) => v.hashtag_name),
141
+ isADS: content.is_ads,
142
+ author,
143
+ statistics,
144
+ video: parseVideo(content),
145
+ music
146
+ }
147
+ });
148
+ const handleRedirect = async (url, proxy) => {
149
+ try {
150
+ const response = await (0, axios_1.default)(url, {
151
+ method: "HEAD",
152
+ maxRedirects: 5,
153
+ validateStatus: (status) => status >= 200 && status < 400,
154
+ ...createProxyAgent(proxy)
155
+ });
156
+ const finalUrl = response.request.res.responseUrl;
157
+ return finalUrl.split("?")[0];
158
+ }
159
+ catch (error) {
160
+ console.error("Error handling redirect:", error);
161
+ return url;
162
+ }
163
+ };
164
+ exports.handleRedirect = handleRedirect;
165
+ const TiktokAPI = async (url, proxy, showOriginalResponse) => {
166
+ try {
167
+ if (!validateTikTokUrl(url)) {
168
+ return {
169
+ status: "error",
170
+ message: constants_1.ERROR_MESSAGES.INVALID_URL
171
+ };
172
+ }
173
+ url = url.replace("https://vm", "https://vt");
174
+ const request = await (0, axios_1.default)(url, {
175
+ method: "GET",
176
+ maxRedirects: 0,
177
+ headers: {
178
+ "User-Agent": USER_AGENT,
179
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
180
+ "Accept-Language": "en-US,en;q=0.9",
181
+ },
182
+ ...createProxyAgent(proxy),
183
+ validateStatus: (status) => status >= 200 && status < 400,
184
+ });
185
+ const redirectUrl = request.headers.location ??
186
+ request.request?.res?.responseUrl ??
187
+ url;
188
+ const videoId = extractVideoId(redirectUrl);
189
+ if (!videoId) {
190
+ return {
191
+ status: "error",
192
+ message: constants_1.ERROR_MESSAGES.INVALID_URL
193
+ };
194
+ }
195
+ const data = await fetchTiktokData(videoId, proxy);
196
+ if (!data?.content) {
197
+ return {
198
+ status: "error",
199
+ message: constants_1.ERROR_MESSAGES.NETWORK_ERROR
200
+ };
201
+ }
202
+ const { content, author, statistics, music } = data;
203
+ const response = content.image_post_info
204
+ ? createImageResponse(content, author, statistics, music)
205
+ : createVideoResponse(content, author, statistics, music);
206
+ if (showOriginalResponse) {
207
+ return {
208
+ status: "success",
209
+ resultNotParsed: data
210
+ };
211
+ }
212
+ return response;
213
+ }
214
+ catch (error) {
215
+ return {
216
+ status: "error",
217
+ message: error instanceof Error ? error.message : constants_1.ERROR_MESSAGES.NETWORK_ERROR
218
+ };
219
+ }
220
+ };
221
+ exports.TiktokAPI = TiktokAPI;
@@ -0,0 +1,7 @@
1
+ import { TiktokCollectionResponse } from "../../types/get/getCollection";
2
+ export declare const getCollection: (collectionId: string, proxy?: string, page?: number, count?: number) => Promise<TiktokCollectionResponse>;
3
+ export declare const Collection: (collectionIdOrUrl: string, options?: {
4
+ page?: number;
5
+ proxy?: string;
6
+ count?: number;
7
+ }) => Promise<TiktokCollectionResponse>;
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Collection = exports.getCollection = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const api_1 = require("../../constants/api");
9
+ const params_1 = require("../../constants/params");
10
+ const https_proxy_agent_1 = require("https-proxy-agent");
11
+ const socks_proxy_agent_1 = require("socks-proxy-agent");
12
+ const constants_1 = require("../../constants");
13
+ const async_retry_1 = __importDefault(require("async-retry"));
14
+ const tiktokAPIDownloader_1 = require("../downloader/tiktokAPIDownloader");
15
+ const urlExtractors_1 = require("../urlExtractors");
16
+ const createProxyAgent = (proxy) => {
17
+ if (!proxy)
18
+ return {};
19
+ if (proxy.startsWith("socks")) {
20
+ return {
21
+ httpsAgent: new socks_proxy_agent_1.SocksProxyAgent(proxy)
22
+ };
23
+ }
24
+ return {
25
+ httpsAgent: new https_proxy_agent_1.HttpsProxyAgent(proxy)
26
+ };
27
+ };
28
+ const getCollection = async (collectionId, proxy, page = 1, count = 5) => {
29
+ try {
30
+ const response = await (0, async_retry_1.default)(async () => {
31
+ const res = await (0, axios_1.default)((0, api_1._tiktokGetCollection)((0, params_1._getCollectionParams)(collectionId, page, count)), {
32
+ method: "GET",
33
+ headers: {
34
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
35
+ Accept: "*/*",
36
+ "Accept-Language": "en-US,en;q=0.7",
37
+ Referer: "https://www.tiktok.com/",
38
+ Origin: "https://www.tiktok.com"
39
+ },
40
+ ...createProxyAgent(proxy)
41
+ });
42
+ if (res.data && res.data.statusCode === 0) {
43
+ return res.data;
44
+ }
45
+ throw new Error(constants_1.ERROR_MESSAGES.NETWORK_ERROR);
46
+ }, {
47
+ retries: 20,
48
+ minTimeout: 200,
49
+ maxTimeout: 1000
50
+ });
51
+ return {
52
+ status: "success",
53
+ result: {
54
+ hasMore: response.hasMore,
55
+ itemList: response.itemList || [],
56
+ extra: response.extra
57
+ }
58
+ };
59
+ }
60
+ catch (error) {
61
+ return {
62
+ status: "error",
63
+ message: error instanceof Error ? error.message : constants_1.ERROR_MESSAGES.NETWORK_ERROR
64
+ };
65
+ }
66
+ };
67
+ exports.getCollection = getCollection;
68
+ const Collection = async (collectionIdOrUrl, options) => {
69
+ try {
70
+ const processedUrl = collectionIdOrUrl.startsWith("http")
71
+ ? await (0, tiktokAPIDownloader_1.handleRedirect)(collectionIdOrUrl, options?.proxy)
72
+ : collectionIdOrUrl;
73
+ const collectionId = (0, urlExtractors_1.extractCollectionId)(processedUrl);
74
+ if (!collectionId) {
75
+ return {
76
+ status: "error",
77
+ message: "Invalid collection ID or URL format"
78
+ };
79
+ }
80
+ const response = await (0, axios_1.default)((0, api_1._tiktokGetCollection)((0, params_1._getCollectionParams)(collectionId, options.page, options.count)), {
81
+ method: "GET",
82
+ headers: {
83
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
84
+ Accept: "*/*",
85
+ "Accept-Language": "en-US,en;q=0.7",
86
+ Referer: "https://www.tiktok.com/",
87
+ Origin: "https://www.tiktok.com"
88
+ },
89
+ ...createProxyAgent(options?.proxy)
90
+ });
91
+ if (response.data && response.data.status_code === 0) {
92
+ const data = response.data;
93
+ return {
94
+ status: "success",
95
+ result: {
96
+ itemList: data.itemList || [],
97
+ hasMore: data.hasMore
98
+ }
99
+ };
100
+ }
101
+ return {
102
+ status: "error",
103
+ message: constants_1.ERROR_MESSAGES.NETWORK_ERROR
104
+ };
105
+ }
106
+ catch (error) {
107
+ return {
108
+ status: "error",
109
+ message: error instanceof Error ? error.message : constants_1.ERROR_MESSAGES.NETWORK_ERROR
110
+ };
111
+ }
112
+ };
113
+ exports.Collection = Collection;
@@ -0,0 +1,2 @@
1
+ import { TiktokVideoCommentsResponse } from "../../types/get/getComments";
2
+ export declare const getComments: (url: string, proxy?: string, commentLimit?: number) => Promise<TiktokVideoCommentsResponse>;
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getComments = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const api_1 = require("../../constants/api");
9
+ const params_1 = require("../../constants/params");
10
+ const https_proxy_agent_1 = require("https-proxy-agent");
11
+ const socks_proxy_agent_1 = require("socks-proxy-agent");
12
+ const TiktokURLregex = /https:\/\/(?:m|www|vm|vt|lite)?\.?tiktok\.com\/((?:.*\b(?:(?:usr|v|embed|user|video|photo)\/|\?shareId=|\&item_id=)(\d+))|\w+)/;
13
+ const getComments = async (url, proxy, commentLimit) => new Promise(async (resolve) => {
14
+ if (!TiktokURLregex.test(url)) {
15
+ return resolve({
16
+ status: "error",
17
+ message: "Invalid Tiktok URL. Make sure your url is correct!"
18
+ });
19
+ }
20
+ url = url.replace("https://vm", "https://vt");
21
+ (0, axios_1.default)(url, {
22
+ method: "HEAD",
23
+ httpsAgent: (proxy &&
24
+ (proxy.startsWith("http") || proxy.startsWith("https")
25
+ ? new https_proxy_agent_1.HttpsProxyAgent(proxy)
26
+ : proxy.startsWith("socks")
27
+ ? new socks_proxy_agent_1.SocksProxyAgent(proxy)
28
+ : undefined)) ||
29
+ undefined
30
+ })
31
+ .then(async ({ request }) => {
32
+ const { responseUrl } = request.res;
33
+ let ID = responseUrl.match(/\d{17,21}/g);
34
+ if (ID === null)
35
+ return resolve({
36
+ status: "error",
37
+ message: "Failed to fetch tiktok url. Make sure your tiktok url is correct!"
38
+ });
39
+ ID = ID[0];
40
+ const resultComments = await parseComments(ID, commentLimit, proxy);
41
+ if (!resultComments.comments.length)
42
+ return resolve({
43
+ status: "error",
44
+ message: "No comments found!"
45
+ });
46
+ return resolve({
47
+ status: "success",
48
+ result: resultComments.comments,
49
+ totalComments: resultComments.total
50
+ });
51
+ })
52
+ .catch((e) => resolve({ status: "error", message: e.message }));
53
+ });
54
+ exports.getComments = getComments;
55
+ const requestComments = async (id, cursor = 0, proxy) => {
56
+ const { data } = await (0, axios_1.default)((0, api_1._tiktokGetComments)((0, params_1._getCommentsParams)(id, cursor)), {
57
+ method: "GET",
58
+ headers: {
59
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
60
+ },
61
+ httpsAgent: (proxy &&
62
+ (proxy.startsWith("http") || proxy.startsWith("https")
63
+ ? new https_proxy_agent_1.HttpsProxyAgent(proxy)
64
+ : proxy.startsWith("socks")
65
+ ? new socks_proxy_agent_1.SocksProxyAgent(proxy)
66
+ : undefined)) ||
67
+ undefined
68
+ });
69
+ return data;
70
+ };
71
+ const parseComments = async (id, commentLimit, proxy) => {
72
+ const comments = [];
73
+ let cursor = 0;
74
+ let total = 0;
75
+ let hasMore = true;
76
+ while (hasMore) {
77
+ const result = await requestComments(id, cursor, proxy);
78
+ hasMore = result.has_more === 1;
79
+ cursor = hasMore ? result.cursor : 0;
80
+ if (result.comments) {
81
+ result.comments.forEach((v) => {
82
+ const comment = {
83
+ cid: v.cid,
84
+ text: v.text,
85
+ commentLanguage: v.comment_language,
86
+ createTime: v.create_time,
87
+ likeCount: v.digg_count,
88
+ isAuthorLiked: v.is_author_digged,
89
+ isCommentTranslatable: v.is_comment_translatable,
90
+ replyCommentTotal: v.reply_comment_total,
91
+ user: {
92
+ uid: v.user.uid,
93
+ avatarThumb: v.user.avatar_thumb.url_list,
94
+ nickname: v.user.nickname,
95
+ username: v.user.unique_id,
96
+ isVerified: v.user.custom_verify !== ""
97
+ },
98
+ url: v.share_info?.url || "",
99
+ replyComment: []
100
+ };
101
+ if (v.reply_comment !== null) {
102
+ v.reply_comment.forEach((v) => {
103
+ comment.replyComment.push({
104
+ cid: v.cid,
105
+ text: v.text,
106
+ commentLanguage: v.comment_language,
107
+ createTime: v.create_time,
108
+ likeCount: v.digg_count,
109
+ isAuthorLiked: v.is_author_digged,
110
+ isCommentTranslatable: v.is_comment_translatable,
111
+ replyCommentTotal: v.reply_comment_total,
112
+ user: {
113
+ uid: v.user.uid,
114
+ avatarThumb: v.user.avatar_thumb.url_list,
115
+ nickname: v.user.nickname,
116
+ username: v.user.unique_id,
117
+ isVerified: v.user.custom_verify !== ""
118
+ },
119
+ url: v.share_info?.url || "",
120
+ replyComment: []
121
+ });
122
+ total++;
123
+ });
124
+ }
125
+ total++;
126
+ comments.push(comment);
127
+ });
128
+ }
129
+ if (commentLimit && comments.length >= commentLimit) {
130
+ hasMore = false;
131
+ break;
132
+ }
133
+ }
134
+ const response = commentLimit ? comments.slice(0, commentLimit) : comments;
135
+ return {
136
+ total: response.length,
137
+ comments: response
138
+ };
139
+ };
@@ -0,0 +1,2 @@
1
+ import { TiktokMusicDetailResponse } from "../../types/get/getMusicDetail";
2
+ export declare const getMusicDetail: (musicIdOrUrl: string, cookie: string | any[], proxy?: string) => Promise<TiktokMusicDetailResponse>;