@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,99 @@
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.SearchLive = 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 socks_proxy_agent_1 = require("socks-proxy-agent");
11
+ const https_proxy_agent_1 = require("https-proxy-agent");
12
+ const SearchLive = async (keyword, cookie, page = 1, proxy) => new Promise(async (resolve) => {
13
+ if (!cookie) {
14
+ return resolve({
15
+ status: "error",
16
+ message: "Cookie is required!"
17
+ });
18
+ }
19
+ (0, axios_1.default)((0, api_1._tiktokSearchLiveFull)((0, params_1._liveSearchParams)(keyword, page)), {
20
+ method: "GET",
21
+ headers: {
22
+ "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",
23
+ cookie: typeof cookie === "object"
24
+ ? cookie.map((v) => `${v.name}=${v.value}`).join("; ")
25
+ : cookie
26
+ },
27
+ httpsAgent: (proxy &&
28
+ (proxy.startsWith("http") || proxy.startsWith("https")
29
+ ? new https_proxy_agent_1.HttpsProxyAgent(proxy)
30
+ : proxy.startsWith("socks")
31
+ ? new socks_proxy_agent_1.SocksProxyAgent(proxy)
32
+ : undefined)) ||
33
+ undefined
34
+ })
35
+ .then(({ data }) => {
36
+ if (data.status_code === 2483)
37
+ return resolve({ status: "error", message: "Invalid cookie!" });
38
+ if (data.status_code !== 0)
39
+ return resolve({
40
+ status: "error",
41
+ message: data.status_msg ||
42
+ "An error occurred! Please report this issue to the developer."
43
+ });
44
+ if (!data.data)
45
+ return resolve({ status: "error", message: "Live not found!" });
46
+ const result = [];
47
+ data.data.forEach((v) => {
48
+ const content = JSON.parse(v.live_info.raw_data);
49
+ const liveInfo = {
50
+ id: content.id,
51
+ title: content.title,
52
+ cover: content.cover?.url_list || [],
53
+ squareCover: content.square_cover_img?.url_list || [],
54
+ rectangleCover: content.rectangle_cover_img?.url_list || [],
55
+ liveTypeThirdParty: content.live_type_third_party,
56
+ hashtag: content.hashtag?.title || "",
57
+ startTime: content.start_time,
58
+ stats: {
59
+ totalUser: content.stats.total_user,
60
+ viewerCount: content.user_count,
61
+ likeCount: content.like_count
62
+ },
63
+ owner: {
64
+ uid: content.owner.id,
65
+ nickname: content.owner.nickname,
66
+ username: content.owner.display_id,
67
+ signature: content.owner.bio_description,
68
+ avatarThumb: content.owner.avatar_thumb?.url_list || [],
69
+ avatarMedium: content.owner.avatar_medium?.url_list || [],
70
+ avatarLarge: content.owner.avatar_large?.url_list || [],
71
+ modifyTime: content.owner.modify_time,
72
+ stats: {
73
+ followingCount: content.owner.follow_info.following_count,
74
+ followerCount: content.owner.follow_info.follower_count
75
+ },
76
+ isVerified: content.owner?.authentication_info?.custom_verify ===
77
+ "verified account" || false
78
+ }
79
+ };
80
+ const roomInfo = {
81
+ hasCommerceGoods: v.live_info.room_info.has_commerce_goods,
82
+ isBattle: v.live_info.room_info.is_battle
83
+ };
84
+ result.push({ roomInfo, liveInfo });
85
+ });
86
+ if (!result.length)
87
+ return resolve({ status: "error", message: "Live not found!" });
88
+ resolve({
89
+ status: "success",
90
+ result,
91
+ page,
92
+ totalResults: result.length
93
+ });
94
+ })
95
+ .catch((e) => {
96
+ resolve({ status: "error", message: e.message });
97
+ });
98
+ });
99
+ exports.SearchLive = SearchLive;
@@ -0,0 +1,2 @@
1
+ import { TiktokUserSearchResponse } from "../../types/search/userSearch";
2
+ export declare const SearchUser: (username: string, cookie: string | any[], page?: number, proxy?: string) => Promise<TiktokUserSearchResponse>;
@@ -0,0 +1,76 @@
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.SearchUser = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const api_1 = require("../../constants/api");
9
+ const https_proxy_agent_1 = require("https-proxy-agent");
10
+ const socks_proxy_agent_1 = require("socks-proxy-agent");
11
+ const tiktokService_1 = require("../../services/tiktokService");
12
+ const headers_1 = require("../../constants/headers");
13
+ const SearchUser = (username, cookie, page = 1, proxy) => new Promise(async (resolve) => {
14
+ if (!cookie) {
15
+ return resolve({
16
+ status: "error",
17
+ message: "Cookie is required!"
18
+ });
19
+ }
20
+ const Tiktok = new tiktokService_1.TiktokService();
21
+ (0, axios_1.default)(Tiktok.generateURLXbogus(username, page), {
22
+ method: "GET",
23
+ headers: {
24
+ "User-Agent": headers_1.webUserAgent,
25
+ cookie: typeof cookie === "object"
26
+ ? cookie.map((v) => `${v.name}=${v.value}`).join("; ")
27
+ : cookie
28
+ },
29
+ httpsAgent: (proxy &&
30
+ (proxy.startsWith("http") || proxy.startsWith("https")
31
+ ? new https_proxy_agent_1.HttpsProxyAgent(proxy)
32
+ : proxy.startsWith("socks")
33
+ ? new socks_proxy_agent_1.SocksProxyAgent(proxy)
34
+ : undefined)) ||
35
+ undefined
36
+ })
37
+ .then(({ data }) => {
38
+ if (data.status_code === 2483)
39
+ return resolve({ status: "error", message: "Invalid cookie!" });
40
+ if (data.status_code !== 0)
41
+ return resolve({
42
+ status: "error",
43
+ message: data.status_msg ||
44
+ "An error occurred! Please report this issue to the developer."
45
+ });
46
+ if (!data.user_list)
47
+ return resolve({ status: "error", message: "User not found!" });
48
+ const result = [];
49
+ for (let i = 0; i < data.user_list.length; i++) {
50
+ const user = data.user_list[i];
51
+ result.push({
52
+ uid: user.user_info.uid,
53
+ username: user.user_info.unique_id,
54
+ nickname: user.user_info.nickname,
55
+ signature: user.user_info.signature,
56
+ followerCount: user.user_info.follower_count,
57
+ avatarThumb: user.user_info.avatar_thumb,
58
+ isVerified: user.custom_verify !== "",
59
+ secUid: user.user_info.sec_uid,
60
+ url: `${api_1._tiktokDesktopUrl}/@${user.user_info.unique_id}`
61
+ });
62
+ }
63
+ if (!result.length)
64
+ return resolve({ status: "error", message: "User not found!" });
65
+ resolve({
66
+ status: "success",
67
+ result,
68
+ page,
69
+ totalResults: result.length
70
+ });
71
+ })
72
+ .catch((e) => {
73
+ resolve({ status: "error", message: e.message });
74
+ });
75
+ });
76
+ exports.SearchUser = SearchUser;
@@ -0,0 +1,2 @@
1
+ import { TiktokVideoSearchResponse } from "../../types/search/videoSearch";
2
+ export declare const SearchVideo: (keyword: string, cookie: string | any[], page?: number, proxy?: string) => Promise<TiktokVideoSearchResponse>;
@@ -0,0 +1,140 @@
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.SearchVideo = 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 socks_proxy_agent_1 = require("socks-proxy-agent");
11
+ const https_proxy_agent_1 = require("https-proxy-agent");
12
+ const async_retry_1 = __importDefault(require("async-retry"));
13
+ const SearchVideo = async (keyword, cookie, page = 1, proxy) => new Promise(async (resolve) => {
14
+ if (!cookie) {
15
+ return resolve({
16
+ status: "error",
17
+ message: "Cookie is required!"
18
+ });
19
+ }
20
+ try {
21
+ const data = await requestVideoSearch(keyword, page, cookie, proxy);
22
+ if (data.status_code === 2483)
23
+ return resolve({ status: "error", message: "Invalid cookie!" });
24
+ if (data.status_code !== 0)
25
+ return resolve({
26
+ status: "error",
27
+ message: data.status_msg ||
28
+ "An error occurred! Please report this issue to the developer."
29
+ });
30
+ if (!data.item_list)
31
+ return resolve({ status: "error", message: "Video not found!" });
32
+ const result = [];
33
+ data.item_list.forEach((v) => {
34
+ const video = {
35
+ id: v.video.id,
36
+ ratio: v.video.ratio,
37
+ cover: v.video.cover,
38
+ originCover: v.video.originCover,
39
+ dynamicCover: v.video.dynamicCover,
40
+ playAddr: v.video.playAddr,
41
+ downloadAddr: v.video.downloadAddr,
42
+ format: v.video.format
43
+ };
44
+ const stats = {
45
+ likeCount: v.stats.diggCount,
46
+ shareCount: v.stats.shareCount,
47
+ commentCount: v.stats.commentCount,
48
+ playCount: v.stats.playCount,
49
+ collectCount: v.stats.collectCount
50
+ };
51
+ const author = {
52
+ id: v.author.id,
53
+ uniqueId: v.author.uniqueId,
54
+ nickname: v.author.nickname,
55
+ avatarThumb: v.author.avatarThumb,
56
+ avatarMedium: v.author.avatarMedium,
57
+ avatarLarger: v.author.avatarLarger,
58
+ signature: v.author.signature,
59
+ verified: v.author.verified,
60
+ secUid: v.author.secUid,
61
+ openFavorite: v.author.openFavorite,
62
+ privateAccount: v.author.privateAccount,
63
+ isADVirtual: v.author.isADVirtual,
64
+ tiktokSeller: v.author.ttSeller,
65
+ isEmbedBanned: v.author.isEmbedBanned
66
+ };
67
+ const music = {
68
+ id: v.music.id,
69
+ title: v.music.title,
70
+ playUrl: v.music.playUrl,
71
+ coverThumb: v.music.coverThumb,
72
+ coverMedium: v.music.coverMedium,
73
+ coverLarge: v.music.coverLarge,
74
+ authorName: v.music.authorName,
75
+ original: v.music.original,
76
+ album: v.music.album,
77
+ duration: v.music.duration,
78
+ isCopyrighted: v.music.isCopyrighted
79
+ };
80
+ result.push({
81
+ id: v.id,
82
+ desc: v.desc,
83
+ createTime: v.createTime,
84
+ author,
85
+ stats,
86
+ video,
87
+ music
88
+ });
89
+ });
90
+ if (!result.length)
91
+ return resolve({ status: "error", message: "Video not found!" });
92
+ resolve({
93
+ status: "success",
94
+ result,
95
+ page,
96
+ totalResults: result.length
97
+ });
98
+ }
99
+ catch (e) {
100
+ resolve({ status: "error", message: e.message });
101
+ }
102
+ });
103
+ exports.SearchVideo = SearchVideo;
104
+ const requestVideoSearch = async (keyword, page, cookie, proxy) => {
105
+ return (0, async_retry_1.default)(async (bail, attempt) => {
106
+ try {
107
+ const { data } = await (0, axios_1.default)((0, api_1._tiktokSearchVideoFull)((0, params_1._videoSearchParams)(keyword, page)), {
108
+ method: "GET",
109
+ headers: {
110
+ "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",
111
+ cookie: typeof cookie === "object"
112
+ ? cookie.map((v) => `${v.name}=${v.value}`).join("; ")
113
+ : cookie
114
+ },
115
+ httpsAgent: (proxy &&
116
+ (proxy.startsWith("http") || proxy.startsWith("https")
117
+ ? new https_proxy_agent_1.HttpsProxyAgent(proxy)
118
+ : proxy.startsWith("socks")
119
+ ? new socks_proxy_agent_1.SocksProxyAgent(proxy)
120
+ : undefined)) ||
121
+ undefined
122
+ });
123
+ if (data === "") {
124
+ throw new Error("Empty response");
125
+ }
126
+ return data;
127
+ }
128
+ catch (error) {
129
+ throw error;
130
+ }
131
+ }, {
132
+ retries: 10,
133
+ minTimeout: 1000,
134
+ maxTimeout: 5000,
135
+ factor: 2,
136
+ onRetry: (error, attempt) => {
137
+ console.log(`Retry attempt ${attempt} due to: ${error}`);
138
+ }
139
+ });
140
+ };
@@ -0,0 +1,3 @@
1
+ export declare const extractMusicId: (musicIdOrUrl: string) => string | null;
2
+ export declare const extractCollectionId: (input: string) => string | null;
3
+ export declare const extractPlaylistId: (input: string) => string | null;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractPlaylistId = exports.extractCollectionId = exports.extractMusicId = void 0;
4
+ const extractMusicId = (musicIdOrUrl) => {
5
+ if (!musicIdOrUrl || typeof musicIdOrUrl !== "string") {
6
+ return null;
7
+ }
8
+ const trimmed = musicIdOrUrl.trim();
9
+ if (/^\d+$/.test(trimmed)) {
10
+ return trimmed;
11
+ }
12
+ const urlPattern = /tiktok\.com\/music\/[^\/\-]*-?(\d+)/i;
13
+ const match = trimmed.match(urlPattern);
14
+ if (match && match[1]) {
15
+ return match[1];
16
+ }
17
+ return null;
18
+ };
19
+ exports.extractMusicId = extractMusicId;
20
+ const extractCollectionId = (input) => {
21
+ if (/^\d+$/.test(input)) {
22
+ return input;
23
+ }
24
+ const urlPattern = /collection\/[^\/\-]*-?(\d+)/i;
25
+ const match = input.match(urlPattern);
26
+ return match ? match[1] : null;
27
+ };
28
+ exports.extractCollectionId = extractCollectionId;
29
+ const extractPlaylistId = (input) => {
30
+ if (/^\d+$/.test(input)) {
31
+ return input;
32
+ }
33
+ const urlPattern = /playlist\/[^\/\-]*-?(\d+)/i;
34
+ const match = input.match(urlPattern);
35
+ return match ? match[1] : null;
36
+ };
37
+ exports.extractPlaylistId = extractPlaylistId;
@@ -0,0 +1 @@
1
+ export declare const validateCookie: (cookie: string | any[]) => boolean;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateCookie = void 0;
4
+ const validateCookie = (cookie) => {
5
+ if (!cookie)
6
+ return false;
7
+ if (typeof cookie === "string")
8
+ return cookie.length > 0;
9
+ if (Array.isArray(cookie))
10
+ return cookie.length > 0;
11
+ return false;
12
+ };
13
+ exports.validateCookie = validateCookie;
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@nxgiang/tiktok-api",
3
+ "version": "1.3.7",
4
+ "description": "Scraper for downloading media in the form of videos, images and audio from Tiktok. Also for stalking Tiktok Users, getting user posts, likes, comments, followers and following.",
5
+ "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "cli": "[ -d ./lib ] || npm run build && ts-node lib/cli/index.js"
10
+ },
11
+ "bin": {
12
+ "tiktokdl": "./lib/cli/index.js"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/TobyG74/tiktok-api-dl.git"
17
+ },
18
+ "keywords": [
19
+ "tiktok-api",
20
+ "tiktok-downloader",
21
+ "tiktok-dl",
22
+ "tiktok-nowatermark",
23
+ "tiktok",
24
+ "musically",
25
+ "tiktokv",
26
+ "tiktok-user",
27
+ "tiktok-stalk"
28
+ ],
29
+ "author": "Tobz",
30
+ "license": "ISC",
31
+ "bugs": {
32
+ "url": "https://github.com/TobyG74/tiktok-api-dl/issues"
33
+ },
34
+ "homepage": "https://github.com/TobyG74/tiktok-api-dl#readme",
35
+ "dependencies": {
36
+ "async-retry": "^1.3.3",
37
+ "axios": "^1.3.4",
38
+ "chalk": "^4.1.2",
39
+ "cheerio": "^1.0.0-rc.12",
40
+ "commander": "^11.0.0",
41
+ "crypto-js": "^4.2.0",
42
+ "https-proxy-agent": "^7.0.5",
43
+ "jsdom": "^26.0.0",
44
+ "node-fetch": "^2.7.0",
45
+ "qs": "^6.12.0",
46
+ "socks-proxy-agent": "^8.0.4",
47
+ "ts-node": "^10.9.2",
48
+ "uuid": "^10.0.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/async-retry": "^1.4.9",
52
+ "@types/cheerio": "^0.22.31",
53
+ "@types/node": "^18.15.11",
54
+ "@types/qs": "^6.9.17",
55
+ "typescript": "^5.0.3"
56
+ },
57
+ "peerDependencies": {
58
+ "canvas": "^3.1.2"
59
+ }
60
+ }
@@ -0,0 +1,73 @@
1
+ import Tiktok from "../src/index"
2
+
3
+ async function testCollection() {
4
+ try {
5
+ // You can use either a collection ID or URL
6
+ const collectionId = "7507916135931218695"
7
+ const collectionUrl =
8
+ "https://www.tiktok.com/@getrex.co.nz/collection/big%20back-7507916135931218695"
9
+ const collectionShareableLink = "https://vt.tiktok.com/ZShvmqNjQ/"
10
+
11
+ console.log("Testing Collection method...")
12
+ const result = await Tiktok.Collection(collectionId, {
13
+ page: 1,
14
+ count: 5, // Optional: Number of items to fetch
15
+ proxy: undefined // Optional: Add your proxy if needed
16
+ })
17
+
18
+ if (result.status === "success" && result.result) {
19
+ console.log("\nCollection fetched successfully!")
20
+ console.log("========================")
21
+ console.log("Collection Overview:")
22
+ console.log("========================")
23
+ console.log(`Total items fetched: ${result.result.itemList.length}`)
24
+ console.log(`Has more items: ${result.result.hasMore}`)
25
+
26
+ // Log all items
27
+ result.result.itemList.forEach((item, index) => {
28
+ console.log(`\nItem ${index + 1}:`)
29
+ console.log("-------------------")
30
+ console.log(`ID: ${item.id}`)
31
+ console.log(`Description: ${item.desc}`)
32
+ console.log(`Author: ${item.author.nickname}`)
33
+ console.log(
34
+ `Created: ${new Date(item.createTime * 1000).toLocaleString()}`
35
+ )
36
+
37
+ // Log video URL
38
+ if (item.video?.playAddr?.[0]) {
39
+ console.log(`Video URL: ${item.video.playAddr[0]}`)
40
+ } else {
41
+ console.log("No video URL available")
42
+ }
43
+
44
+ // Log item statistics
45
+ if (item.statistics) {
46
+ console.log("\nStatistics:")
47
+ console.log(`- Likes: ${item.statistics.likeCount || 0}`)
48
+ console.log(`- Comments: ${item.statistics.commentCount || 0}`)
49
+ console.log(`- Shares: ${item.statistics.shareCount || 0}`)
50
+ console.log(`- Plays: ${item.statistics.playCount || 0}`)
51
+ }
52
+
53
+ // Log hashtags if available
54
+ if (item.textExtra?.length > 0) {
55
+ console.log("\nHashtags:")
56
+ item.textExtra.forEach((tag) => {
57
+ if (tag.hashtagName) {
58
+ console.log(`- #${tag.hashtagName}`)
59
+ }
60
+ })
61
+ }
62
+ console.log("========================")
63
+ })
64
+ } else {
65
+ console.error("Error:", result.message)
66
+ }
67
+ } catch (error) {
68
+ console.error("Test failed:", error)
69
+ }
70
+ }
71
+
72
+ // Run the test
73
+ testCollection()
@@ -0,0 +1,54 @@
1
+ // Test for Tiktok Video Comments
2
+ import Tiktok from "../src/index"
3
+
4
+ async function testComments() {
5
+ try {
6
+ const url = "https://www.tiktok.com/@letuankhang2002/video/7578120269450071304?is_from_webapp=1&sender_device=pc" // Change to a valid TikTok video URL
7
+ const result = await Tiktok.GetVideoComments(url, {
8
+ commentLimit: 1000,
9
+ proxy: undefined
10
+ })
11
+ if (result.status === "success" && result.result) {
12
+ console.log("\nComments fetched successfully!")
13
+ console.log("========================")
14
+ console.log("Comments Overview:")
15
+ console.log("========================")
16
+ console.log(`Total comments fetched: ${result.result.length}`)
17
+ // Log all comments
18
+ result.result.forEach((comment, index) => {
19
+ console.log(`\nComment ${index + 1}:`)
20
+ console.log("-------------------")
21
+ console.log(`ID: ${comment.cid}`)
22
+ if (comment.user) {
23
+ console.log(
24
+ `Author: ${comment.user.nickname} (@${comment.user.username})`
25
+ )
26
+ console.log(`Verified: ${comment.user.isVerified ? "Yes" : "No"}`)
27
+ }
28
+ console.log(`Text: ${comment.text}`)
29
+ if (comment.createTime) {
30
+ console.log(
31
+ `Created: ${new Date(comment.createTime * 1000).toLocaleString()}`
32
+ )
33
+ }
34
+ // Log comment statistics
35
+ if (typeof comment.likeCount !== "undefined") {
36
+ console.log("\nStatistics:")
37
+ console.log(`- Likes: ${comment.likeCount}`)
38
+ }
39
+ if (typeof comment.replyCommentTotal !== "undefined") {
40
+ console.log(`- Replies: ${comment.replyCommentTotal}`)
41
+ }
42
+ if (comment.isAuthorLiked) console.log("👍 Liked by author")
43
+ if (comment.isCommentTranslatable) console.log("🌐 Translatable")
44
+ console.log("========================")
45
+ })
46
+ } else {
47
+ console.error("Error:", result.message)
48
+ }
49
+ } catch (error) {
50
+ console.error("Test failed:", error)
51
+ }
52
+ }
53
+
54
+ testComments()
@@ -0,0 +1,49 @@
1
+ // Test for Tiktok Downloader v1
2
+ import Tiktok from "../src/index"
3
+
4
+ async function testDownloaderV1() {
5
+ try {
6
+ const url = "https://www.tiktok.com/@tobz2k19/video/7451777267107187986" // Change to a valid TikTok video URL
7
+ console.log(`\nTesting Downloader version: v1`)
8
+ const result = await Tiktok.Downloader(url, {
9
+ version: "v1",
10
+ proxy: undefined
11
+ })
12
+ if (result.status === "success" && result.result) {
13
+ const r = result.result
14
+ console.log(`Type: ${r.type}`)
15
+ console.log(`ID: ${r.id}`)
16
+ console.log(`Description: ${r.desc}`)
17
+ if (r.author) {
18
+ console.log(`Author: ${r.author.nickname}`)
19
+ }
20
+ if (r.statistics) {
21
+ console.log("Statistics:")
22
+ console.log(`- Likes: ${r.statistics.likeCount}`)
23
+ console.log(`- Comments: ${r.statistics.commentCount}`)
24
+ console.log(`- Shares: ${r.statistics.shareCount}`)
25
+ console.log(`- Plays: ${r.statistics.playCount}`)
26
+ }
27
+ if (r.video?.playAddr?.length) {
28
+ console.log(`Video URL: ${r.video.playAddr[0]}`)
29
+ }
30
+ if (r.images?.length) {
31
+ console.log(`Images: ${r.images.join(", ")}`)
32
+ }
33
+ if (r.music) {
34
+ console.log(`Music:`)
35
+ console.log(`- Title: ${r.music.title}`)
36
+ if (r.music.playUrl?.length) {
37
+ console.log(`- Music URL: ${r.music.playUrl[0]}`)
38
+ }
39
+ }
40
+ console.log("========================")
41
+ } else {
42
+ console.error("Error:", result.message)
43
+ }
44
+ } catch (error) {
45
+ console.error("Test failed:", error)
46
+ }
47
+ }
48
+
49
+ testDownloaderV1()
@@ -0,0 +1,47 @@
1
+ // Test for Tiktok Downloader v2
2
+ import Tiktok from "../src/index"
3
+
4
+ async function testDownloaderV2() {
5
+ try {
6
+ const url = "https://www.tiktok.com/@tobz2k19/video/7451777267107187986" // Change to a valid TikTok video URL
7
+ console.log(`\nTesting Downloader version: v2`)
8
+ const result = await Tiktok.Downloader(url, {
9
+ version: "v2",
10
+ proxy: undefined
11
+ })
12
+ if (result.status === "success" && result.result) {
13
+ const r = result.result
14
+ console.log(`Type: ${r.type}`)
15
+ if (r.desc) console.log(`Description: ${r.desc}`)
16
+ if (r.author && r.author.nickname) {
17
+ console.log(`Author: ${r.author.nickname}`)
18
+ } else if (r.author && r.author.avatar) {
19
+ // fallback for v2 author structure
20
+ console.log(`Author Avatar: ${r.author.avatar}`)
21
+ }
22
+ if (r.statistics) {
23
+ console.log("Statistics:")
24
+ if (r.statistics.likeCount !== undefined)
25
+ console.log(`- Likes: ${r.statistics.likeCount}`)
26
+ if (r.statistics.commentCount !== undefined)
27
+ console.log(`- Comments: ${r.statistics.commentCount}`)
28
+ if (r.statistics.shareCount !== undefined)
29
+ console.log(`- Shares: ${r.statistics.shareCount}`)
30
+ }
31
+ if (r.video?.playAddr?.length) {
32
+ console.log(`Video URL: ${r.video.playAddr[0]}`)
33
+ }
34
+ if (r.music?.playUrl?.length) {
35
+ console.log(`Music URL: ${r.music.playUrl[0]}`)
36
+ }
37
+ if (r.images?.length) console.log(`Images: ${r.images.join(", ")}`)
38
+ console.log("========================")
39
+ } else {
40
+ console.error("Error:", result.message)
41
+ }
42
+ } catch (error) {
43
+ console.error("Test failed:", error)
44
+ }
45
+ }
46
+
47
+ testDownloaderV2()