@mathrunet/masamune_workflow_sales 3.8.0

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 (31) hide show
  1. package/CHANGELOG.md +361 -0
  2. package/LICENSE +21 -0
  3. package/README.md +70 -0
  4. package/dist/clients/app_store_scraper_client.d.ts +93 -0
  5. package/dist/clients/app_store_scraper_client.js +252 -0
  6. package/dist/clients/app_store_scraper_client.js.map +1 -0
  7. package/dist/clients/google_play_scraper_client.d.ts +92 -0
  8. package/dist/clients/google_play_scraper_client.js +240 -0
  9. package/dist/clients/google_play_scraper_client.js.map +1 -0
  10. package/dist/clients/website_contact_client.d.ts +77 -0
  11. package/dist/clients/website_contact_client.js +262 -0
  12. package/dist/clients/website_contact_client.js.map +1 -0
  13. package/dist/functions/collect_app_store_developers.d.ts +29 -0
  14. package/dist/functions/collect_app_store_developers.js +231 -0
  15. package/dist/functions/collect_app_store_developers.js.map +1 -0
  16. package/dist/functions/collect_google_play_developers.d.ts +38 -0
  17. package/dist/functions/collect_google_play_developers.js +239 -0
  18. package/dist/functions/collect_google_play_developers.js.map +1 -0
  19. package/dist/functions.d.ts +20 -0
  20. package/dist/functions.js +65 -0
  21. package/dist/functions.js.map +1 -0
  22. package/dist/index.d.ts +18 -0
  23. package/dist/index.js +35 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/models/app_store_developer_data.d.ts +176 -0
  26. package/dist/models/app_store_developer_data.js +3 -0
  27. package/dist/models/app_store_developer_data.js.map +1 -0
  28. package/dist/models/google_play_developer_data.d.ts +165 -0
  29. package/dist/models/google_play_developer_data.js +3 -0
  30. package/dist/models/google_play_developer_data.js.map +1 -0
  31. package/package.json +61 -0
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.AppStoreScraperClient = void 0;
37
+ const appStore = __importStar(require("app-store-scraper"));
38
+ const masamune_1 = require("@mathrunet/masamune");
39
+ const website_contact_client_1 = require("./website_contact_client");
40
+ /**
41
+ * Client for scraping App Store developer information.
42
+ *
43
+ * App Storeデベロッパー情報をスクレイピングするクライアント。
44
+ */
45
+ class AppStoreScraperClient {
46
+ config;
47
+ websiteContactClient = null;
48
+ constructor(config = {}) {
49
+ this.config = {
50
+ lang: config.lang ?? "ja",
51
+ country: config.country ?? "jp",
52
+ throttle: config.throttle ?? 1000,
53
+ enableWebsiteScraping: config.enableWebsiteScraping ?? true
54
+ };
55
+ if (this.config.enableWebsiteScraping) {
56
+ this.websiteContactClient = new website_contact_client_1.WebsiteContactClient();
57
+ }
58
+ }
59
+ /**
60
+ * Get developer information by developer ID.
61
+ *
62
+ * デベロッパーIDからデベロッパー情報を取得。
63
+ *
64
+ * @param devId Developer ID (artist ID - numeric) / デベロッパーID(artistID - 数値)
65
+ * @returns Developer information or null / デベロッパー情報またはnull
66
+ */
67
+ async getDeveloperInfo(devId) {
68
+ try {
69
+ // Get developer's apps
70
+ const apps = await appStore.developer({
71
+ devId: devId,
72
+ country: this.config.country
73
+ });
74
+ if (!apps || apps.length === 0) {
75
+ return null;
76
+ }
77
+ // Convert to our app format
78
+ const developerApps = apps.map(app => ({
79
+ id: app.id,
80
+ appId: app.appId,
81
+ title: app.title,
82
+ description: app.description,
83
+ score: app.score,
84
+ icon: app.icon,
85
+ primaryGenre: app.primaryGenre,
86
+ price: app.price,
87
+ free: app.free
88
+ }));
89
+ // Create basic developer info
90
+ const developerInfo = {
91
+ developerId: devId,
92
+ developerName: apps[0].developer,
93
+ developerUrl: apps[0].developerUrl,
94
+ apps: developerApps,
95
+ collectedTime: new masamune_1.ModelTimestamp(new Date())
96
+ };
97
+ // Enrich with website and email details
98
+ return await this.enrichDeveloperInfo(developerInfo);
99
+ }
100
+ catch (error) {
101
+ console.warn(`Failed to get developer info for: ${devId}`, error);
102
+ return null;
103
+ }
104
+ }
105
+ /**
106
+ * Get app details including developer website.
107
+ *
108
+ * デベロッパーのWebサイトを含むアプリ詳細を取得。
109
+ *
110
+ * @param appId App ID (track ID - numeric) / アプリID(トラックID - 数値)
111
+ * @returns App details or null / アプリ詳細またはnull
112
+ */
113
+ async getAppDetails(appId) {
114
+ try {
115
+ await this.throttle();
116
+ return await appStore.app({
117
+ id: appId,
118
+ country: this.config.country,
119
+ lang: this.config.lang
120
+ });
121
+ }
122
+ catch (error) {
123
+ console.warn(`Failed to get app details for: ${appId}`, error);
124
+ return null;
125
+ }
126
+ }
127
+ /**
128
+ * Get apps from category ranking.
129
+ *
130
+ * カテゴリランキングからアプリ一覧を取得。
131
+ *
132
+ * @param options Category ranking options / カテゴリランキングオプション
133
+ * @returns List of apps / アプリ一覧
134
+ */
135
+ async getListApps(options) {
136
+ try {
137
+ await this.throttle();
138
+ return await appStore.list({
139
+ collection: options.collection,
140
+ category: options.category,
141
+ num: options.num ?? 50,
142
+ country: this.config.country,
143
+ lang: this.config.lang
144
+ });
145
+ }
146
+ catch (error) {
147
+ console.warn(`Failed to get list apps for category: ${options.category}`, error);
148
+ return [];
149
+ }
150
+ }
151
+ /**
152
+ * Search for apps by keyword.
153
+ *
154
+ * キーワードでアプリを検索。
155
+ *
156
+ * @param options Search options / 検索オプション
157
+ * @returns List of apps / アプリ一覧
158
+ */
159
+ async searchApps(options) {
160
+ try {
161
+ await this.throttle();
162
+ return await appStore.search({
163
+ term: options.term,
164
+ num: options.num ?? 50,
165
+ country: this.config.country,
166
+ lang: this.config.lang
167
+ });
168
+ }
169
+ catch (error) {
170
+ console.warn(`Failed to search apps for term: ${options.term}`, error);
171
+ return [];
172
+ }
173
+ }
174
+ /**
175
+ * Extract unique developer IDs from app list.
176
+ *
177
+ * アプリ一覧から重複のないデベロッパーIDを抽出。
178
+ *
179
+ * @param apps List of apps / アプリ一覧
180
+ * @returns Unique developer IDs / 重複のないデベロッパーID一覧
181
+ */
182
+ extractDeveloperIds(apps) {
183
+ const devIds = new Set();
184
+ for (const app of apps) {
185
+ if (app.developerId) {
186
+ devIds.add(app.developerId);
187
+ }
188
+ }
189
+ return Array.from(devIds);
190
+ }
191
+ /**
192
+ * Enrich developer info with website and email from website scraping.
193
+ *
194
+ * Webサイトからメールアドレス等の詳細情報を補完。
195
+ *
196
+ * @param devInfo Basic developer info / 基本デベロッパー情報
197
+ * @returns Enriched developer info / 補完されたデベロッパー情報
198
+ */
199
+ async enrichDeveloperInfo(devInfo) {
200
+ if (devInfo.apps.length === 0) {
201
+ return devInfo;
202
+ }
203
+ // Try to get website from first few apps
204
+ const appsToTry = devInfo.apps.slice(0, 3);
205
+ let websiteUrl;
206
+ for (const app of appsToTry) {
207
+ const appDetails = await this.getAppDetails(app.id);
208
+ if (appDetails && appDetails.developerWebsite) {
209
+ websiteUrl = appDetails.developerWebsite;
210
+ devInfo.website = websiteUrl;
211
+ break;
212
+ }
213
+ }
214
+ // Extract email from website using Puppeteer
215
+ if (websiteUrl && this.websiteContactClient) {
216
+ try {
217
+ console.log(`Extracting contact info from: ${websiteUrl}`);
218
+ const contactInfo = await this.websiteContactClient.extractContactInfo(websiteUrl);
219
+ if (contactInfo.emails.length > 0) {
220
+ devInfo.email = contactInfo.emails[0];
221
+ }
222
+ if (contactInfo.contactPageUrls.length > 0) {
223
+ devInfo.contactPageUrls = contactInfo.contactPageUrls;
224
+ }
225
+ }
226
+ catch (error) {
227
+ console.warn(`Failed to extract contact info from website: ${websiteUrl}`, error);
228
+ }
229
+ }
230
+ return devInfo;
231
+ }
232
+ /**
233
+ * Close the website contact client.
234
+ *
235
+ * Webサイトコンタクトクライアントを閉じる。
236
+ */
237
+ async close() {
238
+ if (this.websiteContactClient) {
239
+ await this.websiteContactClient.close();
240
+ }
241
+ }
242
+ /**
243
+ * Sleep for throttle interval.
244
+ *
245
+ * スロットル間隔だけスリープ。
246
+ */
247
+ async throttle() {
248
+ return new Promise(resolve => setTimeout(resolve, this.config.throttle));
249
+ }
250
+ }
251
+ exports.AppStoreScraperClient = AppStoreScraperClient;
252
+ //# sourceMappingURL=app_store_scraper_client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app_store_scraper_client.js","sourceRoot":"","sources":["../../src/clients/app_store_scraper_client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import * as gplay from "google-play-scraper";
2
+ import { GooglePlayDeveloperInfo, CategoryRankingConfig, SearchConfig } from "../models/google_play_developer_data";
3
+ /**
4
+ * Configuration for GooglePlayScraperClient.
5
+ *
6
+ * GooglePlayScraperClientの設定。
7
+ */
8
+ export interface GooglePlayScraperClientConfig {
9
+ /** Language code (default: "ja") / 言語コード */
10
+ lang?: string;
11
+ /** Country code (default: "jp") / 国コード */
12
+ country?: string;
13
+ /** Throttle interval in ms (default: 1000) / リクエスト間隔(ミリ秒) */
14
+ throttle?: number;
15
+ }
16
+ /**
17
+ * Client for scraping Google Play developer information.
18
+ *
19
+ * Google Playデベロッパー情報をスクレイピングするクライアント。
20
+ */
21
+ export declare class GooglePlayScraperClient {
22
+ private config;
23
+ constructor(config?: GooglePlayScraperClientConfig);
24
+ /**
25
+ * Get developer information by developer ID.
26
+ *
27
+ * デベロッパーIDからデベロッパー情報を取得。
28
+ *
29
+ * @param devId Developer ID / デベロッパーID
30
+ * @returns Developer information or null / デベロッパー情報またはnull
31
+ */
32
+ getDeveloperInfo(devId: string): Promise<GooglePlayDeveloperInfo | null>;
33
+ /**
34
+ * Get app details including developer email.
35
+ *
36
+ * デベロッパーのメールアドレスを含むアプリ詳細を取得。
37
+ *
38
+ * @param appId App ID (package name) / アプリID
39
+ * @returns App details or null / アプリ詳細またはnull
40
+ */
41
+ getAppDetails(appId: string): Promise<gplay.AppDetailResult | null>;
42
+ /**
43
+ * Get apps from category ranking.
44
+ *
45
+ * カテゴリランキングからアプリ一覧を取得。
46
+ *
47
+ * @param options Category ranking options / カテゴリランキングオプション
48
+ * @returns List of apps / アプリ一覧
49
+ */
50
+ getListApps(options: CategoryRankingConfig): Promise<gplay.AppResult[]>;
51
+ /**
52
+ * Search for apps by keyword.
53
+ *
54
+ * キーワードでアプリを検索。
55
+ *
56
+ * @param options Search options / 検索オプション
57
+ * @returns List of apps / アプリ一覧
58
+ */
59
+ searchApps(options: SearchConfig): Promise<gplay.AppResult[]>;
60
+ /**
61
+ * Get list of available categories.
62
+ *
63
+ * 利用可能なカテゴリ一覧を取得。
64
+ *
65
+ * @returns List of category IDs / カテゴリID一覧
66
+ */
67
+ getCategories(): Promise<string[]>;
68
+ /**
69
+ * Extract unique developer IDs from app list.
70
+ *
71
+ * アプリ一覧から重複のないデベロッパーIDを抽出。
72
+ *
73
+ * @param apps List of apps / アプリ一覧
74
+ * @returns Unique developer IDs / 重複のないデベロッパーID一覧
75
+ */
76
+ extractDeveloperIds(apps: gplay.AppResult[]): string[];
77
+ /**
78
+ * Enrich developer info with email and other details from first app.
79
+ *
80
+ * 最初のアプリからメールアドレス等の詳細情報を補完。
81
+ *
82
+ * @param devInfo Basic developer info / 基本デベロッパー情報
83
+ * @returns Enriched developer info / 補完されたデベロッパー情報
84
+ */
85
+ private enrichDeveloperInfo;
86
+ /**
87
+ * Sleep for throttle interval.
88
+ *
89
+ * スロットル間隔だけスリープ。
90
+ */
91
+ private throttle;
92
+ }
@@ -0,0 +1,240 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.GooglePlayScraperClient = void 0;
37
+ const gplay = __importStar(require("google-play-scraper"));
38
+ const masamune_1 = require("@mathrunet/masamune");
39
+ /**
40
+ * Client for scraping Google Play developer information.
41
+ *
42
+ * Google Playデベロッパー情報をスクレイピングするクライアント。
43
+ */
44
+ class GooglePlayScraperClient {
45
+ config;
46
+ constructor(config = {}) {
47
+ this.config = {
48
+ lang: config.lang ?? "ja",
49
+ country: config.country ?? "jp",
50
+ throttle: config.throttle ?? 1000
51
+ };
52
+ }
53
+ /**
54
+ * Get developer information by developer ID.
55
+ *
56
+ * デベロッパーIDからデベロッパー情報を取得。
57
+ *
58
+ * @param devId Developer ID / デベロッパーID
59
+ * @returns Developer information or null / デベロッパー情報またはnull
60
+ */
61
+ async getDeveloperInfo(devId) {
62
+ try {
63
+ // Get developer's apps
64
+ const apps = await gplay.developer({
65
+ devId: devId,
66
+ lang: this.config.lang,
67
+ country: this.config.country,
68
+ num: 50
69
+ });
70
+ if (!apps || apps.length === 0) {
71
+ return null;
72
+ }
73
+ // Convert to our app format
74
+ const developerApps = apps.map(app => ({
75
+ appId: app.appId,
76
+ title: app.title,
77
+ summary: app.summary,
78
+ score: app.score,
79
+ icon: app.icon,
80
+ genre: app.genre,
81
+ price: app.price,
82
+ free: app.free
83
+ }));
84
+ // Create basic developer info
85
+ const developerInfo = {
86
+ developerId: devId,
87
+ developerName: apps[0].developer,
88
+ apps: developerApps,
89
+ collectedTime: new masamune_1.ModelTimestamp(new Date())
90
+ };
91
+ // Enrich with email and other details from first app
92
+ return await this.enrichDeveloperInfo(developerInfo);
93
+ }
94
+ catch (error) {
95
+ console.warn(`Failed to get developer info for: ${devId}`, error);
96
+ return null;
97
+ }
98
+ }
99
+ /**
100
+ * Get app details including developer email.
101
+ *
102
+ * デベロッパーのメールアドレスを含むアプリ詳細を取得。
103
+ *
104
+ * @param appId App ID (package name) / アプリID
105
+ * @returns App details or null / アプリ詳細またはnull
106
+ */
107
+ async getAppDetails(appId) {
108
+ try {
109
+ await this.throttle();
110
+ return await gplay.app({
111
+ appId: appId,
112
+ lang: this.config.lang,
113
+ country: this.config.country
114
+ });
115
+ }
116
+ catch (error) {
117
+ console.warn(`Failed to get app details for: ${appId}`, error);
118
+ return null;
119
+ }
120
+ }
121
+ /**
122
+ * Get apps from category ranking.
123
+ *
124
+ * カテゴリランキングからアプリ一覧を取得。
125
+ *
126
+ * @param options Category ranking options / カテゴリランキングオプション
127
+ * @returns List of apps / アプリ一覧
128
+ */
129
+ async getListApps(options) {
130
+ try {
131
+ await this.throttle();
132
+ return await gplay.list({
133
+ category: options.category,
134
+ collection: options.collection,
135
+ num: options.num ?? 50,
136
+ lang: this.config.lang,
137
+ country: this.config.country
138
+ });
139
+ }
140
+ catch (error) {
141
+ console.warn(`Failed to get list apps for category: ${options.category}`, error);
142
+ return [];
143
+ }
144
+ }
145
+ /**
146
+ * Search for apps by keyword.
147
+ *
148
+ * キーワードでアプリを検索。
149
+ *
150
+ * @param options Search options / 検索オプション
151
+ * @returns List of apps / アプリ一覧
152
+ */
153
+ async searchApps(options) {
154
+ try {
155
+ await this.throttle();
156
+ return await gplay.search({
157
+ term: options.term,
158
+ num: options.num ?? 50,
159
+ lang: this.config.lang,
160
+ country: this.config.country,
161
+ price: options.price ?? "all"
162
+ });
163
+ }
164
+ catch (error) {
165
+ console.warn(`Failed to search apps for term: ${options.term}`, error);
166
+ return [];
167
+ }
168
+ }
169
+ /**
170
+ * Get list of available categories.
171
+ *
172
+ * 利用可能なカテゴリ一覧を取得。
173
+ *
174
+ * @returns List of category IDs / カテゴリID一覧
175
+ */
176
+ async getCategories() {
177
+ try {
178
+ return await gplay.categories();
179
+ }
180
+ catch (error) {
181
+ console.warn("Failed to get categories", error);
182
+ return [];
183
+ }
184
+ }
185
+ /**
186
+ * Extract unique developer IDs from app list.
187
+ *
188
+ * アプリ一覧から重複のないデベロッパーIDを抽出。
189
+ *
190
+ * @param apps List of apps / アプリ一覧
191
+ * @returns Unique developer IDs / 重複のないデベロッパーID一覧
192
+ */
193
+ extractDeveloperIds(apps) {
194
+ const devIds = new Set();
195
+ for (const app of apps) {
196
+ if (app.developerId) {
197
+ devIds.add(app.developerId);
198
+ }
199
+ }
200
+ return Array.from(devIds);
201
+ }
202
+ /**
203
+ * Enrich developer info with email and other details from first app.
204
+ *
205
+ * 最初のアプリからメールアドレス等の詳細情報を補完。
206
+ *
207
+ * @param devInfo Basic developer info / 基本デベロッパー情報
208
+ * @returns Enriched developer info / 補完されたデベロッパー情報
209
+ */
210
+ async enrichDeveloperInfo(devInfo) {
211
+ if (devInfo.apps.length === 0) {
212
+ return devInfo;
213
+ }
214
+ // Try to get details from first few apps until we find email
215
+ const appsToTry = devInfo.apps.slice(0, 3);
216
+ for (const app of appsToTry) {
217
+ const appDetails = await this.getAppDetails(app.appId);
218
+ if (appDetails) {
219
+ if (appDetails.developerEmail) {
220
+ devInfo.email = appDetails.developerEmail;
221
+ devInfo.website = appDetails.developerWebsite;
222
+ devInfo.address = appDetails.developerAddress;
223
+ devInfo.privacyPolicyUrl = appDetails.privacyPolicy;
224
+ break;
225
+ }
226
+ }
227
+ }
228
+ return devInfo;
229
+ }
230
+ /**
231
+ * Sleep for throttle interval.
232
+ *
233
+ * スロットル間隔だけスリープ。
234
+ */
235
+ async throttle() {
236
+ return new Promise(resolve => setTimeout(resolve, this.config.throttle));
237
+ }
238
+ }
239
+ exports.GooglePlayScraperClient = GooglePlayScraperClient;
240
+ //# sourceMappingURL=google_play_scraper_client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google_play_scraper_client.js","sourceRoot":"","sources":["../../src/clients/google_play_scraper_client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import { WebsiteContactInfo } from "../models/app_store_developer_data";
2
+ /**
3
+ * Configuration for WebsiteContactClient.
4
+ *
5
+ * WebsiteContactClientの設定。
6
+ */
7
+ export interface WebsiteContactClientConfig {
8
+ /** Page load timeout in ms (default: 10000) / ページ読み込みタイムアウト(ミリ秒) */
9
+ pageTimeout?: number;
10
+ /** Maximum contact pages to visit (default: 2) / 最大訪問コンタクトページ数 */
11
+ maxContactPages?: number;
12
+ }
13
+ /**
14
+ * Client for extracting contact information from websites using Puppeteer.
15
+ *
16
+ * Puppeteerを使用してWebサイトからコンタクト情報を抽出するクライアント。
17
+ */
18
+ export declare class WebsiteContactClient {
19
+ private config;
20
+ private browser;
21
+ /** Email regex pattern / メールアドレスの正規表現パターン */
22
+ private readonly emailRegex;
23
+ /** Contact page URL patterns / コンタクトページのURLパターン */
24
+ private readonly contactPatterns;
25
+ /** Email addresses to exclude (common false positives) / 除外するメールアドレス */
26
+ private readonly excludeEmails;
27
+ constructor(config?: WebsiteContactClientConfig);
28
+ /**
29
+ * Get or create browser instance.
30
+ *
31
+ * ブラウザインスタンスを取得または作成。
32
+ */
33
+ private getBrowser;
34
+ /**
35
+ * Extract contact information from a website.
36
+ *
37
+ * Webサイトからコンタクト情報を抽出。
38
+ *
39
+ * @param websiteUrl Website URL / WebサイトURL
40
+ * @returns Contact information / コンタクト情報
41
+ */
42
+ extractContactInfo(websiteUrl: string): Promise<WebsiteContactInfo>;
43
+ /**
44
+ * Extract email addresses from a page (after JS rendering).
45
+ *
46
+ * ページからメールアドレスを抽出(JSレンダリング後)。
47
+ *
48
+ * @param page Puppeteer page / Puppeteerページ
49
+ * @returns List of email addresses / メールアドレス一覧
50
+ */
51
+ private extractEmailsFromPage;
52
+ /**
53
+ * Find contact page URLs on the current page.
54
+ *
55
+ * 現在のページからコンタクトページのURLを探索。
56
+ *
57
+ * @param page Puppeteer page / Puppeteerページ
58
+ * @param baseUrl Base URL for resolving relative URLs / 相対URLを解決するためのベースURL
59
+ * @returns List of contact page URLs / コンタクトページURL一覧
60
+ */
61
+ private findContactPageUrls;
62
+ /**
63
+ * Filter out invalid or unwanted email addresses.
64
+ *
65
+ * 無効または不要なメールアドレスを除外。
66
+ *
67
+ * @param emails List of emails / メールアドレス一覧
68
+ * @returns Filtered emails / フィルタリングされたメールアドレス一覧
69
+ */
70
+ private filterEmails;
71
+ /**
72
+ * Close the browser instance.
73
+ *
74
+ * ブラウザインスタンスを閉じる。
75
+ */
76
+ close(): Promise<void>;
77
+ }