@xuda.io/ai_module 1.1.4767 → 1.1.4768

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 (3) hide show
  1. package/index.mjs +0 -2684
  2. package/old.mjs +2688 -0
  3. package/package.json +1 -1
package/index.mjs CHANGED
@@ -7207,144 +7207,6 @@ const get_image_blob_from_downloaded_image = async function (url) {
7207
7207
  return images[0];
7208
7208
  };
7209
7209
 
7210
- // export const get_business_info = async function (uid, name, email, account_profile_info) {
7211
- // // Extract lists from your JSON categories array
7212
- // const categories = [
7213
- // {
7214
- // id: 'ind_technology',
7215
- // name: 'Technology',
7216
- // sub: ['Software Development', 'AI & Machine Learning', 'Cybersecurity', 'Cloud Computing', 'IT Services', 'SaaS & Platforms', 'Hardware & Electronics'],
7217
- // },
7218
- // {
7219
- // id: 'ind_marketing',
7220
- // name: 'Marketing & Advertising',
7221
- // sub: ['Digital Marketing', 'PPC & SEO', 'Content Creation', 'Branding', 'Social Media Management', 'Email Marketing', 'Market Research'],
7222
- // },
7223
- // {
7224
- // id: 'ind_sales',
7225
- // name: 'Sales',
7226
- // sub: ['B2B Sales', 'B2C Sales', 'Real Estate Sales', 'Account Management', 'Lead Generation', 'Inside Sales', 'Field Sales'],
7227
- // },
7228
- // {
7229
- // id: 'ind_finance',
7230
- // name: 'Finance & Accounting',
7231
- // sub: ['Banking', 'Investment', 'Financial Planning', 'Accounting', 'Bookkeeping', 'Insurance', 'FinTech'],
7232
- // },
7233
- // {
7234
- // id: 'ind_healthcare',
7235
- // name: 'Healthcare',
7236
- // sub: ['Medical Clinics', 'Hospitals', 'Pharma', 'Mental Health', 'Healthcare IT', 'Home Care', 'Medical Research'],
7237
- // },
7238
- // {
7239
- // id: 'ind_realestate',
7240
- // name: 'Real Estate',
7241
- // sub: ['Residential Real Estate', 'Commercial Real Estate', 'Property Management', 'Investment & BRRRR', 'Construction', 'Architecture', 'Interior Design'],
7242
- // },
7243
- // {
7244
- // id: 'ind_ecommerce',
7245
- // name: 'E-commerce',
7246
- // sub: ['Online Store', 'Dropshipping', 'Amazon FBA', 'Marketplace Selling', 'Retail', 'Inventory Management', 'Fulfillment & Logistics'],
7247
- // },
7248
- // {
7249
- // id: 'ind_education',
7250
- // name: 'Education',
7251
- // sub: ['Schools', 'Universities', 'Private Tutoring', 'Online Courses', 'EdTech', 'Training & Development'],
7252
- // },
7253
- // {
7254
- // id: 'ind_hospitality',
7255
- // name: 'Hospitality & Travel',
7256
- // sub: ['Hotels', 'Restaurants', 'Cafes & Bars', 'Travel Agencies', 'Tourism', 'Events & Catering', 'Transportation'],
7257
- // },
7258
- // {
7259
- // id: 'ind_professional',
7260
- // name: 'Professional Services',
7261
- // sub: ['Legal', 'Consulting', 'HR & Recruiting', 'Accounting Firms', 'Business Services', 'Management Consulting'],
7262
- // },
7263
- // {
7264
- // id: 'ind_manufacturing',
7265
- // name: 'Manufacturing',
7266
- // sub: ['Automotive', 'Industrial', 'Textile', 'Electronics', 'Food Production', 'Machinery', 'Chemicals'],
7267
- // },
7268
- // {
7269
- // id: 'ind_nonprofit',
7270
- // name: 'Nonprofit & Government',
7271
- // sub: ['NGOs', 'Municipality', 'Government Services', 'Public Health', 'Community Organizations', 'Education Programs'],
7272
- // },
7273
- // {
7274
- // id: 'ind_media',
7275
- // name: 'Media & Entertainment',
7276
- // sub: ['Film & Video', 'Music', 'Publishing', 'Gaming', 'News & Journalism', 'Influencers', 'Production Studios'],
7277
- // },
7278
- // {
7279
- // id: 'ind_logistics',
7280
- // name: 'Logistics & Transportation',
7281
- // sub: ['Shipping', 'Trucking', 'Last-Mile Delivery', 'Warehousing', 'Freight Forwarding', 'Route Optimization'],
7282
- // },
7283
- // {
7284
- // id: 'ind_energy',
7285
- // name: 'Energy & Utilities',
7286
- // sub: ['Solar', 'Oil & Gas', 'Electricity Providers', 'Water Utilities', 'Environmental Services', 'Renewable Energy'],
7287
- // },
7288
- // {
7289
- // id: 'ind_construction',
7290
- // name: 'Construction & Trades',
7291
- // sub: ['General Contracting', 'Roofing', 'Plumbing', 'HVAC', 'Electrical', 'Renovation', 'Engineering'],
7292
- // },
7293
- // {
7294
- // id: 'ind_food',
7295
- // name: 'Food & Beverage',
7296
- // sub: ['Restaurants', 'Catering', 'Food Manufacturing', 'Bakeries', 'Bars & Nightlife', 'Food Delivery'],
7297
- // },
7298
- // {
7299
- // id: 'ind_retail',
7300
- // name: 'Retail',
7301
- // sub: ['Physical Stores', 'Boutiques', 'Supermarkets', 'Consumer Goods', 'Fashion Retail', 'Home Goods'],
7302
- // },
7303
- // ];
7304
- // const categoryNames = categories.map((c) => c.name);
7305
- // const allSubCategories = categories.flatMap((c) => c.sub);
7306
-
7307
- // const business_info_ret = await submit_chat_gpt_prompt({
7308
- // uid,
7309
- // prompt: `Research the company: "${name}" (${email}).
7310
- // 1. get the company name.
7311
- // 2. get the domain name from the email.
7312
- // 2. Provide a professional one-sentence biography of the company.
7313
- // 3. Categorize them using the provided industry lists.
7314
- // 4. Identify their primary country as a 2-letter ISO code (e.g., 'US').`,
7315
- // model: 'gpt-5-nano',
7316
- // response_format: z.object({
7317
- // business_name: z.string().describe('the company name'),
7318
- // business_domain: z.string().describe('the email domain name'),
7319
- // business_bio: z.string().describe('A concise, professional one-sentence summary of what the business does'),
7320
- // business_size: z.enum(['unknown', 'small', 'medium', 'large', 'enterprise']),
7321
- // business_category: z.enum(categoryNames),
7322
- // business_sub_category: z.enum(allSubCategories),
7323
- // business_country: z.string().length(2).describe("2-letter ISO country code (e.g., 'US')"),
7324
- // }),
7325
- // metadata: { func: 'get_business_info' },
7326
- // account_profile_info,
7327
- // tools: [{ type: 'web_search_preview' }],
7328
- // });
7329
-
7330
- // try {
7331
- // if (business_info_ret.code > -1) {
7332
- // const data = typeof business_info_ret.data === 'string' ? JSON.parse(business_info_ret.data) : business_info_ret.data;
7333
-
7334
- // // Standardize country to uppercase
7335
- // if (data.business_country) data.business_country = data.business_country.toUpperCase();
7336
-
7337
- // // Logic to attach the ID for your database
7338
- // const matched = categories.find((c) => c.name === data.business_category);
7339
- // data.business_category_id = matched ? matched.id : null;
7340
-
7341
- // return data;
7342
- // }
7343
- // } catch (error) {
7344
- // console.error('Error in get_business_info:', error);
7345
- // }
7346
- // };
7347
-
7348
7210
  const get_chat_picture_cache = async function (uid, docType, key) {
7349
7211
  if (!key || typeof key !== 'string') return null;
7350
7212
 
@@ -8747,2552 +8609,6 @@ Category:`;
8747
8609
  }
8748
8610
  };
8749
8611
 
8750
- // export const get_business_info = async function (uid, name, email, account_profile_info) {
8751
- // // ========== HELPER FUNCTIONS ==========
8752
-
8753
- // function validatePhoneNumber(phone) {
8754
- // if (!phone || phone.toLowerCase() === 'not available' || phone.trim() === '') {
8755
- // return 'Not available';
8756
- // }
8757
-
8758
- // const cleaned = phone.replace(/[^\d\+\(\)\-\s]/g, '');
8759
- // const digitCount = (cleaned.match(/\d/g) || []).length;
8760
-
8761
- // // Require at least 7 digits for a valid phone number
8762
- // if (digitCount < 7) {
8763
- // return 'Not available';
8764
- // }
8765
-
8766
- // return cleaned.trim();
8767
- // }
8768
-
8769
- // function validateWebsite(website) {
8770
- // if (!website || website.toLowerCase() === 'not available' || website.trim() === '') {
8771
- // return 'Not available';
8772
- // }
8773
-
8774
- // const trimmed = website.trim();
8775
-
8776
- // // Ensure URL has proper protocol
8777
- // if (!trimmed.startsWith('http://') && !trimmed.startsWith('https://')) {
8778
- // // Check if it looks like a domain
8779
- // if (trimmed.includes('.') && !trimmed.includes(' ')) {
8780
- // return `https://${trimmed.replace(/^www\./, '')}`;
8781
- // }
8782
- // return 'Not available';
8783
- // }
8784
-
8785
- // return trimmed;
8786
- // }
8787
-
8788
- // function cleanStreetAddress(street) {
8789
- // if (!street || street.toLowerCase() === 'not available' || street.trim() === '') {
8790
- // return 'Not available';
8791
- // }
8792
-
8793
- // return street
8794
- // .replace(/\s+/g, ' ')
8795
- // .replace(/,\s*$/g, '') // Remove trailing commas
8796
- // .trim();
8797
- // }
8798
-
8799
- // function cleanText(text) {
8800
- // if (!text || text.toLowerCase() === 'not available' || text.trim() === '') {
8801
- // return 'Not available';
8802
- // }
8803
-
8804
- // return text.replace(/\s+/g, ' ').trim();
8805
- // }
8806
-
8807
- // function cleanZipCode(zip, country) {
8808
- // if (!zip || zip.toLowerCase() === 'not available' || zip.trim() === '') {
8809
- // return 'Not available';
8810
- // }
8811
-
8812
- // const cleaned = zip.trim();
8813
-
8814
- // // Country-specific formatting
8815
- // switch (country) {
8816
- // case 'US':
8817
- // // US ZIP: 5 digits or 5-4 format
8818
- // return cleaned.replace(/\D/g, '').replace(/^(\d{5})(\d{4})$/, '$1-$2');
8819
- // case 'CA':
8820
- // // Canada: A1A 1A1 format
8821
- // return cleaned.toUpperCase().replace(/\s+/g, '');
8822
- // case 'UK':
8823
- // // UK: various formats, preserve as is but uppercase
8824
- // return cleaned.toUpperCase();
8825
- // case 'AU':
8826
- // // Australia: 4 digits
8827
- // return cleaned.replace(/\D/g, '');
8828
- // default:
8829
- // return cleaned;
8830
- // }
8831
- // }
8832
-
8833
- // function cleanStateProvince(state, country) {
8834
- // if (!state || state.toLowerCase() === 'not available' || state.trim() === '') {
8835
- // return 'Not available';
8836
- // }
8837
-
8838
- // const cleaned = state.trim();
8839
-
8840
- // // Standardize US state abbreviations
8841
- // if (country === 'US') {
8842
- // const stateMap = {
8843
- // alabama: 'AL',
8844
- // alaska: 'AK',
8845
- // arizona: 'AZ',
8846
- // arkansas: 'AR',
8847
- // california: 'CA',
8848
- // colorado: 'CO',
8849
- // connecticut: 'CT',
8850
- // delaware: 'DE',
8851
- // florida: 'FL',
8852
- // georgia: 'GA',
8853
- // hawaii: 'HI',
8854
- // idaho: 'ID',
8855
- // illinois: 'IL',
8856
- // indiana: 'IN',
8857
- // iowa: 'IA',
8858
- // kansas: 'KS',
8859
- // kentucky: 'KY',
8860
- // louisiana: 'LA',
8861
- // maine: 'ME',
8862
- // maryland: 'MD',
8863
- // massachusetts: 'MA',
8864
- // michigan: 'MI',
8865
- // minnesota: 'MN',
8866
- // mississippi: 'MS',
8867
- // missouri: 'MO',
8868
- // montana: 'MT',
8869
- // nebraska: 'NE',
8870
- // nevada: 'NV',
8871
- // 'new hampshire': 'NH',
8872
- // 'new jersey': 'NJ',
8873
- // 'new mexico': 'NM',
8874
- // 'new york': 'NY',
8875
- // 'north carolina': 'NC',
8876
- // 'north dakota': 'ND',
8877
- // ohio: 'OH',
8878
- // oklahoma: 'OK',
8879
- // oregon: 'OR',
8880
- // pennsylvania: 'PA',
8881
- // 'rhode island': 'RI',
8882
- // 'south carolina': 'SC',
8883
- // 'south dakota': 'SD',
8884
- // tennessee: 'TN',
8885
- // texas: 'TX',
8886
- // utah: 'UT',
8887
- // vermont: 'VT',
8888
- // virginia: 'VA',
8889
- // washington: 'WA',
8890
- // 'west virginia': 'WV',
8891
- // wisconsin: 'WI',
8892
- // wyoming: 'WY',
8893
- // 'district of columbia': 'DC',
8894
- // };
8895
-
8896
- // const lowerState = cleaned.toLowerCase();
8897
- // if (stateMap[lowerState]) {
8898
- // return stateMap[lowerState];
8899
- // }
8900
-
8901
- // // If already 2-letter code, uppercase it
8902
- // if (/^[A-Z]{2}$/i.test(cleaned)) {
8903
- // return cleaned.toUpperCase();
8904
- // }
8905
- // }
8906
-
8907
- // return cleaned;
8908
- // }
8909
-
8910
- // function cleanCountry(country) {
8911
- // if (!country || country.toLowerCase() === 'not available' || country.trim() === '') {
8912
- // return 'Not available';
8913
- // }
8914
-
8915
- // // Convert 2-letter codes to full country names for display
8916
- // const countryMap = {
8917
- // US: 'United States',
8918
- // CA: 'Canada',
8919
- // UK: 'United Kingdom',
8920
- // GB: 'United Kingdom',
8921
- // AU: 'Australia',
8922
- // DE: 'Germany',
8923
- // FR: 'France',
8924
- // JP: 'Japan',
8925
- // CN: 'China',
8926
- // IN: 'India',
8927
- // BR: 'Brazil',
8928
- // MX: 'Mexico',
8929
- // };
8930
-
8931
- // const upperCountry = country.toUpperCase();
8932
- // return countryMap[upperCountry] || upperCountry;
8933
- // }
8934
-
8935
- // function formatFullAddress(data) {
8936
- // const parts = [];
8937
-
8938
- // if (data.business_address_street && data.business_address_street !== 'Not available') {
8939
- // parts.push(data.business_address_street);
8940
- // }
8941
-
8942
- // const cityStateZip = [];
8943
- // if (data.business_address_city && data.business_address_city !== 'Not available') {
8944
- // cityStateZip.push(data.business_address_city);
8945
- // }
8946
-
8947
- // if (data.business_address_state && data.business_address_state !== 'Not available') {
8948
- // cityStateZip.push(data.business_address_state);
8949
- // }
8950
-
8951
- // if (data.business_address_zip && data.business_address_zip !== 'Not available') {
8952
- // cityStateZip.push(data.business_address_zip);
8953
- // }
8954
-
8955
- // if (cityStateZip.length > 0) {
8956
- // parts.push(cityStateZip.join(', '));
8957
- // }
8958
-
8959
- // if (data.business_address_country && data.business_address_country !== 'Not available') {
8960
- // parts.push(data.business_address_country);
8961
- // }
8962
-
8963
- // return parts.length > 0 ? parts.join(', ') : 'Not available';
8964
- // }
8965
-
8966
- // function getRegionFromState(state, country) {
8967
- // if (country !== 'US' || state === 'Not available') return null;
8968
-
8969
- // const regions = {
8970
- // Northeast: ['CT', 'ME', 'MA', 'NH', 'RI', 'VT', 'NJ', 'NY', 'PA'],
8971
- // Midwest: ['IL', 'IN', 'MI', 'OH', 'WI', 'IA', 'KS', 'MN', 'MO', 'NE', 'ND', 'SD'],
8972
- // South: ['DE', 'FL', 'GA', 'MD', 'NC', 'SC', 'VA', 'DC', 'WV', 'AL', 'KY', 'MS', 'TN', 'AR', 'LA', 'OK', 'TX'],
8973
- // West: ['AZ', 'CO', 'ID', 'MT', 'NV', 'NM', 'UT', 'WY', 'AK', 'CA', 'HI', 'OR', 'WA'],
8974
- // };
8975
-
8976
- // for (const [region, states] of Object.entries(regions)) {
8977
- // if (states.includes(state)) {
8978
- // return region;
8979
- // }
8980
- // }
8981
-
8982
- // return null;
8983
- // }
8984
-
8985
- // function getDefaultBusinessInfo(name, email, error = null) {
8986
- // const domain = email.includes('@') ? email.split('@')[1] : '';
8987
-
8988
- // return {
8989
- // business_name: name,
8990
- // business_domain: domain,
8991
- // business_bio: 'Information not available',
8992
- // business_size: 'unknown',
8993
- // business_category: 'Professional Services',
8994
- // business_sub_category: 'Business Services',
8995
- // business_country: 'US',
8996
- // business_phone: 'Not available',
8997
- // business_website: 'Not available',
8998
-
8999
- // // Address components
9000
- // business_address_street: 'Not available',
9001
- // business_address_city: 'Not available',
9002
- // business_address_state: 'Not available',
9003
- // business_address_zip: 'Not available',
9004
- // business_address_country: 'Not available',
9005
- // business_address_full: 'Not available',
9006
-
9007
- // // Structured objects
9008
- // business_category_id: null,
9009
- // business_address: {
9010
- // street: 'Not available',
9011
- // city: 'Not available',
9012
- // state: 'Not available',
9013
- // zip: 'Not available',
9014
- // country: 'Not available',
9015
- // full: 'Not available',
9016
- // coordinates: null,
9017
- // timezone: null,
9018
- // },
9019
- // business_location: {
9020
- // region: null,
9021
- // metro_area: null,
9022
- // is_headquarters: null,
9023
- // },
9024
- // error: error || 'API call failed',
9025
- // };
9026
- // }
9027
-
9028
- // // Extract lists from your JSON categories array
9029
- // const categories = [
9030
- // {
9031
- // id: 'ind_technology',
9032
- // name: 'Technology',
9033
- // sub: ['Software Development', 'AI & Machine Learning', 'Cybersecurity', 'Cloud Computing', 'IT Services', 'SaaS & Platforms', 'Hardware & Electronics'],
9034
- // },
9035
- // {
9036
- // id: 'ind_marketing',
9037
- // name: 'Marketing & Advertising',
9038
- // sub: ['Digital Marketing', 'PPC & SEO', 'Content Creation', 'Branding', 'Social Media Management', 'Email Marketing', 'Market Research'],
9039
- // },
9040
- // {
9041
- // id: 'ind_sales',
9042
- // name: 'Sales',
9043
- // sub: ['B2B Sales', 'B2C Sales', 'Real Estate Sales', 'Account Management', 'Lead Generation', 'Inside Sales', 'Field Sales'],
9044
- // },
9045
- // {
9046
- // id: 'ind_finance',
9047
- // name: 'Finance & Accounting',
9048
- // sub: ['Banking', 'Investment', 'Financial Planning', 'Accounting', 'Bookkeeping', 'Insurance', 'FinTech'],
9049
- // },
9050
- // {
9051
- // id: 'ind_healthcare',
9052
- // name: 'Healthcare',
9053
- // sub: ['Medical Clinics', 'Hospitals', 'Pharma', 'Mental Health', 'Healthcare IT', 'Home Care', 'Medical Research'],
9054
- // },
9055
- // {
9056
- // id: 'ind_realestate',
9057
- // name: 'Real Estate',
9058
- // sub: ['Residential Real Estate', 'Commercial Real Estate', 'Property Management', 'Investment & BRRRR', 'Construction', 'Architecture', 'Interior Design'],
9059
- // },
9060
- // {
9061
- // id: 'ind_ecommerce',
9062
- // name: 'E-commerce',
9063
- // sub: ['Online Store', 'Dropshipping', 'Amazon FBA', 'Marketplace Selling', 'Retail', 'Inventory Management', 'Fulfillment & Logistics'],
9064
- // },
9065
- // {
9066
- // id: 'ind_education',
9067
- // name: 'Education',
9068
- // sub: ['Schools', 'Universities', 'Private Tutoring', 'Online Courses', 'EdTech', 'Training & Development'],
9069
- // },
9070
- // {
9071
- // id: 'ind_hospitality',
9072
- // name: 'Hospitality & Travel',
9073
- // sub: ['Hotels', 'Restaurants', 'Cafes & Bars', 'Travel Agencies', 'Tourism', 'Events & Catering', 'Transportation'],
9074
- // },
9075
- // {
9076
- // id: 'ind_professional',
9077
- // name: 'Professional Services',
9078
- // sub: ['Legal', 'Consulting', 'HR & Recruiting', 'Accounting Firms', 'Business Services', 'Management Consulting'],
9079
- // },
9080
- // {
9081
- // id: 'ind_manufacturing',
9082
- // name: 'Manufacturing',
9083
- // sub: ['Automotive', 'Industrial', 'Textile', 'Electronics', 'Food Production', 'Machinery', 'Chemicals'],
9084
- // },
9085
- // {
9086
- // id: 'ind_nonprofit',
9087
- // name: 'Nonprofit & Government',
9088
- // sub: ['NGOs', 'Municipality', 'Government Services', 'Public Health', 'Community Organizations', 'Education Programs'],
9089
- // },
9090
- // {
9091
- // id: 'ind_media',
9092
- // name: 'Media & Entertainment',
9093
- // sub: ['Film & Video', 'Music', 'Publishing', 'Gaming', 'News & Journalism', 'Influencers', 'Production Studios'],
9094
- // },
9095
- // {
9096
- // id: 'ind_logistics',
9097
- // name: 'Logistics & Transportation',
9098
- // sub: ['Shipping', 'Trucking', 'Last-Mile Delivery', 'Warehousing', 'Freight Forwarding', 'Route Optimization'],
9099
- // },
9100
- // {
9101
- // id: 'ind_energy',
9102
- // name: 'Energy & Utilities',
9103
- // sub: ['Solar', 'Oil & Gas', 'Electricity Providers', 'Water Utilities', 'Environmental Services', 'Renewable Energy'],
9104
- // },
9105
- // {
9106
- // id: 'ind_construction',
9107
- // name: 'Construction & Trades',
9108
- // sub: ['General Contracting', 'Roofing', 'Plumbing', 'HVAC', 'Electrical', 'Renovation', 'Engineering'],
9109
- // },
9110
- // {
9111
- // id: 'ind_food',
9112
- // name: 'Food & Beverage',
9113
- // sub: ['Restaurants', 'Catering', 'Food Manufacturing', 'Bakeries', 'Bars & Nightlife', 'Food Delivery'],
9114
- // },
9115
- // {
9116
- // id: 'ind_retail',
9117
- // name: 'Retail',
9118
- // sub: ['Physical Stores', 'Boutiques', 'Supermarkets', 'Consumer Goods', 'Fashion Retail', 'Home Goods'],
9119
- // },
9120
- // ];
9121
- // const categoryNames = categories.map((c) => c.name);
9122
- // const allSubCategories = categories.flatMap((c) => c.sub);
9123
-
9124
- // const business_info_ret = await submit_chat_gpt_prompt({
9125
- // uid,
9126
- // prompt: `Research the company: "${name}" (${email}).
9127
-
9128
- // REQUIRED INFORMATION:
9129
- // 1. Company name (official name)
9130
- // 2. Email domain name
9131
- // 3. Professional one-sentence biography
9132
- // 4. Industry category and sub-category
9133
- // 5. Primary country (2-letter ISO code)
9134
- // 6. Telephone number
9135
- // 7. Website URL
9136
- // 8. COMPLETE ADDRESS DETAILS:
9137
- // - Full street address (street number, street name, suite/apt if applicable)
9138
- // - City
9139
- // - State/Province (use abbreviation where standard)
9140
- // - Zip/Postal code
9141
- // - Country
9142
-
9143
- // ADDRESS FORMATTING EXAMPLES:
9144
- // - Full street: "1600 Amphitheatre Parkway"
9145
- // - City: "Mountain View"
9146
- // - State: "CA"
9147
- // - Zip: "94043"
9148
- // - Country: "US"
9149
- // - Full address: "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA"
9150
-
9151
- // INSTRUCTIONS:
9152
- // - Use web search to find accurate information
9153
- // - If not found online, infer from typical patterns
9154
- // - For unknown info, use "Not available"
9155
- // - For US states, use 2-letter abbreviations (CA, NY, TX, etc.)
9156
- // - For other countries, use standard regional names
9157
-
9158
- // Be as precise and accurate as possible.`,
9159
- // model: 'gpt-5-nano',
9160
- // response_format: z.object({
9161
- // business_name: z.string().describe('Official company name'),
9162
- // business_domain: z.string().describe('Domain name from email'),
9163
- // business_bio: z.string().describe('One-sentence professional summary'),
9164
- // business_size: z.enum(['unknown', 'small', 'medium', 'large', 'enterprise']),
9165
- // business_category: z.enum(categoryNames),
9166
- // business_sub_category: z.enum(allSubCategories),
9167
- // business_country: z.string().length(2).describe('2-letter ISO country code'),
9168
- // business_phone: z.string().describe("Telephone number or 'Not available'"),
9169
- // business_website: z.string().describe("Website URL or 'Not available'"),
9170
-
9171
- // // Complete address components
9172
- // business_address_street: z.string().describe('Full street address (number, street, suite)'),
9173
- // business_address_city: z.string().describe('City name'),
9174
- // business_address_state: z.string().describe('State/Province (abbreviation if standard)'),
9175
- // business_address_zip: z.string().describe('Zip/Postal code'),
9176
- // business_address_country: z.string().describe('Country name'),
9177
- // business_address_full: z.string().describe('Complete formatted address'),
9178
- // }),
9179
- // metadata: {
9180
- // func: 'get_business_info',
9181
- // company_name: name,
9182
- // company_email: email,
9183
- // },
9184
- // account_profile_info,
9185
- // tools: [{ type: 'web_search_preview' }],
9186
- // });
9187
-
9188
- // try {
9189
- // if (business_info_ret.code > -1) {
9190
- // const data = typeof business_info_ret.data === 'string' ? JSON.parse(business_info_ret.data) : business_info_ret.data;
9191
-
9192
- // // Standardize country codes to uppercase
9193
- // if (data.business_country) data.business_country = data.business_country.toUpperCase();
9194
- // if (data.business_address_country) {
9195
- // data.business_address_country = data.business_address_country.toUpperCase();
9196
- // }
9197
-
9198
- // // Logic to attach the ID for your database
9199
- // const matched = categories.find((c) => c.name === data.business_category);
9200
- // data.business_category_id = matched ? matched.id : null;
9201
-
9202
- // // Validate and clean all contact information
9203
- // data.business_phone = validatePhoneNumber(data.business_phone);
9204
- // data.business_website = validateWebsite(data.business_website);
9205
-
9206
- // // Clean and standardize all address components
9207
- // data.business_address_street = cleanStreetAddress(data.business_address_street);
9208
- // data.business_address_city = cleanText(data.business_address_city);
9209
- // data.business_address_zip = cleanZipCode(data.business_address_zip, data.business_country);
9210
- // data.business_address_state = cleanStateProvince(data.business_address_state, data.business_country);
9211
- // data.business_address_country = cleanCountry(data.business_address_country || data.business_country);
9212
- // data.business_address_full = formatFullAddress(data);
9213
-
9214
- // // Create a comprehensive structured address object
9215
- // data.business_address = {
9216
- // street: data.business_address_street,
9217
- // city: data.business_address_city,
9218
- // state: data.business_address_state,
9219
- // zip: data.business_address_zip,
9220
- // country: data.business_address_country,
9221
- // full: data.business_address_full,
9222
- // coordinates: null, // Can be populated later with geocoding
9223
- // timezone: null, // Can be populated later
9224
- // };
9225
-
9226
- // // Generate additional useful fields
9227
- // data.business_location = {
9228
- // region: getRegionFromState(data.business_address_state, data.business_country),
9229
- // metro_area: null, // Can be populated later
9230
- // is_headquarters: null, // Can be determined from address pattern
9231
- // };
9232
-
9233
- // return data;
9234
- // } else {
9235
- // console.error('Business info API call failed:', business_info_ret);
9236
- // return getDefaultBusinessInfo(name, email);
9237
- // }
9238
- // } catch (error) {
9239
- // console.error('Error in get_business_info:', error);
9240
- // return getDefaultBusinessInfo(name, email, error.message);
9241
- // }
9242
- // };
9243
-
9244
- // export const get_person_info = async function (uid, name, email, account_profile_info, email_context = '') {
9245
- // // ========== HELPER FUNCTIONS ==========
9246
-
9247
- // async function hashString(str) {
9248
- // // Simple hash for context tracking
9249
- // const encoder = new TextEncoder();
9250
- // const data = encoder.encode(str);
9251
- // const hashBuffer = await crypto.subtle.digest('SHA-256', data);
9252
- // const hashArray = Array.from(new Uint8Array(hashBuffer));
9253
- // return hashArray
9254
- // .map((b) => b.toString(16).padStart(2, '0'))
9255
- // .join('')
9256
- // .substring(0, 16);
9257
- // }
9258
-
9259
- // function processPersonInfo(data, originalName, originalEmail, emailContext) {
9260
- // // Ensure basic fields are populated
9261
- // if (!data.person_first_name || !data.person_last_name) {
9262
- // const nameParts = originalName.trim().split(/\s+/);
9263
- // data.person_first_name = data.person_first_name || nameParts[0] || '';
9264
- // data.person_last_name = data.person_last_name || nameParts.slice(1).join(' ') || '';
9265
- // }
9266
-
9267
- // // Set full name if not provided
9268
- // if (!data.person_full_name) {
9269
- // data.person_full_name = `${data.person_first_name} ${data.person_last_name}`.trim();
9270
- // }
9271
-
9272
- // // Ensure email is set
9273
- // data.person_email = data.person_email || originalEmail;
9274
-
9275
- // // Process demographic information
9276
- // data.person_age = processAge(data.person_age);
9277
- // data.person_gender = data.person_gender || 'unknown';
9278
- // data.person_nationality = processNationality(data.person_nationality);
9279
-
9280
- // // Standardize location fields
9281
- // data.person_location_city = cleanText(data.person_location_city);
9282
- // data.person_location_state = cleanStateProvince(data.person_location_state);
9283
- // data.person_location_country = processCountryCode(data.person_location_country);
9284
-
9285
- // // Format full location
9286
- // if (!data.person_location_full || data.person_location_full === 'Not available') {
9287
- // const locationParts = [];
9288
- // if (data.person_location_city && data.person_location_city !== 'Not available') {
9289
- // locationParts.push(data.person_location_city);
9290
- // }
9291
- // if (data.person_location_state && data.person_location_state !== 'Not available') {
9292
- // locationParts.push(data.person_location_state);
9293
- // }
9294
- // if (data.person_location_country && data.person_location_country !== 'Not available') {
9295
- // locationParts.push(countryCodeToName(data.person_location_country));
9296
- // }
9297
- // data.person_location_full = locationParts.length > 0 ? locationParts.join(', ') : 'Not available';
9298
- // }
9299
-
9300
- // // Clean and validate URLs
9301
- // data.person_linkedin = validateURL(data.person_linkedin);
9302
- // data.person_twitter = validateURL(data.person_twitter);
9303
- // data.person_github = validateURL(data.person_github);
9304
- // data.person_website = validateURL(data.person_website);
9305
-
9306
- // // Clean phone number
9307
- // data.person_phone = validatePhoneNumber(data.person_phone);
9308
-
9309
- // // Ensure arrays are properly formatted
9310
- // data.person_skills = ensureArray(data.person_skills);
9311
- // data.person_expertise = ensureArray(data.person_expertise);
9312
- // data.person_education = ensureArray(data.person_education);
9313
- // data.person_languages = ensureArray(data.person_languages);
9314
- // data.person_interests = ensureArray(data.person_interests);
9315
- // data.person_context_insights = ensureArray(data.person_context_insights);
9316
-
9317
- // // Calculate additional metadata
9318
- // data.person_name_initials = getInitials(data.person_first_name, data.person_last_name);
9319
- // data.person_age_range = calculateAgeRange(data.person_age);
9320
- // data.person_seniority_score = calculateSeniorityScore(data);
9321
- // data.person_pronouns = getPronounsFromGender(data.person_gender);
9322
-
9323
- // // Extract insights from email context
9324
- // if (emailContext && !data.person_context_insights) {
9325
- // data.person_context_insights = extractContextInsights(emailContext);
9326
- // }
9327
-
9328
- // // Create structured objects for easier access
9329
- // data.person_demographics = {
9330
- // age: data.person_age,
9331
- // age_range: data.person_age_range,
9332
- // gender: data.person_gender,
9333
- // pronouns: data.person_pronouns,
9334
- // nationality: data.person_nationality,
9335
- // nationality_name: countryCodeToName(data.person_nationality),
9336
- // };
9337
-
9338
- // data.person_contact = {
9339
- // email: data.person_email,
9340
- // phone: data.person_phone,
9341
- // location: {
9342
- // city: data.person_location_city,
9343
- // state: data.person_location_state,
9344
- // country: data.person_location_country,
9345
- // country_name: countryCodeToName(data.person_location_country),
9346
- // full: data.person_location_full,
9347
- // },
9348
- // };
9349
-
9350
- // data.person_professional = {
9351
- // title: data.person_title,
9352
- // company: data.person_company,
9353
- // industry: data.person_industry,
9354
- // career_level: data.person_career_level,
9355
- // years_experience: data.person_years_experience,
9356
- // skills: data.person_skills,
9357
- // expertise: data.person_expertise,
9358
- // education: data.person_education,
9359
- // };
9360
-
9361
- // data.person_online = {
9362
- // linkedin: data.person_linkedin,
9363
- // twitter: data.person_twitter,
9364
- // github: data.person_github,
9365
- // website: data.person_website,
9366
- // other: data.person_social_other || [],
9367
- // };
9368
-
9369
- // // Add context metadata
9370
- // data.context_analysis = {
9371
- // has_context: !!emailContext,
9372
- // context_length: emailContext?.length || 0,
9373
- // extracted_insights: data.person_context_insights || [],
9374
- // context_useful: data.person_has_context_hints || false,
9375
- // };
9376
-
9377
- // // Add timestamp
9378
- // data.retrieved_at = new Date().toISOString();
9379
-
9380
- // return data;
9381
- // }
9382
-
9383
- // function processAge(ageInput) {
9384
- // if (!ageInput || ageInput === 'unknown' || ageInput === 'Not available') {
9385
- // return 'unknown';
9386
- // }
9387
-
9388
- // if (typeof ageInput === 'number') {
9389
- // return Math.max(18, Math.min(100, ageInput));
9390
- // }
9391
-
9392
- // if (typeof ageInput === 'string') {
9393
- // // Parse age ranges like "30-40", "35+", "mid-30s"
9394
- // const rangeMatch = ageInput.match(/(\d+)-(\d+)/);
9395
- // if (rangeMatch) {
9396
- // const avg = Math.floor((parseInt(rangeMatch[1]) + parseInt(rangeMatch[2])) / 2);
9397
- // return avg;
9398
- // }
9399
-
9400
- // const numberMatch = ageInput.match(/\d+/);
9401
- // if (numberMatch) {
9402
- // const age = parseInt(numberMatch[0]);
9403
- // if (age >= 18 && age <= 100) return age;
9404
- // }
9405
-
9406
- // // Handle textual age descriptions
9407
- // const text = ageInput.toLowerCase();
9408
- // if (text.includes('twent') || text.includes('20')) return 25;
9409
- // if (text.includes('thirt') || text.includes('30')) return 35;
9410
- // if (text.includes('fort') || text.includes('40')) return 45;
9411
- // if (text.includes('fift') || text.includes('50')) return 55;
9412
- // if (text.includes('sixt') || text.includes('60')) return 65;
9413
- // }
9414
-
9415
- // return 'unknown';
9416
- // }
9417
-
9418
- // function calculateAgeRange(age) {
9419
- // if (age === 'unknown' || typeof age !== 'number') return 'Unknown';
9420
-
9421
- // if (age < 25) return '18-24';
9422
- // if (age < 30) return '25-29';
9423
- // if (age < 35) return '30-34';
9424
- // if (age < 40) return '35-39';
9425
- // if (age < 50) return '40-49';
9426
- // if (age < 60) return '50-59';
9427
- // return '60+';
9428
- // }
9429
-
9430
- // function processNationality(nationality) {
9431
- // if (!nationality || nationality.toLowerCase() === 'unknown' || nationality.toLowerCase() === 'not available') {
9432
- // return 'unknown';
9433
- // }
9434
-
9435
- // // Convert to uppercase for country codes
9436
- // const upper = nationality.toUpperCase();
9437
-
9438
- // // Map common variations to ISO codes
9439
- // const countryMap = {
9440
- // USA: 'US',
9441
- // 'UNITED STATES': 'US',
9442
- // AMERICA: 'US',
9443
- // UK: 'GB',
9444
- // 'UNITED KINGDOM': 'GB',
9445
- // ENGLAND: 'GB',
9446
- // SCOTLAND: 'GB',
9447
- // CANADA: 'CA',
9448
- // AUSTRALIA: 'AU',
9449
- // INDIA: 'IN',
9450
- // GERMANY: 'DE',
9451
- // FRANCE: 'FR',
9452
- // CHINA: 'CN',
9453
- // JAPAN: 'JP',
9454
- // BRAZIL: 'BR',
9455
- // MEXICO: 'MX',
9456
- // SPAIN: 'ES',
9457
- // ITALY: 'IT',
9458
- // NETHERLANDS: 'NL',
9459
- // SWEDEN: 'SE',
9460
- // SWITZERLAND: 'CH',
9461
- // 'SOUTH KOREA': 'KR',
9462
- // RUSSIA: 'RU',
9463
- // };
9464
-
9465
- // if (countryMap[upper]) {
9466
- // return countryMap[upper];
9467
- // }
9468
-
9469
- // // If it's already a 2-letter code, return it
9470
- // if (/^[A-Z]{2}$/.test(upper)) {
9471
- // return upper;
9472
- // }
9473
-
9474
- // return 'unknown';
9475
- // }
9476
-
9477
- // function processCountryCode(country) {
9478
- // if (!country || country.toLowerCase() === 'not available') {
9479
- // return 'unknown';
9480
- // }
9481
-
9482
- // return processNationality(country);
9483
- // }
9484
-
9485
- // function countryCodeToName(code) {
9486
- // if (!code || code === 'unknown') return 'Unknown';
9487
-
9488
- // const countryNames = {
9489
- // US: 'United States',
9490
- // GB: 'United Kingdom',
9491
- // CA: 'Canada',
9492
- // AU: 'Australia',
9493
- // DE: 'Germany',
9494
- // FR: 'France',
9495
- // JP: 'Japan',
9496
- // CN: 'China',
9497
- // IN: 'India',
9498
- // BR: 'Brazil',
9499
- // MX: 'Mexico',
9500
- // ES: 'Spain',
9501
- // IT: 'Italy',
9502
- // NL: 'Netherlands',
9503
- // SE: 'Sweden',
9504
- // CH: 'Switzerland',
9505
- // KR: 'South Korea',
9506
- // RU: 'Russia',
9507
- // };
9508
-
9509
- // return countryNames[code] || code;
9510
- // }
9511
-
9512
- // function getPronounsFromGender(gender) {
9513
- // switch (gender) {
9514
- // case 'male':
9515
- // return ['he/him', 'his'];
9516
- // case 'female':
9517
- // return ['she/her', 'hers'];
9518
- // case 'non-binary':
9519
- // return ['they/them', 'theirs'];
9520
- // default:
9521
- // return ['unknown'];
9522
- // }
9523
- // }
9524
-
9525
- // function extractContextInsights(emailContext) {
9526
- // if (!emailContext) return [];
9527
-
9528
- // const insights = [];
9529
- // const context = emailContext.toLowerCase();
9530
-
9531
- // // Extract potential job role hints
9532
- // const rolePatterns = {
9533
- // manager: ['manage', 'supervise', 'team lead', 'department head'],
9534
- // engineer: ['engineer', 'developer', 'programmer', 'software'],
9535
- // sales: ['sales', 'account executive', 'business development'],
9536
- // marketing: ['marketing', 'campaign', 'brand', 'social media'],
9537
- // executive: ['ceo', 'cto', 'cfo', 'director', 'vp', 'vice president'],
9538
- // };
9539
-
9540
- // for (const [role, patterns] of Object.entries(rolePatterns)) {
9541
- // if (patterns.some((pattern) => context.includes(pattern))) {
9542
- // insights.push(`Possible ${role} role indicated in email`);
9543
- // }
9544
- // }
9545
-
9546
- // // Extract company hints
9547
- // const companyMatch = context.match(/(?:at|from|of)\s+([A-Z][A-Za-z0-9\s&]+)(?:\s|$)/);
9548
- // if (companyMatch && companyMatch[1].length > 2) {
9549
- // insights.push(`Mentioned company/organization: ${companyMatch[1].trim()}`);
9550
- // }
9551
-
9552
- // // Extract project/technology hints
9553
- // const techMatch = context.match(/(?:using|with|built\s+in)\s+([A-Za-z0-9\s+#]+)(?:\s|$)/);
9554
- // if (techMatch) {
9555
- // insights.push(`Technology mentioned: ${techMatch[1].trim()}`);
9556
- // }
9557
-
9558
- // // Extract urgency/priority
9559
- // if (context.includes('urgent') || context.includes('asap') || context.includes('immediately')) {
9560
- // insights.push('Email suggests urgency or time sensitivity');
9561
- // }
9562
-
9563
- // // Extract tone
9564
- // if (context.includes('thank you') || context.includes('appreciate') || context.includes('grateful')) {
9565
- // insights.push('Email shows appreciative/grateful tone');
9566
- // }
9567
-
9568
- // return insights.slice(0, 5); // Limit to 5 insights
9569
- // }
9570
-
9571
- // // Existing helper functions (kept from previous version)
9572
- // function validateURL(url) {
9573
- // /* ... same as before ... */
9574
- // }
9575
- // function validatePhoneNumber(phone) {
9576
- // /* ... same as before ... */
9577
- // }
9578
- // function cleanText(text) {
9579
- // /* ... same as before ... */
9580
- // }
9581
- // function cleanStateProvince(state) {
9582
- // /* ... same as before ... */
9583
- // }
9584
- // function ensureArray(value) {
9585
- // /* ... same as before ... */
9586
- // }
9587
- // function getInitials(firstName, lastName) {
9588
- // /* ... same as before ... */
9589
- // }
9590
- // function calculateSeniorityScore(data) {
9591
- // /* ... same as before ... */
9592
- // }
9593
-
9594
- // function getDefaultPersonInfo(name, email, emailContext = '', error = null) {
9595
- // const nameParts = name.trim().split(/\s+/);
9596
- // const firstName = nameParts[0] || '';
9597
- // const lastName = nameParts.slice(1).join(' ') || '';
9598
- // const domain = email.includes('@') ? email.split('@')[1] : '';
9599
- // const companyGuess = domain
9600
- // .replace(/\..*$/, '')
9601
- // .replace(/[^a-z]/gi, ' ')
9602
- // .replace(/\b\w/g, (l) => l.toUpperCase());
9603
-
9604
- // // Extract basic insights from email context
9605
- // const contextInsights = emailContext ? extractContextInsights(emailContext) : [];
9606
-
9607
- // return {
9608
- // // Basic Information
9609
- // person_full_name: name,
9610
- // person_first_name: firstName,
9611
- // person_last_name: lastName,
9612
- // person_middle_name: '',
9613
- // person_preferred_name: '',
9614
-
9615
- // // Demographic Information
9616
- // person_age: 'unknown',
9617
- // person_gender: 'unknown',
9618
- // person_nationality: 'unknown',
9619
- // person_age_range: 'Unknown',
9620
- // person_pronouns: ['unknown'],
9621
-
9622
- // // Professional Information
9623
- // person_title: 'Professional',
9624
- // person_company: companyGuess || 'Unknown',
9625
- // person_industry: 'Technology',
9626
- // person_bio: 'Information not available',
9627
-
9628
- // // Location
9629
- // person_location_city: 'Not available',
9630
- // person_location_state: 'Not available',
9631
- // person_location_country: 'unknown',
9632
- // person_location_full: 'Not available',
9633
-
9634
- // // Contact Information
9635
- // person_phone: 'Not available',
9636
- // person_email: email,
9637
- // person_email_alternate: '',
9638
-
9639
- // // Education
9640
- // person_education: [],
9641
- // person_education_highest: 'Not available',
9642
-
9643
- // // Professional Details
9644
- // person_skills: [],
9645
- // person_expertise: [],
9646
- // person_career_level: 'unknown',
9647
- // person_years_experience: 0,
9648
-
9649
- // // Social & Online Presence
9650
- // person_linkedin: 'Not available',
9651
- // person_twitter: 'Not available',
9652
- // person_github: 'Not available',
9653
- // person_website: 'Not available',
9654
- // person_social_other: [],
9655
-
9656
- // // Additional Information
9657
- // person_languages: ['English'],
9658
- // person_interests: [],
9659
- // person_achievements: [],
9660
- // person_current_projects: [],
9661
- // person_context_insights: contextInsights,
9662
-
9663
- // // Metadata
9664
- // person_available_for_opportunities: false,
9665
- // person_last_updated: new Date().toISOString(),
9666
- // person_source_confidence: 0,
9667
- // person_has_context_hints: contextInsights.length > 0,
9668
-
9669
- // // Processed fields
9670
- // person_name_initials: getInitials(firstName, lastName),
9671
- // person_seniority_score: 0,
9672
-
9673
- // // Structured objects
9674
- // person_demographics: {
9675
- // age: 'unknown',
9676
- // age_range: 'Unknown',
9677
- // gender: 'unknown',
9678
- // pronouns: ['unknown'],
9679
- // nationality: 'unknown',
9680
- // nationality_name: 'Unknown',
9681
- // },
9682
-
9683
- // person_contact: {
9684
- // email: email,
9685
- // phone: 'Not available',
9686
- // location: {
9687
- // city: 'Not available',
9688
- // state: 'Not available',
9689
- // country: 'unknown',
9690
- // country_name: 'Unknown',
9691
- // full: 'Not available',
9692
- // },
9693
- // },
9694
-
9695
- // person_professional: {
9696
- // title: 'Professional',
9697
- // company: companyGuess || 'Unknown',
9698
- // industry: 'Technology',
9699
- // career_level: 'unknown',
9700
- // years_experience: 0,
9701
- // skills: [],
9702
- // expertise: [],
9703
- // education: [],
9704
- // },
9705
-
9706
- // person_online: {
9707
- // linkedin: 'Not available',
9708
- // twitter: 'Not available',
9709
- // github: 'Not available',
9710
- // website: 'Not available',
9711
- // other: [],
9712
- // },
9713
-
9714
- // context_analysis: {
9715
- // has_context: !!emailContext,
9716
- // context_length: emailContext?.length || 0,
9717
- // extracted_insights: contextInsights,
9718
- // context_useful: contextInsights.length > 0,
9719
- // },
9720
-
9721
- // retrieved_at: new Date().toISOString(),
9722
- // error: error || 'API call failed',
9723
- // };
9724
- // }
9725
-
9726
- // // Build context-aware prompt
9727
- // let context_prompt = `Research the person: "${name}" (${email}).`;
9728
-
9729
- // if (email_context) {
9730
- // context_prompt += `\n\nEMAIL CONTEXT PROVIDED:\n"${email_context.substring(0, 500)}${email_context.length > 500 ? '...' : ''}"`;
9731
- // }
9732
-
9733
- // context_prompt += `
9734
-
9735
- // REQUIRED PERSON INFORMATION:
9736
- // 1. Full name (first, middle, last)
9737
- // 2. Professional title/role
9738
- // 3. Company/organization they work for
9739
- // 4. Industry/field they work in
9740
- // 5. Location (city, state, country)
9741
- // 6. Professional biography (1-2 sentences)
9742
- // 7. Education background
9743
- // 8. Professional skills/expertise
9744
- // 9. Social media profiles (LinkedIn, Twitter, GitHub, etc.)
9745
- // 10. Personal website or portfolio
9746
-
9747
- // DEMOGRAPHIC INFORMATION:
9748
- // 11. Estimated age (based on career, education, and public information)
9749
- // 12. Gender (based on name, pronouns in content, or public profiles)
9750
- // 13. Nationality/country of origin (if discernible) (based on name, pronouns in content, or public profiles)
9751
-
9752
- // CONTACT INFORMATION:
9753
- // 14. Phone number (if available)
9754
- // 15. Alternate email addresses (if available)
9755
- // 16. Physical address (if available and appropriate)
9756
-
9757
- // ADDITIONAL INSIGHTS:
9758
- // 17. Career level (entry, mid, senior, executive, etc.)
9759
- // 18. Years of experience
9760
- // 19. Notable achievements/awards
9761
- // 20. Languages spoken
9762
- // 21. Professional interests
9763
- // 22. Current projects
9764
- // 23. Availability for opportunities
9765
-
9766
- // INSTRUCTIONS:
9767
- // - Use web search to find accurate, public information
9768
- // - Use email context provided to infer additional details
9769
- // - Respect privacy - only include publicly available information
9770
- // - For age: provide numeric estimate or range (e.g., 35, 30-40, unknown)
9771
- // - For gender: use male/female/non-binary/unknown based on available cues
9772
- // - For country: use 2-letter ISO code (e.g., US, IN, UK)
9773
- // - If information is not available, use "Not available" or appropriate defaults
9774
- // - For location, use standard formats (e.g., "San Francisco, CA, USA")
9775
- // - For social media, provide full URLs when available
9776
- // - Focus on professional information suitable for business networking
9777
-
9778
- // Be thorough but respectful of privacy boundaries.`;
9779
-
9780
- // const person_info_ret = await submit_chat_gpt_prompt({
9781
- // uid,
9782
- // prompt: context_prompt,
9783
- // model: 'gpt-5-nano',
9784
- // response_format: z.object({
9785
- // // Basic Information
9786
- // person_full_name: z.string().describe("Person's full name"),
9787
- // person_first_name: z.string().describe('First name'),
9788
- // person_last_name: z.string().describe('Last name'),
9789
- // person_middle_name: z.string().optional().nullable().describe('Middle name if available'),
9790
- // person_preferred_name: z.string().optional().nullable().describe('Preferred/nickname if different'),
9791
-
9792
- // // Demographic Information
9793
- // person_age: z.union([z.number().int().min(18).max(100), z.string().describe("Age range or 'unknown'")]).describe('find age base on the name Estimated age or range'),
9794
- // person_gender: z.enum(['male', 'female']).describe('find Gender based on the name'),
9795
- // person_nationality: z.string().describe('find nationality based on the name Country of origin/nationality (2-letter ISO code)'),
9796
-
9797
- // // Professional Information
9798
- // person_title: z.string().describe('Professional title/role'),
9799
- // person_company: z.string().describe('Current company/organization'),
9800
- // person_industry: z.string().describe('Primary industry/field'),
9801
- // person_bio: z.string().describe('Professional biography (1-2 sentences)'),
9802
-
9803
- // // Location
9804
- // person_location_city: z.string().describe('City of residence/work'),
9805
- // person_location_state: z.string().describe('State/province'),
9806
- // person_location_country: z.string().describe('Country (2-letter ISO code)'),
9807
- // person_location_full: z.string().describe('Full location string'),
9808
-
9809
- // // Contact Information
9810
- // person_phone: z.string().describe("Phone number or 'Not available'"),
9811
- // person_email: z.string().describe('Primary email address'),
9812
- // person_email_alternate: z.string().optional().nullable().describe('Alternate email if available'),
9813
-
9814
- // // Education
9815
- // person_education: z.array(z.string()).describe('Array of educational institutions/degrees'),
9816
- // person_education_highest: z.string().describe('Highest degree obtained'),
9817
-
9818
- // // Professional Details
9819
- // person_skills: z.array(z.string()).describe('Array of professional skills'),
9820
- // person_expertise: z.array(z.string()).describe('Areas of expertise'),
9821
- // person_career_level: z.enum(['entry', 'mid', 'senior', 'lead', 'manager', 'director', 'executive', 'founder', 'unknown']),
9822
- // person_years_experience: z.number().int().min(0).max(60).describe('Years of professional experience'),
9823
-
9824
- // // Social & Online Presence
9825
- // person_linkedin: z.string().describe("LinkedIn profile URL or 'Not available'"),
9826
- // person_twitter: z.string().describe("Twitter/X profile URL or 'Not available'"),
9827
- // person_github: z.string().describe("GitHub profile URL or 'Not available'"),
9828
- // person_website: z.string().describe("Personal website/portfolio or 'Not available'"),
9829
- // person_social_other: z.array(z.string()).optional().nullable().describe('Other social media profiles'),
9830
-
9831
- // // Additional Information
9832
- // person_languages: z.array(z.string()).describe('Languages spoken'),
9833
- // person_interests: z.array(z.string()).describe('Professional/personal interests'),
9834
- // person_achievements: z.array(z.string()).optional().nullable().describe('Notable achievements/awards'),
9835
- // person_current_projects: z.array(z.string()).optional().nullable().describe('Current projects'),
9836
-
9837
- // // Context Extracted Information
9838
- // person_context_insights: z.array(z.string()).optional().nullable().describe('Insights extracted from provided email context'),
9839
-
9840
- // // Metadata
9841
- // person_available_for_opportunities: z.boolean().describe('Open to new opportunities'),
9842
- // person_last_updated: z.string().describe('Date information was last verified'),
9843
- // person_source_confidence: z.number().min(0).max(100).describe('Confidence score for information accuracy'),
9844
- // person_has_context_hints: z.boolean().describe('Whether email context provided useful hints'),
9845
- // }),
9846
- // metadata: {
9847
- // func: 'get_person_info',
9848
- // person_name: name,
9849
- // person_email: email,
9850
- // has_email_context: !!email_context,
9851
- // email_context_length: email_context?.length || 0,
9852
- // context_hash: email_context ? await hashString(email_context.substring(0, 200)) : null,
9853
- // },
9854
- // account_profile_info,
9855
- // tools: [{ type: 'web_search_preview' }],
9856
- // });
9857
-
9858
- // try {
9859
- // if (person_info_ret.code > -1) {
9860
- // const data = typeof person_info_ret.data === 'string' ? JSON.parse(person_info_ret.data) : person_info_ret.data;
9861
-
9862
- // // Process and enhance the data
9863
- // const processedData = processPersonInfo(data, name, email, email_context);
9864
-
9865
- // return processedData;
9866
- // } else {
9867
- // console.error('Person info API call failed:', person_info_ret);
9868
- // return getDefaultPersonInfo(name, email, email_context);
9869
- // }
9870
- // } catch (error) {
9871
- // console.error('Error in get_person_info:', error);
9872
- // return getDefaultPersonInfo(name, email, email_context, error.message);
9873
- // }
9874
- // };
9875
-
9876
- // export const analyze_email_account_type = async function (uid, name, email, account_profile_info, email_context = '') {
9877
- // // ========== HELPER FUNCTIONS ==========
9878
-
9879
- // function enhanceEmailAnalysis(data, name, email, emailContext) {
9880
- // const domain = email.split('@')[1] || '';
9881
- // const localPart = email.split('@')[0] || '';
9882
- // const nameParts = name.toLowerCase().split(/\s+/);
9883
- // const firstName = nameParts[0] || '';
9884
- // const lastName = nameParts.slice(-1)[0] || '';
9885
-
9886
- // // Enhanced business company detection
9887
- // if (data.account_type === 'business' && !data.business_company_name) {
9888
- // data.business_company_name = inferCompanyFromDomain(domain);
9889
- // }
9890
-
9891
- // // Enhanced person detection
9892
- // if (!data.is_real_person) {
9893
- // data.is_real_person = detectRealPerson(localPart, name, domain);
9894
- // }
9895
-
9896
- // if (!data.person_name_in_email) {
9897
- // data.person_name_in_email = checkNameInEmail(localPart, firstName, lastName);
9898
- // }
9899
-
9900
- // // Enhanced pattern analysis
9901
- // if (data.email_pattern === 'unknown') {
9902
- // data.email_pattern = analyzeEmailPattern(localPart, domain);
9903
- // }
9904
-
9905
- // // Enhanced personal provider detection
9906
- // if (data.account_type === 'personal' && !data.personal_account_provider) {
9907
- // data.personal_account_provider = identifyPersonalProvider(domain);
9908
- // }
9909
-
9910
- // // Enhanced risk assessment
9911
- // if (data.spam_risk_level === 'unknown') {
9912
- // data.spam_risk_level = assessSpamRisk(localPart, domain, data.account_type);
9913
- // }
9914
-
9915
- // // Enhanced activity assessment
9916
- // if (!data.is_likely_active) {
9917
- // data.is_likely_active = assessEmailActivity(localPart, domain, data.account_type, data.business_account_category);
9918
- // }
9919
-
9920
- // // Add domain analysis
9921
- // data.domain_analysis = {
9922
- // domain: domain,
9923
- // is_public_provider: isPublicEmailProvider(domain),
9924
- // is_custom_domain: isCustomDomain(domain),
9925
- // is_free_email: isFreeEmailDomain(domain),
9926
- // is_education: isEducationDomain(domain),
9927
- // is_government: isGovernmentDomain(domain),
9928
- // tld: domain.split('.').pop() || '',
9929
- // };
9930
-
9931
- // // Add name-email correlation score
9932
- // data.name_email_correlation = calculateNameEmailCorrelation(localPart, firstName, lastName);
9933
-
9934
- // // Add professional score
9935
- // data.professional_score = calculateProfessionalScore(data);
9936
-
9937
- // // Add structured recommendations
9938
- // data.recommendations = generateRecommendations(data);
9939
-
9940
- // // Add verification suggestions
9941
- // data.verification_suggestions = generateVerificationSuggestions(data, emailContext);
9942
-
9943
- // // Add timestamp
9944
- // data.analysis_timestamp = data.analysis_timestamp || new Date().toISOString();
9945
-
9946
- // return data;
9947
- // }
9948
-
9949
- // function inferCompanyFromDomain(domain) {
9950
- // if (!domain) return 'Unknown';
9951
-
9952
- // // Remove common TLDs and public providers
9953
- // const baseDomain = domain.replace(/\.(com|org|net|co|io|ai|tech|app|dev)$/, '');
9954
-
9955
- // // Remove common subdomains
9956
- // const cleanDomain = baseDomain.replace(/^(mail\.|email\.|webmail\.|smtp\.|mx\.|imap\.)/, '').replace(/\.(com|org|net)$/, '');
9957
-
9958
- // // Convert to readable company name
9959
- // const companyName = cleanDomain
9960
- // .split(/[\.\-]/)
9961
- // .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
9962
- // .join(' ');
9963
-
9964
- // return companyName || 'Unknown';
9965
- // }
9966
-
9967
- // function detectRealPerson(localPart, name, domain) {
9968
- // // Check for generic email addresses
9969
- // const genericPatterns = [
9970
- // 'info',
9971
- // 'support',
9972
- // 'sales',
9973
- // 'contact',
9974
- // 'hello',
9975
- // 'noreply',
9976
- // 'no-reply',
9977
- // 'admin',
9978
- // 'administrator',
9979
- // 'webmaster',
9980
- // 'postmaster',
9981
- // 'hostmaster',
9982
- // 'abuse',
9983
- // 'security',
9984
- // 'billing',
9985
- // 'accounts',
9986
- // 'finance',
9987
- // 'hr',
9988
- // 'humanresources',
9989
- // 'marketing',
9990
- // 'pr',
9991
- // 'press',
9992
- // 'media',
9993
- // 'legal',
9994
- // 'it',
9995
- // 'techsupport',
9996
- // 'help',
9997
- // 'service',
9998
- // 'customerservice',
9999
- // 'feedback',
10000
- // 'inquiries',
10001
- // ];
10002
-
10003
- // const localLower = localPart.toLowerCase();
10004
-
10005
- // // If it matches generic patterns, likely not a real person
10006
- // if (genericPatterns.some((pattern) => localLower === pattern || localLower.startsWith(pattern + '.') || localLower.endsWith('.' + pattern))) {
10007
- // return false;
10008
- // }
10009
-
10010
- // // Check for role-based patterns
10011
- // const rolePatterns = ['ceo', 'cto', 'cfo', 'coo', 'cm', 'director', 'manager', 'head', 'lead', 'senior', 'junior', 'associate', 'analyst', 'engineer', 'developer', 'designer', 'architect', 'consultant', 'advisor'];
10012
-
10013
- // // If contains role patterns but not name, might be generic
10014
- // const hasRolePattern = rolePatterns.some((role) => localLower.includes(role));
10015
- // const hasNameElements = checkNameInEmail(localPart, name.toLowerCase().split(' ')[0], name.toLowerCase().split(' ').slice(-1)[0]);
10016
-
10017
- // if (hasRolePattern && !hasNameElements) {
10018
- // return false;
10019
- // }
10020
-
10021
- // // Check for numeric-only or random strings
10022
- // if (/^\d+$/.test(localPart) || /^[a-f0-9]{32}$/.test(localPart)) {
10023
- // return false;
10024
- // }
10025
-
10026
- // // Check for obvious spam patterns
10027
- // if (localLower.includes('spam') || localLower.includes('bot') || localLower.includes('test')) {
10028
- // return false;
10029
- // }
10030
-
10031
- // return true;
10032
- // }
10033
-
10034
- // function checkNameInEmail(localPart, firstName, lastName) {
10035
- // if (!firstName && !lastName) return false;
10036
-
10037
- // const localLower = localPart.toLowerCase();
10038
- // const firstLower = firstName.toLowerCase();
10039
- // const lastLower = lastName.toLowerCase();
10040
-
10041
- // // Check various name patterns
10042
- // const patterns = [
10043
- // `${firstLower}.${lastLower}`, // john.doe
10044
- // `${firstLower}${lastLower}`, // johndoe
10045
- // `${firstLower.charAt(0)}${lastLower}`, // jdoe
10046
- // `${firstLower}_${lastLower}`, // john_doe
10047
- // `${firstLower}-${lastLower}`, // john-doe
10048
- // `${lastLower}.${firstLower}`, // doe.john
10049
- // `${firstLower.charAt(0)}.${lastLower}`, // j.doe
10050
- // `${lastLower}${firstLower}`, // doejohn
10051
- // `${firstLower}`, // john
10052
- // `${lastLower}`, // doe
10053
- // ];
10054
-
10055
- // return patterns.some((pattern) => localLower === pattern || localLower.startsWith(pattern + '.') || localLower.includes('.' + pattern));
10056
- // }
10057
-
10058
- // function analyzeEmailPattern(localPart, domain) {
10059
- // const localLower = localPart.toLowerCase();
10060
-
10061
- // // Common business patterns
10062
- // if (/^[a-z]+\.[a-z]+$/.test(localLower)) return 'first.last@company.com';
10063
- // if (/^[a-z]+[a-z]+$/.test(localLower) && localLower.length > 5) return 'firstlast@company.com';
10064
- // if (/^[a-z]\.[a-z]+$/.test(localLower)) return 'f.last@company.com';
10065
- // if (/^[a-z][a-z]+$/.test(localLower) && localLower.length <= 5) return 'flast@company.com';
10066
- // if (/^[a-z]+$/.test(localLower) && localLower.length <= 8) return 'first@company.com';
10067
- // if (/^[a-z]+\.[a-z]+\.[a-z]+$/.test(localLower)) return 'first.m.last@company.com';
10068
-
10069
- // // Generic patterns
10070
- // if (/^(info|support|sales|contact|hello)$/.test(localLower)) return 'role@company.com';
10071
- // if (/^(hr|finance|marketing|it|legal)$/.test(localLower)) return 'department@company.com';
10072
-
10073
- // // Personal patterns
10074
- // if (isPublicEmailProvider(domain)) {
10075
- // if (/^[a-z]+\.[a-z]+$/.test(localLower)) return 'first.last@domain.com';
10076
- // if (/^[a-z]+[0-9]+$/.test(localLower)) return 'personal@provider.com';
10077
- // return 'custom@personal.com';
10078
- // }
10079
-
10080
- // return 'unknown';
10081
- // }
10082
-
10083
- // function identifyPersonalProvider(domain) {
10084
- // const providers = {
10085
- // 'gmail.com': 'Google Gmail',
10086
- // 'googlemail.com': 'Google Gmail',
10087
- // 'outlook.com': 'Microsoft Outlook',
10088
- // 'hotmail.com': 'Microsoft Hotmail',
10089
- // 'live.com': 'Microsoft Live',
10090
- // 'yahoo.com': 'Yahoo Mail',
10091
- // 'ymail.com': 'Yahoo Mail',
10092
- // 'aol.com': 'AOL Mail',
10093
- // 'icloud.com': 'Apple iCloud',
10094
- // 'me.com': 'Apple iCloud',
10095
- // 'mac.com': 'Apple iCloud',
10096
- // 'protonmail.com': 'ProtonMail',
10097
- // 'proton.me': 'ProtonMail',
10098
- // 'zoho.com': 'Zoho Mail',
10099
- // 'yandex.com': 'Yandex Mail',
10100
- // 'mail.com': 'Mail.com',
10101
- // 'gmx.com': 'GMX Mail',
10102
- // };
10103
-
10104
- // return providers[domain.toLowerCase()] || 'Custom/Unknown';
10105
- // }
10106
-
10107
- // function isPublicEmailProvider(domain) {
10108
- // const publicProviders = ['gmail.com', 'googlemail.com', 'outlook.com', 'hotmail.com', 'live.com', 'yahoo.com', 'ymail.com', 'aol.com', 'icloud.com', 'me.com', 'mac.com', 'protonmail.com', 'proton.me', 'zoho.com', 'yandex.com', 'mail.com', 'gmx.com'];
10109
-
10110
- // return publicProviders.includes(domain.toLowerCase());
10111
- // }
10112
-
10113
- // function isFreeEmailDomain(domain) {
10114
- // const freeDomains = ['gmail.com', 'yahoo.com', 'outlook.com', 'hotmail.com', 'aol.com', 'mail.com', 'gmx.com', 'yandex.com', 'zoho.com'];
10115
-
10116
- // return freeDomains.includes(domain.toLowerCase());
10117
- // }
10118
-
10119
- // function isCustomDomain(domain) {
10120
- // const publicProviders = ['gmail.com', 'googlemail.com', 'outlook.com', 'hotmail.com', 'live.com', 'yahoo.com', 'ymail.com', 'aol.com', 'icloud.com', 'me.com', 'mac.com', 'protonmail.com', 'proton.me', 'zoho.com', 'yandex.com', 'mail.com', 'gmx.com', 'edu', 'gov', 'mil', 'org', 'net'];
10121
-
10122
- // return !publicProviders.some((provider) => domain.toLowerCase().includes(provider));
10123
- // }
10124
-
10125
- // function isEducationDomain(domain) {
10126
- // return domain.toLowerCase().endsWith('.edu') || domain.toLowerCase().includes('.ac.');
10127
- // }
10128
-
10129
- // function isGovernmentDomain(domain) {
10130
- // return domain.toLowerCase().endsWith('.gov') || domain.toLowerCase().endsWith('.mil');
10131
- // }
10132
-
10133
- // function assessSpamRisk(localPart, domain, accountType) {
10134
- // const localLower = localPart.toLowerCase();
10135
-
10136
- // // High risk indicators
10137
- // if (localLower.includes('spam') || localLower.includes('bot')) return 'high';
10138
- // if (/^[a-f0-9]{32}$/.test(localLower)) return 'high'; // MD5 hash-like
10139
- // if (/^\d+$/.test(localLower)) return 'high'; // Numbers only
10140
- // if (localLower.includes('temp') || localLower.includes('throwaway')) return 'high';
10141
-
10142
- // // Medium risk indicators
10143
- // if (localLower.includes('test') || localLower.includes('demo')) return 'medium';
10144
- // if (accountType === 'personal' && localLower.includes('+')) return 'medium'; // Plus addressing
10145
-
10146
- // // Check disposable email domains
10147
- // if (isDisposableDomain(domain)) return 'high';
10148
-
10149
- // return 'low';
10150
- // }
10151
-
10152
- // function isDisposableDomain(domain) {
10153
- // // Common disposable/temporary email domains
10154
- // const disposableDomains = ['tempmail.com', 'mailinator.com', 'guerrillamail.com', '10minutemail.com', 'yopmail.com', 'trashmail.com', 'dispostable.com', 'fakeinbox.com', 'throwawaymail.com', 'temp-mail.org'];
10155
-
10156
- // return disposableDomains.some((d) => domain.toLowerCase().includes(d));
10157
- // }
10158
-
10159
- // function assessEmailActivity(localPart, domain, accountType, businessCategory) {
10160
- // // Generic/role emails are usually monitored
10161
- // if (accountType === 'business' && ['generic_role', 'department', 'catch_all'].includes(businessCategory)) {
10162
- // return true;
10163
- // }
10164
-
10165
- // // Personal emails with name patterns are likely active
10166
- // if (accountType === 'personal' && /^[a-z]+\.[a-z]+$/.test(localPart.toLowerCase())) {
10167
- // return true;
10168
- // }
10169
-
10170
- // // Education and government emails are usually active
10171
- // if (isEducationDomain(domain) || isGovernmentDomain(domain)) {
10172
- // return true;
10173
- // }
10174
-
10175
- // // Disposable domains are usually inactive after short period
10176
- // if (isDisposableDomain(domain)) {
10177
- // return false;
10178
- // }
10179
-
10180
- // // Default assumption
10181
- // return true;
10182
- // }
10183
-
10184
- // function calculateNameEmailCorrelation(localPart, firstName, lastName) {
10185
- // if (!firstName && !lastName) return 0;
10186
-
10187
- // let score = 0;
10188
- // const localLower = localPart.toLowerCase();
10189
- // const firstLower = firstName.toLowerCase();
10190
- // const lastLower = lastName.toLowerCase();
10191
-
10192
- // // Exact name patterns
10193
- // if (localLower === `${firstLower}.${lastLower}`) score += 40;
10194
- // if (localLower === `${firstLower}${lastLower}`) score += 35;
10195
- // if (localLower === `${firstLower.charAt(0)}${lastLower}`) score += 30;
10196
- // if (localLower === `${firstLower}_${lastLower}`) score += 25;
10197
-
10198
- // // Partial matches
10199
- // if (localLower.includes(firstLower)) score += 15;
10200
- // if (localLower.includes(lastLower)) score += 15;
10201
-
10202
- // // Initial matches
10203
- // if (localLower.startsWith(firstLower.charAt(0))) score += 10;
10204
-
10205
- // // Length consideration (shorter emails with names are better)
10206
- // if (localLower.length <= 20) score += 5;
10207
-
10208
- // return Math.min(score, 100);
10209
- // }
10210
-
10211
- // function calculateProfessionalScore(data) {
10212
- // let score = 50; // Base score
10213
-
10214
- // // Account type weights
10215
- // if (data.account_type === 'business') score += 30;
10216
- // else if (data.account_type === 'personal') score += 10;
10217
-
10218
- // // Real person bonus
10219
- // if (data.is_real_person) score += 20;
10220
-
10221
- // // Active email bonus
10222
- // if (data.is_likely_active) score += 15;
10223
-
10224
- // // Low spam risk bonus
10225
- // if (data.spam_risk_level === 'low') score += 10;
10226
- // else if (data.spam_risk_level === 'high') score -= 20;
10227
-
10228
- // // Name-email correlation bonus
10229
- // score += (data.name_email_correlation / 100) * 20;
10230
-
10231
- // // Business category bonus
10232
- // if (data.business_account_category === 'personal_employee') score += 15;
10233
-
10234
- // return Math.max(0, Math.min(100, score));
10235
- // }
10236
-
10237
- // function generateRecommendations(data) {
10238
- // const recommendations = [];
10239
-
10240
- // if (data.account_type === 'business' && data.is_real_person) {
10241
- // if (data.business_account_category === 'personal_employee') {
10242
- // recommendations.push('Ideal for direct professional outreach');
10243
- // recommendations.push('Suitable for sales, recruitment, and partnership discussions');
10244
- // } else if (data.business_account_category === 'department') {
10245
- // recommendations.push('Best for department-specific inquiries');
10246
- // recommendations.push('Use for customer support or service requests');
10247
- // }
10248
- // } else if (data.account_type === 'personal') {
10249
- // recommendations.push('Suitable for networking and personal connections');
10250
- // recommendations.push('May be used for freelance or consulting work');
10251
- // }
10252
-
10253
- // if (data.spam_risk_level === 'high') {
10254
- // recommendations.push('Consider verifying before important communications');
10255
- // }
10256
-
10257
- // if (!data.is_likely_active) {
10258
- // recommendations.push('Email may not be actively monitored');
10259
- // }
10260
-
10261
- // return recommendations;
10262
- // }
10263
-
10264
- // function generateVerificationSuggestions(data, emailContext) {
10265
- // const suggestions = [];
10266
-
10267
- // if (data.account_type === 'business' && !data.business_company_name) {
10268
- // suggestions.push('Verify company name through LinkedIn or company website');
10269
- // }
10270
-
10271
- // if (!data.is_real_person && data.account_type === 'business') {
10272
- // suggestions.push('Check if this is a role-based email that forwards to individuals');
10273
- // }
10274
-
10275
- // if (data.spam_risk_level === 'medium' || data.spam_risk_level === 'high') {
10276
- // suggestions.push('Send verification email before important communications');
10277
- // }
10278
-
10279
- // if (data.domain_analysis.is_custom_domain) {
10280
- // suggestions.push('Check company website for email format patterns');
10281
- // }
10282
-
10283
- // return suggestions;
10284
- // }
10285
-
10286
- // function getDefaultEmailAnalysis(name, email, emailContext = '', error = null) {
10287
- // const domain = email.split('@')[1] || '';
10288
- // const localPart = email.split('@')[0] || '';
10289
- // const nameParts = name.toLowerCase().split(/\s+/);
10290
- // const firstName = nameParts[0] || '';
10291
- // const lastName = nameParts.slice(-1)[0] || '';
10292
-
10293
- // const isPublicProvider = isPublicEmailProvider(domain);
10294
- // const accountType = isPublicProvider ? 'personal' : 'business';
10295
- // const isRealPerson = detectRealPerson(localPart, name, domain);
10296
-
10297
- // return {
10298
- // success: false,
10299
- // account_type: accountType,
10300
- // account_type_confidence: 70,
10301
-
10302
- // personal_account_provider: isPublicProvider ? identifyPersonalProvider(domain) : undefined,
10303
- // personal_account_type: 'unknown',
10304
- // personal_account_age_indicator: 'unknown',
10305
-
10306
- // business_company_name: !isPublicProvider ? inferCompanyFromDomain(domain) : undefined,
10307
- // business_company_domain: !isPublicProvider ? domain : undefined,
10308
- // business_account_category: !isPublicProvider ? (isRealPerson ? 'personal_employee' : 'generic_role') : undefined,
10309
- // business_account_role: undefined,
10310
- // business_department: undefined,
10311
-
10312
- // is_real_person: isRealPerson,
10313
- // person_name_in_email: checkNameInEmail(localPart, firstName, lastName),
10314
- // person_title_inferred: undefined,
10315
-
10316
- // email_pattern: analyzeEmailPattern(localPart, domain),
10317
-
10318
- // context_supports_business: undefined,
10319
- // context_supports_personal: undefined,
10320
- // context_company_mentions: [],
10321
-
10322
- // is_high_quality_contact: isRealPerson && !isPublicProvider,
10323
- // is_likely_active: true,
10324
- // spam_risk_level: assessSpamRisk(localPart, domain, accountType),
10325
-
10326
- // suggested_use_case: isRealPerson && !isPublicProvider ? 'sales_outreach' : 'networking',
10327
-
10328
- // analysis_timestamp: new Date().toISOString(),
10329
- // analysis_notes: ['Default analysis due to API failure'],
10330
-
10331
- // // Enhanced fields
10332
- // domain_analysis: {
10333
- // domain: domain,
10334
- // is_public_provider: isPublicProvider,
10335
- // is_custom_domain: isCustomDomain(domain),
10336
- // is_free_email: isFreeEmailDomain(domain),
10337
- // is_education: isEducationDomain(domain),
10338
- // is_government: isGovernmentDomain(domain),
10339
- // tld: domain.split('.').pop() || '',
10340
- // },
10341
-
10342
- // name_email_correlation: calculateNameEmailCorrelation(localPart, firstName, lastName),
10343
- // professional_score: calculateProfessionalScore({
10344
- // account_type: accountType,
10345
- // is_real_person: isRealPerson,
10346
- // is_likely_active: true,
10347
- // spam_risk_level: assessSpamRisk(localPart, domain, accountType),
10348
- // name_email_correlation: calculateNameEmailCorrelation(localPart, firstName, lastName),
10349
- // business_account_category: !isPublicProvider ? (isRealPerson ? 'personal_employee' : 'generic_role') : undefined,
10350
- // }),
10351
-
10352
- // recommendations: generateRecommendations({
10353
- // account_type: accountType,
10354
- // is_real_person: isRealPerson,
10355
- // business_account_category: !isPublicProvider ? (isRealPerson ? 'personal_employee' : 'generic_role') : undefined,
10356
- // spam_risk_level: assessSpamRisk(localPart, domain, accountType),
10357
- // is_likely_active: true,
10358
- // }),
10359
-
10360
- // verification_suggestions: generateVerificationSuggestions(
10361
- // {
10362
- // account_type: accountType,
10363
- // business_company_name: !isPublicProvider ? inferCompanyFromDomain(domain) : undefined,
10364
- // is_real_person: isRealPerson,
10365
- // spam_risk_level: assessSpamRisk(localPart, domain, accountType),
10366
- // domain_analysis: { is_custom_domain: isCustomDomain(domain) },
10367
- // },
10368
- // emailContext,
10369
- // ),
10370
-
10371
- // error: error || 'API call failed',
10372
- // };
10373
- // }
10374
-
10375
- // const analysis_ret = await submit_chat_gpt_prompt({
10376
- // uid,
10377
- // prompt: `Analyze this email account: "${email}" for person: "${name}"
10378
-
10379
- // EMAIL CONTEXT (if provided):
10380
- // "${email_context.substring(0, 400)}${email_context.length > 400 ? '...' : ''}"
10381
-
10382
- // ANALYSIS TASKS:
10383
- // 1. Determine if this is a PERSONAL or BUSINESS email account
10384
- // 2. For BUSINESS accounts:
10385
- // - Identify the company/organization
10386
- // - Determine if this email belongs to a REAL PERSON at the company
10387
- // - Or if it's a generic/role-based account
10388
- // 3. For PERSONAL accounts:
10389
- // - Identify which personal email provider is used
10390
- // - Determine if it's likely a primary or secondary personal account
10391
-
10392
- // ANALYSIS CRITERIA:
10393
- // BUSINESS EMAIL INDICATORS:
10394
- // - Domain matches a known company (not public email providers)
10395
- // - Email format matches company naming conventions
10396
- // - Email is mentioned in professional context
10397
- // - Contains company-specific signature or details
10398
-
10399
- // PERSONAL EMAIL INDICATORS:
10400
- // - Domain is from public email providers (gmail.com, outlook.com, yahoo.com, etc.)
10401
- // - Email format is personal/creative
10402
- // - No company affiliation in context
10403
- // - Used for personal communications
10404
-
10405
- // PERSON VS GENERIC BUSINESS ACCOUNT:
10406
- // - PERSON: Contains personal name elements (john.doe@company.com)
10407
- // - GENERIC: info@, support@, sales@, contact@, hello@, noreply@, etc.
10408
- // - DEPARTMENT: hr@, finance@, marketing@, it@, etc.
10409
-
10410
- // COMPANY DETECTION:
10411
- // - Extract company from email domain when possible
10412
- // - Use name patterns to identify likely companies
10413
- // - Consider email context for company references
10414
-
10415
- // PROVIDE DETAILED ANALYSIS WITH CONFIDENCE LEVELS.`,
10416
- // model: 'gpt-5-nano',
10417
- // response_format: z.object({
10418
- // // Primary Classification
10419
- // account_type: z.enum(['personal', 'business', 'ambiguous']),
10420
- // account_type_confidence: z.number().min(0).max(100),
10421
-
10422
- // // Personal Account Details
10423
- // personal_account_provider: z.string().optional().nullable().describe('Email provider for personal accounts'),
10424
- // personal_account_type: z.enum(['primary', 'secondary', 'disposable', 'unknown']).optional().nullable(),
10425
- // personal_account_age_indicator: z.enum(['new', 'established', 'old', 'unknown']).optional().nullable(),
10426
-
10427
- // // Business Account Details
10428
- // business_company_name: z.string().optional().nullable().describe('Company name if business account'),
10429
- // business_company_domain: z.string().optional().nullable().describe('Company domain'),
10430
- // business_account_category: z.enum(['personal_employee', 'generic_role', 'department', 'catch_all', 'unknown']).optional().nullable(),
10431
- // business_account_role: z.string().optional().nullable().describe('Role suggested by email address'),
10432
- // business_department: z.string().optional().nullable().describe('Department if applicable'),
10433
-
10434
- // // Person Analysis
10435
- // is_real_person: z.boolean().describe('Whether email belongs to a real person'),
10436
- // person_name_in_email: z.boolean().describe("Whether person's name appears in email address"),
10437
- // person_title_inferred: z.string().optional().nullable().describe('Inferred job title from email pattern'),
10438
-
10439
- // // Email Pattern Analysis
10440
- // email_pattern: z.enum([
10441
- // 'first.last@company.com',
10442
- // 'first.last@domain.com',
10443
- // 'firstlast@company.com',
10444
- // 'flast@company.com',
10445
- // 'first@company.com',
10446
- // 'f.last@company.com',
10447
- // 'initial.last@company.com',
10448
- // 'role@company.com',
10449
- // 'department@company.com',
10450
- // 'info@company.com',
10451
- // 'generic@company.com',
10452
- // 'personal@provider.com',
10453
- // 'custom@personal.com',
10454
- // 'unknown',
10455
- // ]),
10456
-
10457
- // // Context Analysis
10458
- // context_supports_business: z.boolean().optional().nullable().describe('Email context suggests business use'),
10459
- // context_supports_personal: z.boolean().optional().nullable().describe('Email context suggests personal use'),
10460
- // context_company_mentions: z.array(z.string()).optional().nullable().describe('Companies mentioned in context'),
10461
-
10462
- // // Risk & Quality Assessment
10463
- // is_high_quality_contact: z.boolean().describe('Good contact for professional outreach'),
10464
- // is_likely_active: z.boolean().describe('Email likely actively monitored'),
10465
- // spam_risk_level: z.enum(['low', 'medium', 'high', 'unknown']),
10466
-
10467
- // // Recommendations
10468
- // suggested_use_case: z.enum(['sales_outreach', 'recruitment', 'customer_support', 'partnership', 'networking', 'personal_contact', 'avoid']),
10469
-
10470
- // // Metadata
10471
- // analysis_timestamp: z.string().describe('When analysis was performed'),
10472
- // analysis_notes: z.array(z.string()).optional().nullable().describe('Key observations from analysis'),
10473
- // }),
10474
- // metadata: {
10475
- // func: 'analyze_email_account_type',
10476
- // person_name: name,
10477
- // person_email: email,
10478
- // has_email_context: !!email_context,
10479
- // email_length: email_context?.length || 0,
10480
- // },
10481
- // account_profile_info,
10482
- // tools: [{ type: 'web_search_preview' }],
10483
- // });
10484
-
10485
- // try {
10486
- // if (analysis_ret.code > -1) {
10487
- // const data = typeof analysis_ret.data === 'string' ? JSON.parse(analysis_ret.data) : analysis_ret.data;
10488
-
10489
- // // Enhance with additional analysis
10490
- // const enhancedData = enhanceEmailAnalysis(data, name, email, email_context);
10491
-
10492
- // return {
10493
- // success: true,
10494
- // ...enhancedData,
10495
- // };
10496
- // } else {
10497
- // console.error('Email analysis API call failed:', analysis_ret);
10498
- // return getDefaultEmailAnalysis(name, email, email_context);
10499
- // }
10500
- // } catch (error) {
10501
- // console.error('Error in analyze_email_account_type:', error);
10502
- // return getDefaultEmailAnalysis(name, email, email_context, error.message);
10503
- // }
10504
- // };
10505
-
10506
- // export const detect_email_type = async function (uid, name, email, account_profile_info, email_body = '', email_subject = '') {
10507
- // // ========== HELPER FUNCTIONS ==========
10508
-
10509
- // async function hashString(str) {
10510
- // const encoder = new TextEncoder();
10511
- // const data = encoder.encode(str);
10512
- // const hashBuffer = await crypto.subtle.digest('SHA-256', data);
10513
- // const hashArray = Array.from(new Uint8Array(hashBuffer));
10514
- // return hashArray
10515
- // .map((b) => b.toString(16).padStart(2, '0'))
10516
- // .join('')
10517
- // .substring(0, 16);
10518
- // }
10519
-
10520
- // function enhanceEmailDetection(data, name, email, emailBody, emailSubject) {
10521
- // // Run additional local analysis
10522
- // const localAnalysis = analyzeEmailLocally(emailBody, emailSubject, email, name);
10523
-
10524
- // // Combine AI analysis with local analysis
10525
- // const combinedData = {
10526
- // ...data,
10527
- // // Override with local analysis if confidence is high
10528
- // spam_confidence: Math.max(data.spam_confidence, localAnalysis.spamScore),
10529
- // phishing_risk: localAnalysis.phishingScore > 70 ? 'high' : data.phishing_risk,
10530
-
10531
- // // Add local analysis results
10532
- // local_analysis: localAnalysis,
10533
-
10534
- // // Enhance sender analysis
10535
- // sender_analysis: analyzeSender(email, name, emailBody),
10536
-
10537
- // // Content statistics
10538
- // content_stats: {
10539
- // word_count: (emailBody.match(/\S+/g) || []).length,
10540
- // sentence_count: (emailBody.match(/[.!?]+/g) || []).length,
10541
- // link_count: (emailBody.match(/https?:\/\/[^\s]+/g) || []).length,
10542
- // uppercase_ratio: calculateUppercaseRatio(emailBody),
10543
- // exclamation_count: (emailBody.match(/!/g) || []).length,
10544
- // dollar_sign_count: (emailBody.match(/\$/g) || []).length,
10545
- // phone_patterns: (emailBody.match(/\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g) || []).length,
10546
- // },
10547
-
10548
- // // Behavioral patterns
10549
- // behavioral_patterns: detectBehavioralPatterns(emailBody, emailSubject),
10550
-
10551
- // // Domain reputation
10552
- // domain_reputation: assessDomainReputation(email),
10553
-
10554
- // // Add comprehensive risk assessment
10555
- // comprehensive_risk_score: calculateComprehensiveRisk(data, localAnalysis),
10556
-
10557
- // // Filter rules that matched
10558
- // matched_filters: detectMatchedFilters(emailBody, emailSubject, email, name),
10559
-
10560
- // // Timeline analysis
10561
- // temporal_analysis: {
10562
- // is_time_sensitive: detectTimeSensitivity(emailBody),
10563
- // has_expiry: detectExpiryDate(emailBody),
10564
- // is_follow_up: detectFollowUpPattern(emailBody, emailSubject),
10565
- // },
10566
-
10567
- // // Relationship context
10568
- // relationship_context: analyzeRelationshipContext(emailBody, emailSubject, name),
10569
-
10570
- // // Update timestamp
10571
- // analysis_timestamp: new Date().toISOString(),
10572
- // content_length: emailBody.length,
10573
- // };
10574
-
10575
- // // Calculate final classification confidence
10576
- // combinedData.final_confidence = calculateFinalConfidence(combinedData);
10577
-
10578
- // // Generate detailed explanation
10579
- // combinedData.explanation = generateExplanation(combinedData);
10580
-
10581
- // // Add compliance flags
10582
- // combinedData.compliance_flags = checkCompliance(emailBody, emailSubject);
10583
-
10584
- // return combinedData;
10585
- // }
10586
-
10587
- // function analyzeEmailLocally(body, subject, email, name) {
10588
- // const text = (subject + ' ' + body).toLowerCase();
10589
- // let spamScore = 0;
10590
- // let phishingScore = 0;
10591
- // let promotionalScore = 0;
10592
- // let transactionalScore = 0;
10593
-
10594
- // // SPAM indicators
10595
- // const spamKeywords = [
10596
- // 'congratulations',
10597
- // 'winner',
10598
- // 'prize',
10599
- // 'lottery',
10600
- // 'free',
10601
- // 'guaranteed',
10602
- // 'risk-free',
10603
- // 'act now',
10604
- // 'limited time',
10605
- // 'urgent',
10606
- // 'important',
10607
- // 'attention',
10608
- // 'alert',
10609
- // 'click here',
10610
- // 'buy now',
10611
- // 'order now',
10612
- // 'discount',
10613
- // 'save big',
10614
- // 'cheap',
10615
- // 'viagra',
10616
- // 'cialis',
10617
- // 'pharmacy',
10618
- // 'prescription',
10619
- // 'enlarge',
10620
- // 'weight loss',
10621
- // 'nigerian',
10622
- // 'prince',
10623
- // 'inheritance',
10624
- // 'unclaimed',
10625
- // 'bank account',
10626
- // 'password',
10627
- // 'account suspended',
10628
- // 'verify',
10629
- // 'security alert',
10630
- // 'dear friend',
10631
- // 'dear customer',
10632
- // 'dear account holder',
10633
- // ];
10634
-
10635
- // spamKeywords.forEach((keyword) => {
10636
- // if (text.includes(keyword)) spamScore += 2;
10637
- // });
10638
-
10639
- // // Phishing indicators
10640
- // const phishingPatterns = [/login\s*(?:here|now)/i, /verify\s*(?:your|my)\s*account/i, /password\s*(?:reset|expired|change)/i, /suspended\s*account/i, /unauthorized\s*activity/i, /security\s*breach/i, /update\s*(?:your|my)\s*information/i, /confirm\s*(?:your|my)\s*identity/i];
10641
-
10642
- // phishingPatterns.forEach((pattern) => {
10643
- // if (pattern.test(text)) phishingScore += 15;
10644
- // });
10645
-
10646
- // // Promotional indicators
10647
- // const promotionalKeywords = ['newsletter', 'subscribe', 'unsubscribe', 'marketing', 'promotion', 'sale', 'offer', 'deal', 'coupon', 'voucher', 'discount code', 'new product', 'announcement', 'launch', 'event', 'webinar', 'limited offer', 'exclusive', 'special offer', 'members only'];
10648
-
10649
- // promotionalKeywords.forEach((keyword) => {
10650
- // if (text.includes(keyword)) promotionalScore += 3;
10651
- // });
10652
-
10653
- // // Transactional indicators
10654
- // const transactionalKeywords = ['order', 'invoice', 'receipt', 'payment', 'booking', 'reservation', 'confirmation', 'shipping', 'delivery', 'tracking', 'shipment', 'appointment', 'meeting', 'reminder', 'bill', 'statement', 'account', 'statement', 'balance', 'transaction'];
10655
-
10656
- // transactionalKeywords.forEach((keyword) => {
10657
- // if (text.includes(keyword)) transactionalScore += 3;
10658
- // });
10659
-
10660
- // // Link analysis
10661
- // const links = body.match(/https?:\/\/[^\s]+/g) || [];
10662
- // const suspiciousDomains = ['bit.ly', 'tinyurl', 'shorte.st', 'adf.ly', 'goo.gl'];
10663
-
10664
- // links.forEach((link) => {
10665
- // if (suspiciousDomains.some((domain) => link.includes(domain))) {
10666
- // spamScore += 10;
10667
- // phishingScore += 10;
10668
- // }
10669
- // });
10670
-
10671
- // // Grammar/spelling analysis (simple)
10672
- // const misspellings = body.match(/\b(?:recieve|seperate|definately|occured|tomm?orrow)\b/gi) || [];
10673
- // spamScore += misspellings.length * 2;
10674
-
10675
- // // Urgency analysis
10676
- // const urgencyWords = ['urgent', 'immediately', 'asap', 'right now', 'today only'];
10677
- // let urgencyCount = 0;
10678
- // urgencyWords.forEach((word) => {
10679
- // if (text.includes(word)) urgencyCount++;
10680
- // });
10681
- // spamScore += urgencyCount * 5;
10682
-
10683
- // // Personalization check
10684
- // const hasName = name && body.toLowerCase().includes(name.toLowerCase().split(' ')[0]);
10685
- // const personalPronouns = ['you', 'your', 'yours'];
10686
- // let personalCount = 0;
10687
- // personalPronouns.forEach((pronoun) => {
10688
- // const regex = new RegExp(`\\b${pronoun}\\b`, 'gi');
10689
- // personalCount += (body.match(regex) || []).length;
10690
- // });
10691
-
10692
- // const personalizationScore = hasName ? 30 : Math.min(personalCount * 2, 20);
10693
-
10694
- // return {
10695
- // spamScore: Math.min(spamScore, 100),
10696
- // phishingScore: Math.min(phishingScore, 100),
10697
- // promotionalScore: Math.min(promotionalScore, 100),
10698
- // transactionalScore: Math.min(transactionalScore, 100),
10699
- // personalizationScore,
10700
- // linkCount: links.length,
10701
- // hasUnsubscribe: text.includes('unsubscribe') || text.includes('opt-out'),
10702
- // hasPhone: /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/.test(body),
10703
- // hasAddress: /\b\d+\s+[\w\s]+(?:street|st|avenue|ave|road|rd|boulevard|blvd|way)\b/i.test(body),
10704
- // urgencyCount,
10705
- // misspellingCount: misspellings.length,
10706
- // };
10707
- // }
10708
-
10709
- // function analyzeSender(email, name, body) {
10710
- // const domain = email.split('@')[1] || '';
10711
- // const localPart = email.split('@')[0] || '';
10712
-
10713
- // return {
10714
- // email: email,
10715
- // domain: domain,
10716
- // local_part: localPart,
10717
- // is_public_domain: isPublicEmailDomain(domain),
10718
- // is_generic_sender: isGenericSender(localPart, name),
10719
- // domain_age_indicator: assessDomainAge(domain),
10720
- // sender_consistency: checkSenderConsistency(name, email, body),
10721
- // };
10722
- // }
10723
-
10724
- // function isPublicEmailDomain(domain) {
10725
- // const publicDomains = ['gmail.com', 'yahoo.com', 'outlook.com', 'hotmail.com', 'aol.com', 'icloud.com', 'protonmail.com', 'zoho.com', 'yandex.com'];
10726
- // return publicDomains.includes(domain.toLowerCase());
10727
- // }
10728
-
10729
- // function isGenericSender(localPart, name) {
10730
- // const genericSenders = ['info', 'support', 'sales', 'contact', 'hello', 'noreply', 'admin', 'newsletter', 'marketing', 'team', 'notifications'];
10731
-
10732
- // const localLower = localPart.toLowerCase();
10733
- // const nameLower = name.toLowerCase();
10734
-
10735
- // return genericSenders.some((sender) => localLower.includes(sender) || nameLower.includes(sender));
10736
- // }
10737
-
10738
- // function assessDomainAge(domain) {
10739
- // // This is a simplified version - in production, you'd use a domain age API
10740
- // const newDomains = ['xyz', 'online', 'site', 'top', 'club', 'shop'];
10741
- // const tld = domain.split('.').pop() || '';
10742
-
10743
- // if (newDomains.includes(tld)) return 'likely_new';
10744
- // if (['com', 'org', 'net', 'edu', 'gov'].includes(tld)) return 'likely_established';
10745
- // return 'unknown';
10746
- // }
10747
-
10748
- // function checkSenderConsistency(name, email, body) {
10749
- // const emailName = email.split('@')[0].toLowerCase();
10750
- // const bodyName = name.toLowerCase();
10751
-
10752
- // // Check if name appears in body
10753
- // const nameInBody = body.toLowerCase().includes(bodyName.split(' ')[0]);
10754
-
10755
- // // Check email-name consistency patterns
10756
- // const nameParts = bodyName.split(' ');
10757
- // const firstName = nameParts[0] || '';
10758
- // const lastName = nameParts.slice(-1)[0] || '';
10759
-
10760
- // const patterns = [`${firstName}.${lastName}`, `${firstName}${lastName}`, `${firstName.charAt(0)}${lastName}`, `${firstName}`];
10761
-
10762
- // const consistent = patterns.some((pattern) => emailName.includes(pattern.toLowerCase()));
10763
-
10764
- // return {
10765
- // name_in_body: nameInBody,
10766
- // email_name_consistent: consistent,
10767
- // consistency_score: (nameInBody ? 40 : 0) + (consistent ? 60 : 0),
10768
- // };
10769
- // }
10770
-
10771
- // function calculateUppercaseRatio(text) {
10772
- // const letters = text.replace(/[^a-zA-Z]/g, '');
10773
- // if (letters.length === 0) return 0;
10774
-
10775
- // const uppercase = letters.replace(/[^A-Z]/g, '');
10776
- // return (uppercase.length / letters.length) * 100;
10777
- // }
10778
-
10779
- // function detectBehavioralPatterns(body, subject) {
10780
- // const text = (subject + ' ' + body).toLowerCase();
10781
- // const patterns = [];
10782
-
10783
- // if (/(?:click|tap)\s+(?:here|this|link|button)/i.test(text)) {
10784
- // patterns.push('call_to_action_link');
10785
- // }
10786
-
10787
- // if (/limited\s+time|offer\s+expires|only\s+\d+\s+left/i.test(text)) {
10788
- // patterns.push('scarcity_tactic');
10789
- // }
10790
-
10791
- // if (/\$\d+|\d+\s*%|\d+\s*off|discount|save|sale/i.test(text)) {
10792
- // patterns.push('monetary_offer');
10793
- // }
10794
-
10795
- // if (/urgent|important|alert|attention|warning/i.test(text)) {
10796
- // patterns.push('urgency_tactic');
10797
- // }
10798
-
10799
- // if (/(?:please|kindly)\s+(?:help|assist|reply)/i.test(text)) {
10800
- // patterns.push('polite_request');
10801
- // }
10802
-
10803
- // if (/unsubscribe|opt.?out|preference|manage subscription/i.test(text)) {
10804
- // patterns.push('subscription_management');
10805
- // }
10806
-
10807
- // return patterns;
10808
- // }
10809
-
10810
- // function assessDomainReputation(email) {
10811
- // const domain = email.split('@')[1] || '';
10812
-
10813
- // // Known spam domains (simplified list)
10814
- // const spamDomains = ['spam4.me', 'trashmail.com', 'mailinator.com', 'guerrillamail.com', 'tempmail.com', 'yopmail.com', 'dispostable.com'];
10815
-
10816
- // if (spamDomains.includes(domain.toLowerCase())) {
10817
- // return 'known_spam_domain';
10818
- // }
10819
-
10820
- // // Professional domains
10821
- // const professionalTLDs = ['com', 'org', 'net', 'edu', 'gov', 'io', 'ai', 'tech'];
10822
- // const tld = domain.split('.').pop() || '';
10823
-
10824
- // if (professionalTLDs.includes(tld.toLowerCase())) {
10825
- // return 'professional_domain';
10826
- // }
10827
-
10828
- // // New/suspicious TLDs
10829
- // const suspiciousTLDs = ['xyz', 'top', 'win', 'bid', 'download', 'stream'];
10830
- // if (suspiciousTLDs.includes(tld.toLowerCase())) {
10831
- // return 'suspicious_tld';
10832
- // }
10833
-
10834
- // return 'neutral';
10835
- // }
10836
-
10837
- // function calculateComprehensiveRisk(aiData, localAnalysis) {
10838
- // let risk = 0;
10839
-
10840
- // // Base on AI classification
10841
- // switch (aiData.email_type) {
10842
- // case 'spam':
10843
- // risk += 80;
10844
- // break;
10845
- // case 'promotional':
10846
- // risk += 30;
10847
- // break;
10848
- // case 'transactional':
10849
- // risk += 10;
10850
- // break;
10851
- // case 'personal':
10852
- // risk += 5;
10853
- // break;
10854
- // case 'business':
10855
- // risk += 15;
10856
- // break;
10857
- // }
10858
-
10859
- // // Add local analysis scores
10860
- // risk += localAnalysis.spamScore * 0.2;
10861
- // risk += localAnalysis.phishingScore * 0.3;
10862
-
10863
- // // Adjust for phishing risk
10864
- // switch (aiData.phishing_risk) {
10865
- // case 'critical':
10866
- // risk += 40;
10867
- // break;
10868
- // case 'high':
10869
- // risk += 30;
10870
- // break;
10871
- // case 'medium':
10872
- // risk += 15;
10873
- // break;
10874
- // case 'low':
10875
- // risk += 5;
10876
- // break;
10877
- // }
10878
-
10879
- // // Adjust for unsolicited
10880
- // if (aiData.is_unsolicited) risk += 20;
10881
-
10882
- // // Adjust for urgency
10883
- // if (aiData.is_urgent) risk += 10;
10884
-
10885
- // return Math.min(risk, 100);
10886
- // }
10887
-
10888
- // function detectMatchedFilters(body, subject, email, name) {
10889
- // const filters = [];
10890
- // const text = (subject + ' ' + body).toLowerCase();
10891
-
10892
- // // Spam filters
10893
- // if (/(?:viagra|cialis|penis|enlarge)/i.test(text)) filters.push('adult_content_filter');
10894
- // if (/(?:lottery|winner|prize|jackpot)/i.test(text)) filters.push('lottery_scam_filter');
10895
- // if (/(?:nigerian|prince|inheritance|unclaimed)/i.test(text)) filters.push('inheritance_scam_filter');
10896
- // if (/password\s+reset|verify\s+account/i.test(text)) filters.push('account_verification_filter');
10897
-
10898
- // // Promotional filters
10899
- // if (/newsletter|subscribe|unsubscribe/i.test(text)) filters.push('newsletter_filter');
10900
- // if (/sale|discount|offer|coupon/i.test(text)) filters.push('promotional_offer_filter');
10901
- // if (/webinar|event|conference/i.test(text)) filters.push('event_filter');
10902
-
10903
- // // Transactional filters
10904
- // if (/order|invoice|receipt|payment/i.test(text)) filters.push('transaction_filter');
10905
- // if (/shipping|delivery|tracking/i.test(text)) filters.push('shipping_filter');
10906
- // if (/appointment|meeting|reminder/i.test(text)) filters.push('calendar_filter');
10907
-
10908
- // return filters;
10909
- // }
10910
-
10911
- // function detectTimeSensitivity(body) {
10912
- // const text = body.toLowerCase();
10913
- // const patterns = [/today|tomorrow|this\s+week|immediately|asap/i, /deadline|due\s+by|expires|limited\s+time/i, /urgent|important|attention|alert/i];
10914
-
10915
- // return patterns.some((pattern) => pattern.test(text));
10916
- // }
10917
-
10918
- // function detectExpiryDate(body) {
10919
- // const datePatterns = [/\b\d{1,2}\/\d{1,2}\/\d{2,4}\b/g, /\b\d{1,2}\s+(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*\s+\d{2,4}\b/gi, /\bexpires?\s+(?:on|by)?\s*[:]?\s*\d{1,2}\/\d{1,2}\/\d{2,4}\b/gi];
10920
-
10921
- // return datePatterns.some((pattern) => pattern.test(body.toLowerCase()));
10922
- // }
10923
-
10924
- // function detectFollowUpPattern(body, subject) {
10925
- // const text = (subject + ' ' + body).toLowerCase();
10926
- // return /follow.?up|following.?up|checking.?in|touch.?base|re:.?re:/i.test(text);
10927
- // }
10928
-
10929
- // function analyzeRelationshipContext(body, subject, name) {
10930
- // const text = (subject + ' ' + body).toLowerCase();
10931
- // const nameParts = name.toLowerCase().split(' ');
10932
- // const firstName = nameParts[0] || '';
10933
-
10934
- // const indicators = {
10935
- // uses_name: firstName && text.includes(firstName),
10936
- // uses_personal_pronouns: /\b(?:i|me|my|mine|you|your|yours)\b/gi.test(text),
10937
- // has_greeting: /^(?:hi|hello|hey|dear|greetings)\b/im.test(body),
10938
- // has_signature: /(?:best|regards|sincerely|thanks|thank you)\s*[,]?\s*\n/im.test(body),
10939
- // has_questions: /\?/.test(text) && /(?:can|could|would|will|do|are|is)\s+you/i.test(text),
10940
- // };
10941
-
10942
- // const relationshipScore = Object.values(indicators).filter(Boolean).length * 20;
10943
-
10944
- // return {
10945
- // ...indicators,
10946
- // relationship_score: Math.min(relationshipScore, 100),
10947
- // likely_known_sender: relationshipScore >= 40,
10948
- // };
10949
- // }
10950
-
10951
- // function calculateFinalConfidence(data) {
10952
- // let confidence = data.email_type_confidence;
10953
-
10954
- // // Adjust based on local analysis
10955
- // if (data.local_analysis.spamScore > 70 && data.email_type !== 'spam') {
10956
- // confidence -= 20;
10957
- // }
10958
-
10959
- // // Adjust based on phishing risk
10960
- // if (data.phishing_risk === 'critical' || data.phishing_risk === 'high') {
10961
- // confidence += 15;
10962
- // }
10963
-
10964
- // // Adjust based on personalization
10965
- // if (data.is_personalized) {
10966
- // confidence += 10;
10967
- // }
10968
-
10969
- // // Adjust based on content stats
10970
- // if (data.content_stats.link_count > 5) {
10971
- // confidence += 5;
10972
- // }
10973
-
10974
- // return Math.max(0, Math.min(100, confidence));
10975
- // }
10976
-
10977
- // function generateExplanation(data) {
10978
- // const explanations = [];
10979
-
10980
- // if (data.email_type === 'spam') {
10981
- // explanations.push('Classified as spam due to:');
10982
- // if (data.spam_confidence > 70) explanations.push(`- High spam confidence (${data.spam_confidence}%)`);
10983
- // if (data.phishing_risk !== 'none') explanations.push(`- ${data.phishing_risk} phishing risk`);
10984
- // if (data.local_analysis.spamScore > 60) explanations.push('- Contains spam indicators');
10985
- // }
10986
-
10987
- // if (data.email_type === 'promotional') {
10988
- // explanations.push('Classified as promotional due to:');
10989
- // if (data.is_commercial) explanations.push('- Commercial intent detected');
10990
- // if (data.local_analysis.hasUnsubscribe) explanations.push('- Contains unsubscribe option');
10991
- // if (data.local_analysis.promotionalScore > 30) explanations.push('- Promotional content detected');
10992
- // }
10993
-
10994
- // if (data.key_indicators && data.key_indicators.length > 0) {
10995
- // explanations.push('Key indicators:');
10996
- // data.key_indicators.forEach((indicator) => {
10997
- // explanations.push(`- ${indicator}`);
10998
- // });
10999
- // }
11000
-
11001
- // return explanations.join('\n');
11002
- // }
11003
-
11004
- // function checkCompliance(body, subject) {
11005
- // const text = (subject + ' ' + body).toLowerCase();
11006
- // const flags = [];
11007
-
11008
- // // CAN-SPAM Act compliance (US)
11009
- // if (text.includes('unsubscribe') || text.includes('opt-out')) {
11010
- // flags.push('has_unsubscribe_option');
11011
- // }
11012
-
11013
- // if (/\b\d{10}\b/.test(body.replace(/\D/g, ''))) {
11014
- // flags.push('contains_phone_number');
11015
- // }
11016
-
11017
- // if (/address\s*[:]?\s*\d+\s+[\w\s]+/i.test(body)) {
11018
- // flags.push('contains_physical_address');
11019
- // }
11020
-
11021
- // // GDPR indicators (EU)
11022
- // if (/privacy\s+policy|gdpr|data\s+protection/i.test(text)) {
11023
- // flags.push('gdpr_mentions');
11024
- // }
11025
-
11026
- // if (/consent|opt.?in|permission/i.test(text)) {
11027
- // flags.push('consent_mentions');
11028
- // }
11029
-
11030
- // return flags;
11031
- // }
11032
-
11033
- // function getDefaultEmailDetection(name, email, emailBody, emailSubject, error = null) {
11034
- // const localAnalysis = analyzeEmailLocally(emailBody, emailSubject, email, name);
11035
-
11036
- // // Determine type based on local analysis
11037
- // let emailType = 'ambiguous';
11038
- // if (localAnalysis.spamScore > 70) emailType = 'spam';
11039
- // else if (localAnalysis.promotionalScore > localAnalysis.transactionalScore && localAnalysis.promotionalScore > 30) emailType = 'promotional';
11040
- // else if (localAnalysis.transactionalScore > 40) emailType = 'transactional';
11041
-
11042
- // const spamConfidence = localAnalysis.spamScore;
11043
- // const phishingRisk = localAnalysis.phishingScore > 50 ? 'medium' : 'low';
11044
-
11045
- // return {
11046
- // success: false,
11047
- // email_type: emailType,
11048
- // email_type_confidence: Math.max(50, spamConfidence),
11049
- // email_subtype: 'personal_message',
11050
-
11051
- // spam_confidence: spamConfidence,
11052
- // phishing_risk: phishingRisk,
11053
- // malware_risk: 'none',
11054
-
11055
- // is_unsolicited: true,
11056
- // is_commercial: localAnalysis.promotionalScore > 30,
11057
- // is_urgent: localAnalysis.urgencyCount > 0,
11058
- // is_personalized: localAnalysis.personalizationScore > 20,
11059
-
11060
- // sender_legitimacy: 'unknown',
11061
- // sender_intent: 'unknown',
11062
-
11063
- // contains_links: localAnalysis.linkCount > 0,
11064
- // contains_attachments: false,
11065
- // contains_unsubscribe: localAnalysis.hasUnsubscribe,
11066
- // contains_phone_number: localAnalysis.hasPhone,
11067
- // contains_address: localAnalysis.hasAddress,
11068
-
11069
- // language_quality: localAnalysis.misspellingCount > 3 ? 'poor' : 'average',
11070
- // urgency_level: localAnalysis.urgencyCount > 2 ? 'high' : 'low',
11071
- // personalization_score: localAnalysis.personalizationScore,
11072
-
11073
- // suggested_action: emailType === 'spam' ? 'mark_as_spam' : 'keep_in_inbox',
11074
- // auto_filter_suggestion: emailType === 'spam' ? 'spam_filter' : 'no_filter',
11075
- // inbox_priority: emailType === 'spam' ? 'ignore' : 'normal',
11076
-
11077
- // key_indicators: ['Local analysis only - API failed'],
11078
- // risk_factors: [],
11079
- // legitimacy_signals: [],
11080
-
11081
- // analysis_timestamp: new Date().toISOString(),
11082
- // content_length: emailBody.length,
11083
- // analysis_complexity: 'simple',
11084
-
11085
- // // Enhanced fields
11086
- // local_analysis: localAnalysis,
11087
- // sender_analysis: analyzeSender(email, name, emailBody),
11088
- // content_stats: {
11089
- // word_count: (emailBody.match(/\S+/g) || []).length,
11090
- // sentence_count: (emailBody.match(/[.!?]+/g) || []).length,
11091
- // link_count: localAnalysis.linkCount,
11092
- // uppercase_ratio: calculateUppercaseRatio(emailBody),
11093
- // exclamation_count: (emailBody.match(/!/g) || []).length,
11094
- // dollar_sign_count: (emailBody.match(/\$/g) || []).length,
11095
- // phone_patterns: (emailBody.match(/\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g) || []).length,
11096
- // },
11097
-
11098
- // comprehensive_risk_score: calculateComprehensiveRisk({ email_type: emailType, phishing_risk: phishingRisk, is_unsolicited: true, is_urgent: localAnalysis.urgencyCount > 0 }, localAnalysis),
11099
-
11100
- // final_confidence: Math.max(50, spamConfidence),
11101
- // explanation: 'Default analysis due to API failure',
11102
- // error: error || 'API call failed',
11103
- // };
11104
- // }
11105
-
11106
- // const detection_ret = await submit_chat_gpt_prompt({
11107
- // uid,
11108
- // prompt: `Analyze this email and determine if it's SPAM, PROMOTIONAL, TRANSACTIONAL, or PERSONAL/BUSINESS communication.
11109
-
11110
- // FROM: "${name}" <${email}>
11111
- // SUBJECT: "${email_subject}"
11112
- // BODY: "${email_body.substring(0, 800)}${email_body.length > 800 ? '...' : ''}"
11113
-
11114
- // ANALYSIS CRITERIA:
11115
-
11116
- // SPAM INDICATORS:
11117
- // - Unsolicited commercial content
11118
- // - Phishing attempts or suspicious links
11119
- // - Poor grammar/spelling
11120
- // - Urgent/panic-inducing language
11121
- // - Requests for personal information
11122
- // - Too good to be true offers
11123
- // - Hidden/unclear sender identity
11124
- // - Multiple recipient addresses visible
11125
- // - Stock/"spammy" subject lines
11126
-
11127
- // PROMOTIONAL INDICATORS:
11128
- // - Marketing/sales content
11129
- // - Product announcements
11130
- // - Newsletter content
11131
- // - Discount/coupon offers
11132
- // - Event invitations (commercial)
11133
- // - Company updates (marketing focused)
11134
- // - Clear opt-out/unsubscribe option
11135
- // - Professional branding/templates
11136
- // - Call-to-action buttons
11137
-
11138
- // TRANSACTIONAL INDICATORS:
11139
- // - Order confirmations
11140
- // - Shipping notifications
11141
- // - Invoice/billing
11142
- // - Account notifications
11143
- // - Password resets
11144
- // - Booking confirmations
11145
- // - Appointment reminders
11146
- // - Payment receipts
11147
- // - Service updates
11148
-
11149
- // PERSONAL/BUSINESS INDICATORS:
11150
- // - Direct communication to you
11151
- // - Known sender relationship
11152
- // - Work/project related
11153
- // - Personal conversations
11154
- // - One-on-one correspondence
11155
- // - Contains your name specifically
11156
- // - Contextually relevant to you
11157
-
11158
- // ADDITIONAL FACTORS TO CONSIDER:
11159
- // - Sender reputation (company vs personal)
11160
- // - Your relationship with sender
11161
- // - Email formatting quality
11162
- // - Personalization level
11163
- // - Expected vs unexpected content
11164
- // - Action requested (if any)
11165
-
11166
- // PROVIDE DETAILED ANALYSIS WITH CONFIDENCE SCORES.`,
11167
- // model: 'gpt-5-nano',
11168
- // response_format: z.object({
11169
- // // Primary Classification
11170
- // email_type: z.enum(['spam', 'promotional', 'transactional', 'personal', 'business', 'ambiguous']),
11171
- // email_type_confidence: z.number().min(0).max(100),
11172
-
11173
- // // Sub-classification
11174
- // email_subtype: z.enum([
11175
- // // Spam types
11176
- // 'phishing_attempt',
11177
- // 'scam_offer',
11178
- // 'malware_risk',
11179
- // 'adult_content',
11180
- // 'financial_scam',
11181
- // 'lottery_scam',
11182
- // 'inheritance_scam',
11183
- // 'romance_scam',
11184
- // 'tech_support_scam',
11185
-
11186
- // // Promotional types
11187
- // 'marketing_newsletter',
11188
- // 'product_announcement',
11189
- // 'discount_offer',
11190
- // 'event_invitation',
11191
- // 'company_update',
11192
- // 'blog_newsletter',
11193
- // 'educational_content',
11194
- // 'lead_magnet',
11195
-
11196
- // // Transactional types
11197
- // 'order_confirmation',
11198
- // 'shipping_notification',
11199
- // 'invoice_billing',
11200
- // 'payment_receipt',
11201
- // 'account_verification',
11202
- // 'password_reset',
11203
- // 'appointment_reminder',
11204
- // 'service_notification',
11205
-
11206
- // // Personal/Business types
11207
- // 'personal_message',
11208
- // 'work_collaboration',
11209
- // 'client_communication',
11210
- // 'team_announcement',
11211
- // 'meeting_invitation',
11212
- // 'project_update',
11213
- // 'direct_inquiry',
11214
- // 'networking_request',
11215
- // ]),
11216
-
11217
- // // Risk Assessment
11218
- // spam_confidence: z.number().min(0).max(100).describe('Confidence this is spam'),
11219
- // phishing_risk: z.enum(['none', 'low', 'medium', 'high', 'critical']),
11220
- // malware_risk: z.enum(['none', 'low', 'medium', 'high']),
11221
-
11222
- // // Content Analysis
11223
- // is_unsolicited: z.boolean().describe('Email was not requested/expected'),
11224
- // is_commercial: z.boolean().describe('Contains commercial intent'),
11225
- // is_urgent: z.boolean().describe('Uses urgent/time-sensitive language'),
11226
- // is_personalized: z.boolean().describe('Content is personalized to recipient'),
11227
-
11228
- // // Sender Analysis
11229
- // sender_legitimacy: z.enum(['verified', 'likely_legitimate', 'suspicious', 'likely_fake', 'unknown']),
11230
- // sender_intent: z.enum(['inform', 'sell', 'scam', 'build_relationship', 'request_action', 'unknown']),
11231
-
11232
- // // Content Characteristics
11233
- // contains_links: z.boolean(),
11234
- // contains_attachments: z.boolean(),
11235
- // contains_unsubscribe: z.boolean(),
11236
- // contains_phone_number: z.boolean(),
11237
- // contains_address: z.boolean(),
11238
-
11239
- // // Language Analysis
11240
- // language_quality: z.enum(['excellent', 'good', 'average', 'poor', 'spammy']),
11241
- // urgency_level: z.enum(['none', 'low', 'medium', 'high', 'extreme']),
11242
- // personalization_score: z.number().min(0).max(100).describe('How personalized the content is'),
11243
-
11244
- // // Action Recommendations
11245
- // suggested_action: z.enum(['delete_immediately', 'mark_as_spam', 'move_to_promotions', 'respond_politely', 'follow_up', 'archive', 'keep_in_inbox', 'add_to_contacts', 'report_phishing']),
11246
-
11247
- // // Filter Recommendations
11248
- // auto_filter_suggestion: z.enum(['spam_filter', 'promotions_filter', 'social_filter', 'updates_filter', 'primary_inbox', 'no_filter']),
11249
-
11250
- // // Priority
11251
- // inbox_priority: z.enum(['critical', 'high', 'normal', 'low', 'ignore']),
11252
-
11253
- // // Detailed Analysis
11254
- // key_indicators: z.array(z.string()).describe('Key factors influencing classification'),
11255
- // risk_factors: z.array(z.string()).describe('Specific risks identified'),
11256
- // legitimacy_signals: z.array(z.string()).describe('Signals of legitimate communication'),
11257
-
11258
- // // Metadata
11259
- // analysis_timestamp: z.string(),
11260
- // content_length: z.number().describe('Length of email body analyzed'),
11261
- // analysis_complexity: z.enum(['simple', 'moderate', 'complex', 'ambiguous']),
11262
- // }),
11263
- // metadata: {
11264
- // func: 'detect_email_type',
11265
- // sender_name: name,
11266
- // sender_email: email,
11267
- // subject_length: email_subject?.length || 0,
11268
- // body_length: email_body?.length || 0,
11269
- // body_preview_hash: await hashString(email_body.substring(0, 200)),
11270
- // },
11271
- // account_profile_info,
11272
- // tools: [{ type: 'web_search_preview' }],
11273
- // });
11274
-
11275
- // try {
11276
- // if (detection_ret.code > -1) {
11277
- // const data = typeof detection_ret.data === 'string' ? JSON.parse(detection_ret.data) : detection_ret.data;
11278
-
11279
- // // Enhance with additional analysis
11280
- // const enhancedData = enhanceEmailDetection(data, name, email, email_body, email_subject);
11281
-
11282
- // return {
11283
- // success: true,
11284
- // ...enhancedData,
11285
- // };
11286
- // } else {
11287
- // console.error('Email detection API call failed:', detection_ret);
11288
- // return getDefaultEmailDetection(name, email, email_body, email_subject);
11289
- // }
11290
- // } catch (error) {
11291
- // console.error('Error in detect_email_type:', error);
11292
- // return getDefaultEmailDetection(name, email, email_body, email_subject, error.message);
11293
- // }
11294
- // };
11295
-
11296
8612
  export const get_business_info = async function (uid, name, email, account_profile_info, options = {}) {
11297
8613
  // ========== HELPER FUNCTIONS ==========
11298
8614