@xuda.io/account_module 1.2.1256 → 1.2.1258
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.
- package/index.mjs +825 -861
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -1601,566 +1601,165 @@ const get_user_contact = async function (uid, uid_query) {
|
|
|
1601
1601
|
return doc;
|
|
1602
1602
|
};
|
|
1603
1603
|
|
|
1604
|
-
|
|
1605
|
-
const { _id, uid, name, limit, skip, bookmark, search, filter_type = 'all', contact_id } = req;
|
|
1604
|
+
// invite user
|
|
1606
1605
|
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1606
|
+
// const contact_ret = await db_module.get_couch_view_raw(
|
|
1607
|
+
// "xuda_contacts",
|
|
1608
|
+
// "contacts_by_name_count",
|
|
1609
|
+
// {
|
|
1610
|
+
// startkey: [uid, ""],
|
|
1611
|
+
// endkey: [uid, "ZZZZZZZZZZ"],
|
|
1612
|
+
// reduce: true,
|
|
1613
|
+
// group_level: 2,
|
|
1614
|
+
// }
|
|
1615
|
+
// );
|
|
1612
1616
|
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
uid: account_profile_info.uid,
|
|
1618
|
-
stat: { $lt: 4 },
|
|
1619
|
-
},
|
|
1620
|
-
limit: limit || 9999,
|
|
1621
|
-
skip: skip || 0,
|
|
1622
|
-
sort: [{ ts: 'desc' }],
|
|
1623
|
-
};
|
|
1617
|
+
// const get_contact_id = async function (uid, contact_uid) {
|
|
1618
|
+
// contact_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_contact_uid', { key: [uid, contact_uid] });
|
|
1619
|
+
// return contact_ret?.rows?.[0]?.id;
|
|
1620
|
+
// };
|
|
1624
1621
|
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
opt.selector.stat = 5;
|
|
1628
|
-
break;
|
|
1629
|
-
}
|
|
1630
|
-
case 'shared': {
|
|
1631
|
-
opt.selector.shared_from_uid = { $gt: null };
|
|
1632
|
-
break;
|
|
1633
|
-
}
|
|
1622
|
+
export const update_contact = async function (req) {
|
|
1623
|
+
const { uid, email, contact_uid, stat, team_req_id } = req;
|
|
1634
1624
|
|
|
1635
|
-
|
|
1636
|
-
opt.selector.pinned = true;
|
|
1637
|
-
break;
|
|
1638
|
-
}
|
|
1625
|
+
const account_profile_info = await get_active_account_profile_info(uid);
|
|
1639
1626
|
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1627
|
+
var contact_ret;
|
|
1628
|
+
if (email) {
|
|
1629
|
+
contact_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_user_email_address', { key: [account_profile_info.uid, email] });
|
|
1630
|
+
} else if (contact_uid) {
|
|
1631
|
+
contact_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_contact_uid', { key: [account_profile_info.uid, contact_uid] });
|
|
1632
|
+
}
|
|
1633
|
+
if (contact_ret.rows.length) {
|
|
1634
|
+
var doc = contact_ret.rows[0].value;
|
|
1635
|
+
if (stat) {
|
|
1636
|
+
doc.stat = stat;
|
|
1637
|
+
doc.stat_ts = Date.now();
|
|
1638
|
+
}
|
|
1639
|
+
if (team_req_id) {
|
|
1640
|
+
doc.team_req_id = team_req_id;
|
|
1643
1641
|
}
|
|
1644
1642
|
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1643
|
+
if (contact_uid) {
|
|
1644
|
+
const ret = await db_module.get_couch_doc('xuda_accounts', contact_uid);
|
|
1645
|
+
const account_obj = ret.data;
|
|
1646
|
+
doc.profile_picture = account_obj.account_info.profile_picture;
|
|
1647
|
+
doc.profile_avatar = account_obj.account_info.profile_avatar;
|
|
1648
|
+
}
|
|
1649
1649
|
|
|
1650
|
-
|
|
1651
|
-
opt.selector._id = _id;
|
|
1650
|
+
return await db_module.save_couch_doc('xuda_contacts', doc);
|
|
1652
1651
|
}
|
|
1652
|
+
return { code: -1, data: 'contact not found' };
|
|
1653
|
+
};
|
|
1654
|
+
// export const invite_user = async function (req) {
|
|
1655
|
+
// const { email, name, uid } = req;
|
|
1653
1656
|
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
+
// const team_module = await import(`${module_path}/team_module/index.mjs`);
|
|
1658
|
+
// const ret = await team_module.create_team_request({
|
|
1659
|
+
// email,
|
|
1660
|
+
// access_type: 'contact',
|
|
1661
|
+
// uid,
|
|
1662
|
+
// });
|
|
1657
1663
|
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
}
|
|
1664
|
+
// // return { code: -1, data: "contact already exist active or deleted" };
|
|
1665
|
+
// };
|
|
1661
1666
|
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
},
|
|
1668
|
-
},
|
|
1669
|
-
{
|
|
1670
|
-
email: {
|
|
1671
|
-
$regex: `(?i)${search}`,
|
|
1672
|
-
},
|
|
1673
|
-
},
|
|
1674
|
-
];
|
|
1667
|
+
export const get_account_rt_info = async function (uid) {
|
|
1668
|
+
const doc_ret = await db_module.get_couch_doc('xuda_accounts', uid);
|
|
1669
|
+
if (doc_ret.code < 0) {
|
|
1670
|
+
console.error('get_account_rt_info', doc_ret);
|
|
1671
|
+
return {};
|
|
1675
1672
|
}
|
|
1673
|
+
var account_info = doc_ret.data.account_info;
|
|
1676
1674
|
|
|
1677
|
-
|
|
1678
|
-
opt.bookmark = bookmark;
|
|
1679
|
-
}
|
|
1675
|
+
delete account_info.user_id;
|
|
1680
1676
|
|
|
1681
|
-
|
|
1677
|
+
account_info.uid = doc_ret.data._id;
|
|
1678
|
+
return account_info;
|
|
1679
|
+
};
|
|
1682
1680
|
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
if (!limit || contact_id) {
|
|
1686
|
-
contacts.total_docs = contacts.docs.length;
|
|
1687
|
-
} else {
|
|
1688
|
-
delete opt.sort;
|
|
1689
|
-
delete opt.skip;
|
|
1690
|
-
opt.limit = 9999;
|
|
1691
|
-
opt.fields = ['_id'];
|
|
1681
|
+
export const validate_account_topup = async function (uid, items = []) {
|
|
1682
|
+
const stripe_module = await import(`${module_path}/stripe_module/index.mjs`);
|
|
1692
1683
|
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1684
|
+
const { code, data } = await stripe_module.get_billing_metrics({ uid });
|
|
1685
|
+
if (code < 0) {
|
|
1686
|
+
throw new Error(data);
|
|
1687
|
+
}
|
|
1688
|
+
let topup = 0;
|
|
1689
|
+
for (const item of items) {
|
|
1690
|
+
topup += get_prices(uid, item);
|
|
1696
1691
|
}
|
|
1697
1692
|
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
return e.contact_uid === doc.contact_uid;
|
|
1706
|
-
});
|
|
1707
|
-
if (ret_to) continue;
|
|
1708
|
-
|
|
1709
|
-
const ret_from = requests_from.docs.find((e) => {
|
|
1710
|
-
return e.contact_uid === doc.contact_uid;
|
|
1711
|
-
});
|
|
1712
|
-
if (ret_from) continue;
|
|
1693
|
+
if (!data?.customer_obj?.default_source) {
|
|
1694
|
+
let err = new Error('no card on file');
|
|
1695
|
+
err.code = -90;
|
|
1696
|
+
err.billing_problem = true;
|
|
1697
|
+
throw err;
|
|
1698
|
+
// throw new Error('no card on file');
|
|
1699
|
+
}
|
|
1713
1700
|
|
|
1714
|
-
|
|
1701
|
+
if (data?.balance?.past_due) {
|
|
1702
|
+
let err = new Error(`past_due ${data.balance.past_due}`);
|
|
1703
|
+
err.code = -91;
|
|
1704
|
+
err.billing_problem = true;
|
|
1705
|
+
err.topup = topup + data.balance.past_due;
|
|
1706
|
+
err.open_invoices = data?.open_invoices;
|
|
1707
|
+
throw err;
|
|
1708
|
+
}
|
|
1709
|
+
// if (data?.balance?.past_due) {
|
|
1710
|
+
// let err = new Error(`past_due ${data?.balance?.past_due}`);
|
|
1711
|
+
// err.code = -91;
|
|
1712
|
+
// err.billing_problem = true;
|
|
1713
|
+
// err.topup = topup;
|
|
1714
|
+
// throw err;
|
|
1715
|
+
// }
|
|
1715
1716
|
|
|
1716
|
-
|
|
1717
|
-
if (!doc.online) continue;
|
|
1718
|
-
}
|
|
1717
|
+
const balance = data?.balance?.account || 0; // minus balance represents positive balance
|
|
1719
1718
|
|
|
1720
|
-
|
|
1719
|
+
if (balance > 0) {
|
|
1720
|
+
let err = new Error(`negative balance ${-balance}`);
|
|
1721
|
+
err.code = -92;
|
|
1722
|
+
err.billing_problem = true;
|
|
1723
|
+
err.topup = topup - balance; // ask for whole balance
|
|
1724
|
+
throw err;
|
|
1721
1725
|
}
|
|
1722
1726
|
|
|
1723
|
-
if (
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
////// FROM - IN
|
|
1730
|
-
requests_from.docs = await get_pending_contact_in(uid);
|
|
1731
|
-
requests_from.total_docs = requests_from.docs.length;
|
|
1732
|
-
shared_from.docs = await get_pending_share_contact_in(uid);
|
|
1733
|
-
shared_from.total_docs = shared_from.docs.length;
|
|
1734
|
-
}
|
|
1727
|
+
if (topup + balance > 0) {
|
|
1728
|
+
let err = new Error(`not enough balance ${topup + balance}`);
|
|
1729
|
+
err.code = -93;
|
|
1730
|
+
err.billing_problem = true;
|
|
1731
|
+
err.topup = topup;
|
|
1732
|
+
throw err;
|
|
1735
1733
|
}
|
|
1736
1734
|
|
|
1737
|
-
return
|
|
1738
|
-
code: 1,
|
|
1739
|
-
data: {
|
|
1740
|
-
docs: [...shared_from.docs, ...requests_from.docs, ...requests_to.docs, ...contact_docs.docs],
|
|
1741
|
-
total_docs: shared_from.total_docs + requests_from.total_docs + requests_to.total_docs + contact_docs.total_docs,
|
|
1742
|
-
},
|
|
1743
|
-
};
|
|
1735
|
+
return true;
|
|
1744
1736
|
};
|
|
1745
1737
|
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
try {
|
|
1749
|
-
const team_module = await import(`${module_path}/team_module/index.mjs`);
|
|
1750
|
-
await team_module.validate_share_exist(uid, 'contact', contact_id);
|
|
1738
|
+
const get_prices = function (uid, item) {
|
|
1739
|
+
let price;
|
|
1751
1740
|
|
|
1752
|
-
|
|
1741
|
+
switch (item) {
|
|
1742
|
+
case 'user_group':
|
|
1743
|
+
case 'pwa':
|
|
1744
|
+
case 'preview':
|
|
1745
|
+
case 'android':
|
|
1746
|
+
case 'ios':
|
|
1747
|
+
case 'macos':
|
|
1748
|
+
case 'emitter':
|
|
1749
|
+
price = _conf.PRICE_OBJ.deployments[item];
|
|
1750
|
+
break;
|
|
1753
1751
|
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1752
|
+
case 'drive_ocr':
|
|
1753
|
+
price = _conf.PRICE_OBJ.drive_addons.ocr.price;
|
|
1754
|
+
break;
|
|
1757
1755
|
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1756
|
+
case 'drive_edit_image':
|
|
1757
|
+
price = _conf.PRICE_OBJ.drive_addons.edit_image.price;
|
|
1758
|
+
break;
|
|
1761
1759
|
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
} catch (err) {
|
|
1766
|
-
return {
|
|
1767
|
-
code: -22,
|
|
1768
|
-
data: err.message,
|
|
1769
|
-
};
|
|
1770
|
-
}
|
|
1771
|
-
};
|
|
1772
|
-
|
|
1773
|
-
export const delete_contact = async function (req, job_id, headers) {
|
|
1774
|
-
const { contact_id } = req;
|
|
1775
|
-
try {
|
|
1776
|
-
var contact_doc = await db_module.get_couch_doc_native('xuda_contacts', contact_id);
|
|
1777
|
-
if (contact_doc.stat !== 5) {
|
|
1778
|
-
throw new Error('A document can only be deleted after it has been archived');
|
|
1779
|
-
}
|
|
1780
|
-
contact_doc.stat = 4;
|
|
1781
|
-
contact_doc.stat_ts = Date.now();
|
|
1782
|
-
contact_doc.stat_reason = 'deleted by the user';
|
|
1783
|
-
|
|
1784
|
-
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
1785
|
-
const ai_module = await import(`${module_path}/ai_module/index.mjs`);
|
|
1786
|
-
ai_module.delete_depended_chats(uid, contact_id);
|
|
1787
|
-
return contact_save_ret;
|
|
1788
|
-
} catch (err) {
|
|
1789
|
-
return {
|
|
1790
|
-
code: -22,
|
|
1791
|
-
data: err.message,
|
|
1792
|
-
};
|
|
1793
|
-
}
|
|
1794
|
-
};
|
|
1795
|
-
|
|
1796
|
-
export const unarchive_contact = async function (req) {
|
|
1797
|
-
const { contact_id } = req;
|
|
1798
|
-
try {
|
|
1799
|
-
var contact_doc = await db_module.get_couch_doc_native('xuda_contacts', contact_id);
|
|
1800
|
-
|
|
1801
|
-
if (contact_doc.stat !== 5) {
|
|
1802
|
-
throw new Error('contact is not archived');
|
|
1803
|
-
}
|
|
1804
|
-
|
|
1805
|
-
contact_doc.stat = 3;
|
|
1806
|
-
contact_doc.stat_ts = Date.now();
|
|
1807
|
-
contact_doc.stat_reason = 'archived by the user';
|
|
1808
|
-
|
|
1809
|
-
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
1810
|
-
|
|
1811
|
-
return contact_save_ret;
|
|
1812
|
-
} catch (err) {
|
|
1813
|
-
return {
|
|
1814
|
-
code: -22,
|
|
1815
|
-
data: err.message,
|
|
1816
|
-
};
|
|
1817
|
-
}
|
|
1818
|
-
};
|
|
1819
|
-
|
|
1820
|
-
export const unfriend_contact = async function (req) {
|
|
1821
|
-
const { contact_id } = req;
|
|
1822
|
-
try {
|
|
1823
|
-
const contact_ret = await db_module.get_couch_doc('xuda_contacts', contact_id);
|
|
1824
|
-
if (contact_ret.code < 0) {
|
|
1825
|
-
throw new Error(contact_ret.data);
|
|
1826
|
-
}
|
|
1827
|
-
var contact_doc = contact_ret.data;
|
|
1828
|
-
|
|
1829
|
-
if (!contact_doc.team_req_id) {
|
|
1830
|
-
throw new Error('no friend relationship found');
|
|
1831
|
-
}
|
|
1832
|
-
let req_doc = await db_module.get_couch_doc_native('xuda_team', contact_doc.team_req_id);
|
|
1833
|
-
req_doc.team_req_stat = 4;
|
|
1834
|
-
req_doc.team_req_stat_desc = 'unfriend by the user';
|
|
1835
|
-
await db_module.get_couch_doc_native('xuda_team', contact_doc.team_req_id);
|
|
1836
|
-
|
|
1837
|
-
contact_doc.team_req_id = null;
|
|
1838
|
-
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
1839
|
-
|
|
1840
|
-
const req_save_ret = await db_module.save_couch_doc('xuda_team', req_doc);
|
|
1841
|
-
|
|
1842
|
-
return req_save_ret;
|
|
1843
|
-
} catch (err) {
|
|
1844
|
-
return {
|
|
1845
|
-
code: -21,
|
|
1846
|
-
data: err.message,
|
|
1847
|
-
};
|
|
1848
|
-
}
|
|
1849
|
-
};
|
|
1850
|
-
|
|
1851
|
-
export const pin_contact = async function (req) {
|
|
1852
|
-
const { uid, contact_id } = req;
|
|
1853
|
-
try {
|
|
1854
|
-
const contact_ret = await db_module.get_couch_doc('xuda_contacts', contact_id);
|
|
1855
|
-
if (contact_ret.code < 0) {
|
|
1856
|
-
return contact_ret;
|
|
1857
|
-
}
|
|
1858
|
-
var contact_doc = contact_ret.data;
|
|
1859
|
-
contact_doc.pinned = true;
|
|
1860
|
-
|
|
1861
|
-
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
1862
|
-
|
|
1863
|
-
global[`_account_module_ch`].sendToQueue(
|
|
1864
|
-
'ws_dashboard_module',
|
|
1865
|
-
Buffer.from(
|
|
1866
|
-
JSON.stringify({
|
|
1867
|
-
method: 'emit_message_to_dashboard',
|
|
1868
|
-
data: {
|
|
1869
|
-
service: 'contact_pinned',
|
|
1870
|
-
to: [uid],
|
|
1871
|
-
data: await get_contact_info(uid, null, contact_id),
|
|
1872
|
-
},
|
|
1873
|
-
}),
|
|
1874
|
-
),
|
|
1875
|
-
);
|
|
1876
|
-
|
|
1877
|
-
return contact_save_ret;
|
|
1878
|
-
} catch (err) {
|
|
1879
|
-
return {
|
|
1880
|
-
code: -24,
|
|
1881
|
-
data: err.message,
|
|
1882
|
-
};
|
|
1883
|
-
}
|
|
1884
|
-
};
|
|
1885
|
-
|
|
1886
|
-
export const unpin_contact = async function (req) {
|
|
1887
|
-
const { contact_id, uid } = req;
|
|
1888
|
-
try {
|
|
1889
|
-
const contact_ret = await db_module.get_couch_doc('xuda_contacts', contact_id);
|
|
1890
|
-
if (contact_ret.code < 0) {
|
|
1891
|
-
return contact_ret;
|
|
1892
|
-
}
|
|
1893
|
-
var contact_doc = contact_ret.data;
|
|
1894
|
-
contact_doc.pinned = false;
|
|
1895
|
-
|
|
1896
|
-
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
1897
|
-
|
|
1898
|
-
global[`_account_module_ch`].sendToQueue(
|
|
1899
|
-
'ws_dashboard_module',
|
|
1900
|
-
Buffer.from(
|
|
1901
|
-
JSON.stringify({
|
|
1902
|
-
method: 'emit_message_to_dashboard',
|
|
1903
|
-
data: {
|
|
1904
|
-
service: 'contact_unpinned',
|
|
1905
|
-
to: [uid],
|
|
1906
|
-
data: await get_contact_info(uid, null, contact_id),
|
|
1907
|
-
},
|
|
1908
|
-
}),
|
|
1909
|
-
),
|
|
1910
|
-
);
|
|
1911
|
-
|
|
1912
|
-
return contact_save_ret;
|
|
1913
|
-
} catch (err) {
|
|
1914
|
-
return {
|
|
1915
|
-
code: -24,
|
|
1916
|
-
data: err.message,
|
|
1917
|
-
};
|
|
1918
|
-
}
|
|
1919
|
-
};
|
|
1920
|
-
|
|
1921
|
-
// invite user
|
|
1922
|
-
|
|
1923
|
-
// const contact_ret = await db_module.get_couch_view_raw(
|
|
1924
|
-
// "xuda_contacts",
|
|
1925
|
-
// "contacts_by_name_count",
|
|
1926
|
-
// {
|
|
1927
|
-
// startkey: [uid, ""],
|
|
1928
|
-
// endkey: [uid, "ZZZZZZZZZZ"],
|
|
1929
|
-
// reduce: true,
|
|
1930
|
-
// group_level: 2,
|
|
1931
|
-
// }
|
|
1932
|
-
// );
|
|
1933
|
-
|
|
1934
|
-
export const add_contact = async function (req, job_id, headers) {
|
|
1935
|
-
try {
|
|
1936
|
-
const { uid, email, name, stat, contact_uid, context, source, team_req_id, metadata = {} } = req;
|
|
1937
|
-
const account_profile_info = await get_active_account_profile_info(uid);
|
|
1938
|
-
|
|
1939
|
-
const contact_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_user_email_address', { key: [account_profile_info.uid, email] });
|
|
1940
|
-
|
|
1941
|
-
if (contact_ret.rows.length) {
|
|
1942
|
-
throw new Error('contact already exist active or deleted');
|
|
1943
|
-
}
|
|
1944
|
-
|
|
1945
|
-
let is_spam = false;
|
|
1946
|
-
let profile_avatar, profile_avatar_obj;
|
|
1947
|
-
let account_info_ret;
|
|
1948
|
-
if (contact_uid) {
|
|
1949
|
-
account_info_ret = await get_account_name({ uid_query: contact_uid });
|
|
1950
|
-
if (account_info_ret.code < 0) {
|
|
1951
|
-
throw new Error(`account ${contact_uid} not found`);
|
|
1952
|
-
}
|
|
1953
|
-
} else {
|
|
1954
|
-
// contact without use account
|
|
1955
|
-
if (metadata.subject && !metadata.is_sent) {
|
|
1956
|
-
is_spam_ret = await ai_module.is_spam_email(uid, email, metadata.subject);
|
|
1957
|
-
try {
|
|
1958
|
-
if (is_spam_ret.code > -1) {
|
|
1959
|
-
const data = JSON.parse(is_spam_ret.data);
|
|
1960
|
-
is_spam = data.is_spam;
|
|
1961
|
-
}
|
|
1962
|
-
} catch (error) {}
|
|
1963
|
-
}
|
|
1964
|
-
|
|
1965
|
-
const existing_contacts_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_email_address', { key: email });
|
|
1966
|
-
for (const contact of existing_contacts_ret.rows) {
|
|
1967
|
-
if (contact.value.profile_avatar) {
|
|
1968
|
-
profile_avatar = contact.value.profile_avatar;
|
|
1969
|
-
profile_avatar_obj == contact.value.profile_avatar_obj;
|
|
1970
|
-
}
|
|
1971
|
-
}
|
|
1972
|
-
}
|
|
1973
|
-
const d = Date.now();
|
|
1974
|
-
const doc = {
|
|
1975
|
-
_id: await _common.xuda_get_uuid('contact'),
|
|
1976
|
-
email: [email],
|
|
1977
|
-
name,
|
|
1978
|
-
stat: stat || 1,
|
|
1979
|
-
date_created: d,
|
|
1980
|
-
ts: d,
|
|
1981
|
-
docType: 'contact',
|
|
1982
|
-
contact_uid,
|
|
1983
|
-
uid: account_profile_info.uid,
|
|
1984
|
-
uid_created: uid,
|
|
1985
|
-
context,
|
|
1986
|
-
headers,
|
|
1987
|
-
source,
|
|
1988
|
-
team_req_id,
|
|
1989
|
-
metadata,
|
|
1990
|
-
is_spam,
|
|
1991
|
-
profile_avatar,
|
|
1992
|
-
profile_avatar_obj,
|
|
1993
|
-
account_profile_info,
|
|
1994
|
-
};
|
|
1995
|
-
const ret = await db_module.save_couch_doc('xuda_contacts', doc);
|
|
1996
|
-
|
|
1997
|
-
if (!account_info_ret?.data?.profile_avatar) {
|
|
1998
|
-
const app_id = await get_account_default_project_id(uid);
|
|
1999
|
-
const ai_module = await import(`${module_path}/ai_module/index.mjs`);
|
|
2000
|
-
if (account_info_ret?.data?.profile_avatar) {
|
|
2001
|
-
// account_info_ret.data.profile_avatar_stat = 2;
|
|
2002
|
-
ai_module.create_profile_avatar({ url: account_info_ret.data.profile_picture, uid, account_obj: { _id: contact_uid, account_info: account_info_ret.data }, account_profile_info }, job_id, headers);
|
|
2003
|
-
} else {
|
|
2004
|
-
if (!doc.profile_avatar) {
|
|
2005
|
-
// create factual avatar
|
|
2006
|
-
if (!is_spam) {
|
|
2007
|
-
ai_module.update_thumbnail('contact', doc, account_profile_info.app_id, uid, job_id, headers, 'xuda_contacts', [email, doc._id, 'contact', account_profile_info.app_id], account_profile_info);
|
|
2008
|
-
}
|
|
2009
|
-
}
|
|
2010
|
-
}
|
|
2011
|
-
}
|
|
2012
|
-
return ret;
|
|
2013
|
-
} catch (err) {
|
|
2014
|
-
return { code: -1, data: err.message };
|
|
2015
|
-
}
|
|
2016
|
-
};
|
|
2017
|
-
|
|
2018
|
-
// const get_contact_id = async function (uid, contact_uid) {
|
|
2019
|
-
// contact_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_contact_uid', { key: [uid, contact_uid] });
|
|
2020
|
-
// return contact_ret?.rows?.[0]?.id;
|
|
2021
|
-
// };
|
|
2022
|
-
|
|
2023
|
-
export const update_contact = async function (req) {
|
|
2024
|
-
const { uid, email, contact_uid, stat, team_req_id } = req;
|
|
2025
|
-
|
|
2026
|
-
const account_profile_info = await get_active_account_profile_info(uid);
|
|
2027
|
-
|
|
2028
|
-
var contact_ret;
|
|
2029
|
-
if (email) {
|
|
2030
|
-
contact_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_user_email_address', { key: [account_profile_info.uid, email] });
|
|
2031
|
-
} else if (contact_uid) {
|
|
2032
|
-
contact_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_contact_uid', { key: [account_profile_info.uid, contact_uid] });
|
|
2033
|
-
}
|
|
2034
|
-
if (contact_ret.rows.length) {
|
|
2035
|
-
var doc = contact_ret.rows[0].value;
|
|
2036
|
-
if (stat) {
|
|
2037
|
-
doc.stat = stat;
|
|
2038
|
-
doc.stat_ts = Date.now();
|
|
2039
|
-
}
|
|
2040
|
-
if (team_req_id) {
|
|
2041
|
-
doc.team_req_id = team_req_id;
|
|
2042
|
-
}
|
|
2043
|
-
|
|
2044
|
-
if (contact_uid) {
|
|
2045
|
-
const ret = await db_module.get_couch_doc('xuda_accounts', contact_uid);
|
|
2046
|
-
const account_obj = ret.data;
|
|
2047
|
-
doc.profile_picture = account_obj.account_info.profile_picture;
|
|
2048
|
-
doc.profile_avatar = account_obj.account_info.profile_avatar;
|
|
2049
|
-
}
|
|
2050
|
-
|
|
2051
|
-
return await db_module.save_couch_doc('xuda_contacts', doc);
|
|
2052
|
-
}
|
|
2053
|
-
return { code: -1, data: 'contact not found' };
|
|
2054
|
-
};
|
|
2055
|
-
// export const invite_user = async function (req) {
|
|
2056
|
-
// const { email, name, uid } = req;
|
|
2057
|
-
|
|
2058
|
-
// const team_module = await import(`${module_path}/team_module/index.mjs`);
|
|
2059
|
-
// const ret = await team_module.create_team_request({
|
|
2060
|
-
// email,
|
|
2061
|
-
// access_type: 'contact',
|
|
2062
|
-
// uid,
|
|
2063
|
-
// });
|
|
2064
|
-
|
|
2065
|
-
// // return { code: -1, data: "contact already exist active or deleted" };
|
|
2066
|
-
// };
|
|
2067
|
-
|
|
2068
|
-
export const get_account_rt_info = async function (uid) {
|
|
2069
|
-
const doc_ret = await db_module.get_couch_doc('xuda_accounts', uid);
|
|
2070
|
-
if (doc_ret.code < 0) {
|
|
2071
|
-
console.error('get_account_rt_info', doc_ret);
|
|
2072
|
-
return {};
|
|
2073
|
-
}
|
|
2074
|
-
var account_info = doc_ret.data.account_info;
|
|
2075
|
-
|
|
2076
|
-
delete account_info.user_id;
|
|
2077
|
-
|
|
2078
|
-
account_info.uid = doc_ret.data._id;
|
|
2079
|
-
return account_info;
|
|
2080
|
-
};
|
|
2081
|
-
|
|
2082
|
-
export const validate_account_topup = async function (uid, items = []) {
|
|
2083
|
-
const stripe_module = await import(`${module_path}/stripe_module/index.mjs`);
|
|
2084
|
-
|
|
2085
|
-
const { code, data } = await stripe_module.get_billing_metrics({ uid });
|
|
2086
|
-
if (code < 0) {
|
|
2087
|
-
throw new Error(data);
|
|
2088
|
-
}
|
|
2089
|
-
let topup = 0;
|
|
2090
|
-
for (const item of items) {
|
|
2091
|
-
topup += get_prices(uid, item);
|
|
2092
|
-
}
|
|
2093
|
-
|
|
2094
|
-
if (!data?.customer_obj?.default_source) {
|
|
2095
|
-
let err = new Error('no card on file');
|
|
2096
|
-
err.code = -90;
|
|
2097
|
-
err.billing_problem = true;
|
|
2098
|
-
throw err;
|
|
2099
|
-
// throw new Error('no card on file');
|
|
2100
|
-
}
|
|
2101
|
-
|
|
2102
|
-
if (data?.balance?.past_due) {
|
|
2103
|
-
let err = new Error(`past_due ${data.balance.past_due}`);
|
|
2104
|
-
err.code = -91;
|
|
2105
|
-
err.billing_problem = true;
|
|
2106
|
-
err.topup = topup + data.balance.past_due;
|
|
2107
|
-
err.open_invoices = data?.open_invoices;
|
|
2108
|
-
throw err;
|
|
2109
|
-
}
|
|
2110
|
-
// if (data?.balance?.past_due) {
|
|
2111
|
-
// let err = new Error(`past_due ${data?.balance?.past_due}`);
|
|
2112
|
-
// err.code = -91;
|
|
2113
|
-
// err.billing_problem = true;
|
|
2114
|
-
// err.topup = topup;
|
|
2115
|
-
// throw err;
|
|
2116
|
-
// }
|
|
2117
|
-
|
|
2118
|
-
const balance = data?.balance?.account || 0; // minus balance represents positive balance
|
|
2119
|
-
|
|
2120
|
-
if (balance > 0) {
|
|
2121
|
-
let err = new Error(`negative balance ${-balance}`);
|
|
2122
|
-
err.code = -92;
|
|
2123
|
-
err.billing_problem = true;
|
|
2124
|
-
err.topup = topup - balance; // ask for whole balance
|
|
2125
|
-
throw err;
|
|
2126
|
-
}
|
|
2127
|
-
|
|
2128
|
-
if (topup + balance > 0) {
|
|
2129
|
-
let err = new Error(`not enough balance ${topup + balance}`);
|
|
2130
|
-
err.code = -93;
|
|
2131
|
-
err.billing_problem = true;
|
|
2132
|
-
err.topup = topup;
|
|
2133
|
-
throw err;
|
|
2134
|
-
}
|
|
2135
|
-
|
|
2136
|
-
return true;
|
|
2137
|
-
};
|
|
2138
|
-
|
|
2139
|
-
const get_prices = function (uid, item) {
|
|
2140
|
-
let price;
|
|
2141
|
-
|
|
2142
|
-
switch (item) {
|
|
2143
|
-
case 'user_group':
|
|
2144
|
-
case 'pwa':
|
|
2145
|
-
case 'preview':
|
|
2146
|
-
case 'android':
|
|
2147
|
-
case 'ios':
|
|
2148
|
-
case 'macos':
|
|
2149
|
-
case 'emitter':
|
|
2150
|
-
price = _conf.PRICE_OBJ.deployments[item];
|
|
2151
|
-
break;
|
|
2152
|
-
|
|
2153
|
-
case 'drive_ocr':
|
|
2154
|
-
price = _conf.PRICE_OBJ.drive_addons.ocr.price;
|
|
2155
|
-
break;
|
|
2156
|
-
|
|
2157
|
-
case 'drive_edit_image':
|
|
2158
|
-
price = _conf.PRICE_OBJ.drive_addons.edit_image.price;
|
|
2159
|
-
break;
|
|
2160
|
-
|
|
2161
|
-
case 'auto_backup':
|
|
2162
|
-
price = _conf.PRICE_OBJ.auto_backup_per_month;
|
|
2163
|
-
break;
|
|
1760
|
+
case 'auto_backup':
|
|
1761
|
+
price = _conf.PRICE_OBJ.auto_backup_per_month;
|
|
1762
|
+
break;
|
|
2164
1763
|
|
|
2165
1764
|
case 'deployment_offline':
|
|
2166
1765
|
price = _conf.PRICE_OBJ.deployment_offline_per_month;
|
|
@@ -2216,395 +1815,730 @@ export const create_account_oauth_link = async function (req, job_id) {
|
|
|
2216
1815
|
};
|
|
2217
1816
|
};
|
|
2218
1817
|
|
|
2219
|
-
export const get_default_project_account_doc = async function (uid) {
|
|
2220
|
-
const ret = await db_module.get_couch_doc('xuda_accounts', uid);
|
|
2221
|
-
return ret.data;
|
|
2222
|
-
};
|
|
2223
|
-
export const get_account_default_project_id = async function (uid) {
|
|
2224
|
-
const account_obj = await get_default_project_account_doc(uid);
|
|
2225
|
-
return account_obj.account_project_id;
|
|
1818
|
+
export const get_default_project_account_doc = async function (uid) {
|
|
1819
|
+
const ret = await db_module.get_couch_doc('xuda_accounts', uid);
|
|
1820
|
+
return ret.data;
|
|
1821
|
+
};
|
|
1822
|
+
export const get_account_default_project_id = async function (uid) {
|
|
1823
|
+
const account_obj = await get_default_project_account_doc(uid);
|
|
1824
|
+
return account_obj.account_project_id;
|
|
1825
|
+
};
|
|
1826
|
+
|
|
1827
|
+
setTimeout(async () => {
|
|
1828
|
+
// const uid = "0489f946c213947316647b468f029ed9"; //"aecc740881fd0a35098c738652000fab";
|
|
1829
|
+
|
|
1830
|
+
// // // clear data
|
|
1831
|
+
// // const contact_ret = await db_module.find_couch_query("xuda_contacts", {
|
|
1832
|
+
// // selector: {
|
|
1833
|
+
// // docType: "contact",
|
|
1834
|
+
// // },
|
|
1835
|
+
// // limit: 99999,
|
|
1836
|
+
// // });
|
|
1837
|
+
// // var contact_docs = [];
|
|
1838
|
+
// // for (let val of contact_ret.docs) {
|
|
1839
|
+
// // val._deleted = true;
|
|
1840
|
+
// // contact_docs.push(val);
|
|
1841
|
+
// // }
|
|
1842
|
+
// // await db_module.save_couch_bulk_docs("xuda_contacts", contact_docs);
|
|
1843
|
+
|
|
1844
|
+
// // const emails_ret = await db_module.find_couch_query("xuda_emails", {
|
|
1845
|
+
// // selector: {
|
|
1846
|
+
// // docType: "email",
|
|
1847
|
+
// // },
|
|
1848
|
+
// // limit: 99999,
|
|
1849
|
+
// // });
|
|
1850
|
+
// // var email_docs = [];
|
|
1851
|
+
// // for (let val of emails_ret.docs) {
|
|
1852
|
+
// // val._deleted = true;
|
|
1853
|
+
// // email_docs.push(val);
|
|
1854
|
+
// // }
|
|
1855
|
+
|
|
1856
|
+
// // await db_module.save_couch_bulk_docs("xuda_emails", email_docs);
|
|
1857
|
+
|
|
1858
|
+
// ///////////////////////////////////
|
|
1859
|
+
// return;
|
|
1860
|
+
// const email_account_ret = await get_email_accounts({
|
|
1861
|
+
// uid,
|
|
1862
|
+
// });
|
|
1863
|
+
|
|
1864
|
+
// var accessToken;
|
|
1865
|
+
// for await (let email_account of email_account_ret.data.docs) {
|
|
1866
|
+
// switch (email_account.vendor) {
|
|
1867
|
+
// case "gmail":
|
|
1868
|
+
// const ret = await generate_gmail_access_token(email_account);
|
|
1869
|
+
// accessToken = ret.access_token;
|
|
1870
|
+
// break;
|
|
1871
|
+
|
|
1872
|
+
// default:
|
|
1873
|
+
// break;
|
|
1874
|
+
// }
|
|
1875
|
+
|
|
1876
|
+
// read_emails({
|
|
1877
|
+
// uid,
|
|
1878
|
+
// email_account_address: email_account.email,
|
|
1879
|
+
// accessToken,
|
|
1880
|
+
// email_account_id: email_account._id,
|
|
1881
|
+
// vendor: email_account.vendor,
|
|
1882
|
+
// });
|
|
1883
|
+
// }
|
|
1884
|
+
|
|
1885
|
+
// // console.log(await get_contact({ uid, name: "bo" }));
|
|
1886
|
+
|
|
1887
|
+
let ret;
|
|
1888
|
+
// ret = await add_contact({ uid: 'd39126e0e2c51ffbd1aad10709fc8335', name: 'Boaz Avrahami', email: 'bocabo67@gmail.com', context: {} }, null, { 'accept-language': 'en-US,en;q=0.9,he;q=0.8' });
|
|
1889
|
+
console.log(ret);
|
|
1890
|
+
}, 2000);
|
|
1891
|
+
|
|
1892
|
+
export const get_user_name = async function (uid) {
|
|
1893
|
+
try {
|
|
1894
|
+
const account_info = await get_account_name({ uid });
|
|
1895
|
+
let username = 'unknown';
|
|
1896
|
+
if (account_info) {
|
|
1897
|
+
username = account_info.first_name + ' ' + account_info.last_name;
|
|
1898
|
+
|
|
1899
|
+
if (!username) {
|
|
1900
|
+
username = +account_info.email;
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
return username;
|
|
1905
|
+
} catch (err) {
|
|
1906
|
+
return 'unknown';
|
|
1907
|
+
}
|
|
1908
|
+
};
|
|
1909
|
+
|
|
1910
|
+
// TBD
|
|
1911
|
+
export const update_contacts_with_account_changes = async function (uid, changes = []) {
|
|
1912
|
+
try {
|
|
1913
|
+
if (!changes.length) return;
|
|
1914
|
+
const ret = await db_module.get_couch_doc('xuda_accounts', uid);
|
|
1915
|
+
var account_obj = ret.data;
|
|
1916
|
+
account_obj.ts = Date.now();
|
|
1917
|
+
|
|
1918
|
+
// update all uid contacts with the new avatar
|
|
1919
|
+
const opt = {
|
|
1920
|
+
selector: { contact_uid: uid, docType: 'contact' },
|
|
1921
|
+
};
|
|
1922
|
+
debugger;
|
|
1923
|
+
let changes_made;
|
|
1924
|
+
var contacts = await db_module.find_couch_query('xuda_contacts', opt);
|
|
1925
|
+
for (let doc of contacts.docs) {
|
|
1926
|
+
if (changes.includes('profile_picture')) {
|
|
1927
|
+
changes_made = true;
|
|
1928
|
+
doc.profile_picture = account_obj.account_info.profile_picture;
|
|
1929
|
+
}
|
|
1930
|
+
if (changes.includes('profile_avatar')) {
|
|
1931
|
+
changes_made = true;
|
|
1932
|
+
doc.profile_avatar = account_obj.account_info.profile_avatar;
|
|
1933
|
+
}
|
|
1934
|
+
if (changes.includes('email')) {
|
|
1935
|
+
changes_made = true;
|
|
1936
|
+
doc.email = account_obj.account_info.email;
|
|
1937
|
+
}
|
|
1938
|
+
if (changes.includes('first_name') || changes.includes('last_name')) {
|
|
1939
|
+
changes_made = true;
|
|
1940
|
+
doc.name = `${account_obj.account_info.first_name} ${account_obj.account_info.last_name}`;
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
console.log(doc);
|
|
1944
|
+
}
|
|
1945
|
+
if (contacts.docs && changes_made) {
|
|
1946
|
+
await db_module.save_couch_bulk_docs('xuda_contacts', contacts.docs);
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
return username;
|
|
1950
|
+
} catch (err) {
|
|
1951
|
+
return 'unknown';
|
|
1952
|
+
}
|
|
1953
|
+
};
|
|
1954
|
+
|
|
1955
|
+
export const get_user_card = async function (uid, uid_query) {
|
|
1956
|
+
if (uid === uid_query) return await get_user_contact(uid, uid_query);
|
|
1957
|
+
|
|
1958
|
+
let user_contact_obj; // = { border, card_background, contact_uid, date_created, docType, icon_pattern, name, business_name, profile_avatar, connection_stat, username, bio, notifications, email, phone_number };
|
|
1959
|
+
|
|
1960
|
+
const contact_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_contact_uid', { key: [uid, uid_query] });
|
|
1961
|
+
|
|
1962
|
+
const contact_id = contact_ret?.rows?.[0]?.id;
|
|
1963
|
+
if (contact_id) {
|
|
1964
|
+
user_contact_obj = await get_contact_info(uid, null, contact_id);
|
|
1965
|
+
} else {
|
|
1966
|
+
user_contact_obj = await get_user_contact(uid, uid_query);
|
|
1967
|
+
}
|
|
1968
|
+
return user_contact_obj;
|
|
1969
|
+
};
|
|
1970
|
+
|
|
1971
|
+
// export const generate_user_avatar = async function (req, job_id, headers) {
|
|
1972
|
+
// const { uid, account_info } = req;
|
|
1973
|
+
// try {
|
|
1974
|
+
// const ai_module = await import(`${module_path}/ai_module/index.mjs`);
|
|
1975
|
+
|
|
1976
|
+
// ai_module.create_profile_avatar({ url: account_info?.profile_picture, uid, account_obj }, job_id, headers);
|
|
1977
|
+
|
|
1978
|
+
// // const account_info = await get_account_name({ uid });
|
|
1979
|
+
// // let username = 'unknown';
|
|
1980
|
+
// // if (account_info) {
|
|
1981
|
+
// // username = account_info.first_name + ' ' + account_info.last_name;
|
|
1982
|
+
|
|
1983
|
+
// // if (!username) {
|
|
1984
|
+
// // username = +account_info.email;
|
|
1985
|
+
// // }
|
|
1986
|
+
// // }
|
|
1987
|
+
|
|
1988
|
+
// // return username;
|
|
1989
|
+
// } catch (err) {
|
|
1990
|
+
// return 'unknown';
|
|
1991
|
+
// }
|
|
1992
|
+
// };
|
|
1993
|
+
|
|
1994
|
+
export const onboarding_completed = async function (req, job_id, headers) {
|
|
1995
|
+
const { uid } = req;
|
|
1996
|
+
try {
|
|
1997
|
+
await update_account_info(req, job_id, headers);
|
|
1998
|
+
|
|
1999
|
+
let account_doc = await db_module.get_couch_doc_native('xuda_accounts', uid);
|
|
2000
|
+
|
|
2001
|
+
if (!account_doc.account_info?.profile_picture) {
|
|
2002
|
+
throw new Error(`missing profile_picture`);
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
if (!account_doc.account_info?.profile_avatar) {
|
|
2006
|
+
throw new Error(`missing profile_avatar`);
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
if (!account_doc.account_project_id) {
|
|
2010
|
+
const app_module = await import(`${module_path}/app_module/index.mjs`);
|
|
2011
|
+
|
|
2012
|
+
const ret = await app_module.create_project({ token_ret: req.token_ret, uid, data: { app_name: `Account ${uid} main project`, is_account_project: true, app_plugins_purchased: [' @xuda.io/xuda-dbs-plugin-xuda', '@xuda.io/xuda-framework-plugin-tailwind'] } }, job_id, headers);
|
|
2013
|
+
if (ret.code > -1) {
|
|
2014
|
+
account_doc.account_project_id = ret.data;
|
|
2015
|
+
const drive_module = await import(`${module_path}/drive_module/index.mjs`);
|
|
2016
|
+
let drive_req = { app_id: account_doc.account_project_id, uid, path: '/' };
|
|
2017
|
+
await drive_module.create_drive_folder_user({ ...drive_req, ...{ folder_name: 'Profile Images', is_system: true } }, job_id, headers);
|
|
2018
|
+
await drive_module.create_drive_folder_user({ ...drive_req, ...{ folder_name: 'Chat Thumbnails', is_system: true } }, job_id, headers);
|
|
2019
|
+
await drive_module.create_drive_folder_user({ ...drive_req, ...{ folder_name: 'Chat Attachments', is_system: true } }, job_id, headers);
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
account_doc.account_info.full_name = `${account_doc.account_info.first_name} ${account_doc.account_info.last_name}`;
|
|
2024
|
+
|
|
2025
|
+
if (!account_doc.ai_workspace_plan) {
|
|
2026
|
+
account_doc.ai_workspace_plan = 'free_ai_workspace';
|
|
2027
|
+
}
|
|
2028
|
+
if (!account_doc.account_profile_id) {
|
|
2029
|
+
const account_profile_ret = await create_account_profile({ uid, profile_name: account_doc.account_info.full_name, main: true });
|
|
2030
|
+
account_doc.account_profile_id = account_profile_ret.data.id;
|
|
2031
|
+
account_doc.account_info.active_account_profile_id = account_doc.account_profile_id;
|
|
2032
|
+
}
|
|
2033
|
+
account_doc.boarded_info = { headers, date_ts: Date.now() };
|
|
2034
|
+
account_doc.isBoarded = true;
|
|
2035
|
+
const save_ret = await db_module.save_couch_doc('xuda_accounts', account_doc);
|
|
2036
|
+
|
|
2037
|
+
/// create view
|
|
2038
|
+
|
|
2039
|
+
let _design = await db_module.get_app_couch_doc_native(account_doc.account_project_id, '_design/xuda');
|
|
2040
|
+
if (!_design.views.ai_chat_usage) {
|
|
2041
|
+
_design.views['ai_chat_usage'] = {
|
|
2042
|
+
map: "function formatTimestampToDDMMYYYY(timestampMs) {\n const date = new Date(timestampMs); // directly use milliseconds\n\n const day = Number(String(date.getDate()).padStart(2, '0'));\n const month =Number( String(date.getMonth() + 1).padStart(2, '0')); // months are 0-based\n const year = date.getFullYear();\n\n // return `${day}/${month}/${year}`;\n return {day,month,year}\n}\n\nfunction (doc) {\n \n if(doc.docType===\"chat_usage\"){\n if(doc.cost && doc.account_profile_info){\n const cost_input=(doc.cost.input/1000000)*doc.input_tokens*100 ;\n const cost_output=(doc.cost.output/1000000)*doc.output_tokens*100 \n \n const d=formatTimestampToDDMMYYYY(doc.date_created_ts)\n emit([d.year,d.month,d.day,doc.account_profile_info.account_profile_id,doc.account_profile_info.account_profile_obj.uid,doc.model], [doc.input_tokens,doc.output_tokens ,cost_input,cost_output]);\n // emit([d.year,d.month,d.day,doc.model], [doc.input_tokens,doc.output_tokens]);\n}\n }\n }",
|
|
2043
|
+
reduce: '_sum',
|
|
2044
|
+
};
|
|
2045
|
+
}
|
|
2046
|
+
await db_module.save_app_couch_doc_native(account_doc.account_project_id, _design);
|
|
2047
|
+
///////
|
|
2048
|
+
|
|
2049
|
+
return save_ret;
|
|
2050
|
+
} catch (err) {
|
|
2051
|
+
return { code: -44, data: err.message };
|
|
2052
|
+
}
|
|
2053
|
+
};
|
|
2054
|
+
|
|
2055
|
+
export const ts_contact = async function (contact_id) {
|
|
2056
|
+
try {
|
|
2057
|
+
const contact_doc = await db_module.get_couch_doc_native('xuda_contacts', contact_id);
|
|
2058
|
+
contact_doc.ts = Date.now();
|
|
2059
|
+
const save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
2060
|
+
return save_ret;
|
|
2061
|
+
} catch (err) {
|
|
2062
|
+
console.error(err);
|
|
2063
|
+
}
|
|
2226
2064
|
};
|
|
2227
2065
|
|
|
2228
|
-
|
|
2229
|
-
|
|
2066
|
+
export const get_account_ai_usage = async function (req, job_id, headers) {
|
|
2067
|
+
const { uid, year, month, day, usage_scope = 'account' } = req;
|
|
2068
|
+
try {
|
|
2069
|
+
const app_id = await get_account_default_project_id(uid);
|
|
2070
|
+
const { data: acc_obj } = await db_module.get_couch_doc('xuda_accounts', uid);
|
|
2230
2071
|
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
// // docType: "contact",
|
|
2235
|
-
// // },
|
|
2236
|
-
// // limit: 99999,
|
|
2237
|
-
// // });
|
|
2238
|
-
// // var contact_docs = [];
|
|
2239
|
-
// // for (let val of contact_ret.docs) {
|
|
2240
|
-
// // val._deleted = true;
|
|
2241
|
-
// // contact_docs.push(val);
|
|
2242
|
-
// // }
|
|
2243
|
-
// // await db_module.save_couch_bulk_docs("xuda_contacts", contact_docs);
|
|
2072
|
+
const d = new Date();
|
|
2073
|
+
const curr_month = Number(String(d.getMonth() + 1).padStart(2, '0')); // months are 0-based
|
|
2074
|
+
const curr_year = d.getFullYear();
|
|
2244
2075
|
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
// // for (let val of emails_ret.docs) {
|
|
2253
|
-
// // val._deleted = true;
|
|
2254
|
-
// // email_docs.push(val);
|
|
2255
|
-
// // }
|
|
2076
|
+
const ai_usage = await db_module.get_app_couch_view(app_id, 'ai_chat_usage', {
|
|
2077
|
+
startkey: [year || curr_year, month || curr_month, day || 0],
|
|
2078
|
+
endkey: [year || curr_year, month || curr_month, day || 99],
|
|
2079
|
+
reduce: true,
|
|
2080
|
+
group_level: 999,
|
|
2081
|
+
});
|
|
2082
|
+
// console.log('ai_usage', ai_usage.rows);
|
|
2256
2083
|
|
|
2257
|
-
|
|
2084
|
+
let total_usage = 0;
|
|
2085
|
+
let profile = {};
|
|
2258
2086
|
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2087
|
+
for (const row of ai_usage.rows) {
|
|
2088
|
+
const year = row.key[0];
|
|
2089
|
+
const month = row.key[1];
|
|
2090
|
+
const day = row.key[2];
|
|
2091
|
+
const account_profile_id = row.key[3];
|
|
2092
|
+
const uid = row.key[4];
|
|
2093
|
+
const model = row.key[5];
|
|
2094
|
+
const input_tokens = row.value[0];
|
|
2095
|
+
const output_tokens = row.value[1];
|
|
2096
|
+
const input_credits = row.value[2];
|
|
2097
|
+
const output_credits = row.value[3];
|
|
2098
|
+
if (!profile[account_profile_id]) {
|
|
2099
|
+
profile[account_profile_id] = {};
|
|
2100
|
+
}
|
|
2101
|
+
if (!profile[account_profile_id][uid]) {
|
|
2102
|
+
profile[account_profile_id][uid] = 0;
|
|
2103
|
+
}
|
|
2264
2104
|
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
// case "gmail":
|
|
2269
|
-
// const ret = await generate_gmail_access_token(email_account);
|
|
2270
|
-
// accessToken = ret.access_token;
|
|
2271
|
-
// break;
|
|
2105
|
+
profile[account_profile_id][uid] += input_credits + output_credits;
|
|
2106
|
+
total_usage += input_credits + output_credits;
|
|
2107
|
+
}
|
|
2272
2108
|
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2109
|
+
let membership_plan = _conf.PLAN_OBJ?.[acc_obj?.ai_workspace_plan]?.features?.ai_credits || 0;
|
|
2110
|
+
let ai_workspace_plan = _conf.PLAN_OBJ?.[acc_obj?.membership_plan]?.features?.ai_credits || 0;
|
|
2111
|
+
let contact_connection = 0;
|
|
2112
|
+
let total_credits = membership_plan + ai_workspace_plan + contact_connection;
|
|
2276
2113
|
|
|
2277
|
-
|
|
2278
|
-
// uid,
|
|
2279
|
-
// email_account_address: email_account.email,
|
|
2280
|
-
// accessToken,
|
|
2281
|
-
// email_account_id: email_account._id,
|
|
2282
|
-
// vendor: email_account.vendor,
|
|
2283
|
-
// });
|
|
2284
|
-
// }
|
|
2114
|
+
let data = { credits: { membership_plan, ai_workspace_plan, contact_connection, total: total_credits }, usage: { profile, projects: [], total: total_usage } };
|
|
2285
2115
|
|
|
2286
|
-
|
|
2116
|
+
return { code: 55, data };
|
|
2117
|
+
} catch (err) {
|
|
2118
|
+
return { code: -55, data: err.message };
|
|
2119
|
+
}
|
|
2120
|
+
};
|
|
2121
|
+
|
|
2122
|
+
setTimeout(async () => {
|
|
2123
|
+
const app_id = 'prj712ffdf5aa8adce6cedef988f9c12392'; //'prj3937cb6f9a31c8c7dea25055bba845b1'; //
|
|
2124
|
+
const uid = 'd39126e0e2c51ffbd1aad10709fc8335';
|
|
2287
2125
|
|
|
2288
2126
|
let ret;
|
|
2289
|
-
|
|
2127
|
+
|
|
2128
|
+
// ret = await get_account_ai_usage({ uid });
|
|
2129
|
+
// ret = await create_account_profile({ uid });
|
|
2130
|
+
// ret = await get_account_profiles({ uid });
|
|
2131
|
+
|
|
2132
|
+
// let _design = await db_module.get_app_couch_doc_native(app_id, '_design/xuda');
|
|
2133
|
+
// ret = _design.views.ai_chat_usage;
|
|
2134
|
+
// console.log(_design.views.ai_chat_usage);
|
|
2290
2135
|
console.log(ret);
|
|
2291
|
-
},
|
|
2136
|
+
}, 1000);
|
|
2292
2137
|
|
|
2293
|
-
|
|
2138
|
+
//////// CONTACTS //////////////
|
|
2139
|
+
|
|
2140
|
+
export const add_contact = async function (req, job_id, headers) {
|
|
2294
2141
|
try {
|
|
2295
|
-
const
|
|
2296
|
-
|
|
2297
|
-
if (account_info) {
|
|
2298
|
-
username = account_info.first_name + ' ' + account_info.last_name;
|
|
2142
|
+
const { uid, email, name, stat, contact_uid, context, source, team_req_id, metadata = {} } = req;
|
|
2143
|
+
const account_profile_info = await get_active_account_profile_info(uid);
|
|
2299
2144
|
|
|
2300
|
-
|
|
2301
|
-
|
|
2145
|
+
const contact_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_user_email_address', { key: [account_profile_info.uid, email] });
|
|
2146
|
+
|
|
2147
|
+
if (contact_ret.rows.length) {
|
|
2148
|
+
throw new Error('contact already exist active or deleted');
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
let is_spam = false;
|
|
2152
|
+
let profile_avatar, profile_avatar_obj;
|
|
2153
|
+
let account_info_ret;
|
|
2154
|
+
if (contact_uid) {
|
|
2155
|
+
account_info_ret = await get_account_name({ uid_query: contact_uid });
|
|
2156
|
+
if (account_info_ret.code < 0) {
|
|
2157
|
+
throw new Error(`account ${contact_uid} not found`);
|
|
2158
|
+
}
|
|
2159
|
+
} else {
|
|
2160
|
+
// contact without use account
|
|
2161
|
+
if (metadata.subject && !metadata.is_sent) {
|
|
2162
|
+
is_spam_ret = await ai_module.is_spam_email(uid, email, metadata.subject);
|
|
2163
|
+
try {
|
|
2164
|
+
if (is_spam_ret.code > -1) {
|
|
2165
|
+
const data = JSON.parse(is_spam_ret.data);
|
|
2166
|
+
is_spam = data.is_spam;
|
|
2167
|
+
}
|
|
2168
|
+
} catch (error) {}
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2171
|
+
const existing_contacts_ret = await db_module.get_couch_view_raw('xuda_contacts', 'contacts_by_email_address', { key: email });
|
|
2172
|
+
for (const contact of existing_contacts_ret.rows) {
|
|
2173
|
+
if (contact.value.profile_avatar) {
|
|
2174
|
+
profile_avatar = contact.value.profile_avatar;
|
|
2175
|
+
profile_avatar_obj == contact.value.profile_avatar_obj;
|
|
2176
|
+
}
|
|
2302
2177
|
}
|
|
2303
2178
|
}
|
|
2179
|
+
const d = Date.now();
|
|
2180
|
+
const doc = {
|
|
2181
|
+
_id: await _common.xuda_get_uuid('contact'),
|
|
2182
|
+
email: [email],
|
|
2183
|
+
name,
|
|
2184
|
+
stat: stat || 1,
|
|
2185
|
+
date_created: d,
|
|
2186
|
+
ts: d,
|
|
2187
|
+
docType: 'contact',
|
|
2188
|
+
contact_uid,
|
|
2189
|
+
uid: account_profile_info.uid,
|
|
2190
|
+
uid_created: uid,
|
|
2191
|
+
context,
|
|
2192
|
+
headers,
|
|
2193
|
+
source,
|
|
2194
|
+
team_req_id,
|
|
2195
|
+
metadata,
|
|
2196
|
+
is_spam,
|
|
2197
|
+
profile_avatar,
|
|
2198
|
+
profile_avatar_obj,
|
|
2199
|
+
account_profile_info,
|
|
2200
|
+
};
|
|
2201
|
+
const ret = await db_module.save_couch_doc('xuda_contacts', doc);
|
|
2304
2202
|
|
|
2305
|
-
|
|
2203
|
+
if (!account_info_ret?.data?.profile_avatar) {
|
|
2204
|
+
const app_id = await get_account_default_project_id(uid);
|
|
2205
|
+
const ai_module = await import(`${module_path}/ai_module/index.mjs`);
|
|
2206
|
+
if (account_info_ret?.data?.profile_avatar) {
|
|
2207
|
+
// account_info_ret.data.profile_avatar_stat = 2;
|
|
2208
|
+
ai_module.create_profile_avatar({ url: account_info_ret.data.profile_picture, uid, account_obj: { _id: contact_uid, account_info: account_info_ret.data }, account_profile_info }, job_id, headers);
|
|
2209
|
+
} else {
|
|
2210
|
+
if (!doc.profile_avatar) {
|
|
2211
|
+
// create factual avatar
|
|
2212
|
+
if (!is_spam) {
|
|
2213
|
+
ai_module.update_thumbnail('contact', doc, account_profile_info.app_id, uid, job_id, headers, 'xuda_contacts', [email, doc._id, 'contact', account_profile_info.app_id], account_profile_info);
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
return ret;
|
|
2306
2219
|
} catch (err) {
|
|
2307
|
-
return
|
|
2220
|
+
return { code: -1, data: err.message };
|
|
2308
2221
|
}
|
|
2309
2222
|
};
|
|
2310
2223
|
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
try {
|
|
2314
|
-
if (!changes.length) return;
|
|
2315
|
-
const ret = await db_module.get_couch_doc('xuda_accounts', uid);
|
|
2316
|
-
var account_obj = ret.data;
|
|
2317
|
-
account_obj.ts = Date.now();
|
|
2224
|
+
export const get_contacts = async function (req) {
|
|
2225
|
+
const { _id, uid, name, limit, skip, bookmark, search, filter_type = 'all', contact_id } = req;
|
|
2318
2226
|
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
}
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
changes_made = true;
|
|
2337
|
-
doc.email = account_obj.account_info.email;
|
|
2338
|
-
}
|
|
2339
|
-
if (changes.includes('first_name') || changes.includes('last_name')) {
|
|
2340
|
-
changes_made = true;
|
|
2341
|
-
doc.name = `${account_obj.account_info.first_name} ${account_obj.account_info.last_name}`;
|
|
2342
|
-
}
|
|
2227
|
+
const account_profile_info = await get_active_account_profile_info(uid);
|
|
2228
|
+
if (_id) {
|
|
2229
|
+
let data = await db_module.get_couch_doc('xuda_contacts', _id);
|
|
2230
|
+
return data;
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
let { with_requests } = req;
|
|
2234
|
+
var opt = {
|
|
2235
|
+
selector: {
|
|
2236
|
+
docType: 'contact',
|
|
2237
|
+
uid: account_profile_info.uid,
|
|
2238
|
+
stat: { $lt: 4 },
|
|
2239
|
+
},
|
|
2240
|
+
limit: limit || 9999,
|
|
2241
|
+
skip: skip || 0,
|
|
2242
|
+
sort: [{ ts: 'desc' }],
|
|
2243
|
+
};
|
|
2343
2244
|
|
|
2344
|
-
|
|
2245
|
+
switch (filter_type) {
|
|
2246
|
+
case 'archived': {
|
|
2247
|
+
opt.selector.stat = 5;
|
|
2248
|
+
break;
|
|
2345
2249
|
}
|
|
2346
|
-
|
|
2347
|
-
|
|
2250
|
+
case 'shared': {
|
|
2251
|
+
opt.selector.shared_from_uid = { $gt: null };
|
|
2252
|
+
break;
|
|
2348
2253
|
}
|
|
2349
2254
|
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
};
|
|
2255
|
+
case 'pinned': {
|
|
2256
|
+
opt.selector.pinned = true;
|
|
2257
|
+
break;
|
|
2258
|
+
}
|
|
2355
2259
|
|
|
2356
|
-
|
|
2357
|
-
|
|
2260
|
+
case 'online': {
|
|
2261
|
+
opt.limit = 9999;
|
|
2262
|
+
break;
|
|
2263
|
+
}
|
|
2358
2264
|
|
|
2359
|
-
|
|
2265
|
+
default:
|
|
2266
|
+
with_requests = true;
|
|
2267
|
+
break;
|
|
2268
|
+
}
|
|
2360
2269
|
|
|
2361
|
-
|
|
2270
|
+
if (_id) {
|
|
2271
|
+
opt.selector._id = _id;
|
|
2272
|
+
}
|
|
2362
2273
|
|
|
2363
|
-
const contact_id = contact_ret?.rows?.[0]?.id;
|
|
2364
2274
|
if (contact_id) {
|
|
2365
|
-
|
|
2366
|
-
} else {
|
|
2367
|
-
user_contact_obj = await get_user_contact(uid, uid_query);
|
|
2275
|
+
opt.selector._id = contact_id;
|
|
2368
2276
|
}
|
|
2369
|
-
return user_contact_obj;
|
|
2370
|
-
};
|
|
2371
|
-
|
|
2372
|
-
// export const generate_user_avatar = async function (req, job_id, headers) {
|
|
2373
|
-
// const { uid, account_info } = req;
|
|
2374
|
-
// try {
|
|
2375
|
-
// const ai_module = await import(`${module_path}/ai_module/index.mjs`);
|
|
2376
|
-
|
|
2377
|
-
// ai_module.create_profile_avatar({ url: account_info?.profile_picture, uid, account_obj }, job_id, headers);
|
|
2378
2277
|
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
// // username = account_info.first_name + ' ' + account_info.last_name;
|
|
2278
|
+
if (typeof name !== 'undefined') {
|
|
2279
|
+
opt.selector.name = { $regex: `(?i)${name}` };
|
|
2280
|
+
}
|
|
2383
2281
|
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2282
|
+
if (typeof search !== 'undefined') {
|
|
2283
|
+
opt.selector['$or'] = [
|
|
2284
|
+
{
|
|
2285
|
+
name: {
|
|
2286
|
+
$regex: `(?i)${search}`,
|
|
2287
|
+
},
|
|
2288
|
+
},
|
|
2289
|
+
{
|
|
2290
|
+
email: {
|
|
2291
|
+
$regex: `(?i)${search}`,
|
|
2292
|
+
},
|
|
2293
|
+
},
|
|
2294
|
+
];
|
|
2295
|
+
}
|
|
2388
2296
|
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
// }
|
|
2393
|
-
// };
|
|
2297
|
+
if (bookmark && bookmark !== 'nil') {
|
|
2298
|
+
opt.bookmark = bookmark;
|
|
2299
|
+
}
|
|
2394
2300
|
|
|
2395
|
-
|
|
2396
|
-
const { uid } = req;
|
|
2397
|
-
try {
|
|
2398
|
-
await update_account_info(req, job_id, headers);
|
|
2301
|
+
let contacts = { docs: [], total_docs: 0 };
|
|
2399
2302
|
|
|
2400
|
-
|
|
2303
|
+
if (filter_type !== 'pending') {
|
|
2304
|
+
contacts = await db_module.find_couch_query('xuda_contacts', opt);
|
|
2305
|
+
if (!limit || contact_id) {
|
|
2306
|
+
contacts.total_docs = contacts.docs.length;
|
|
2307
|
+
} else {
|
|
2308
|
+
delete opt.sort;
|
|
2309
|
+
delete opt.skip;
|
|
2310
|
+
opt.limit = 9999;
|
|
2311
|
+
opt.fields = ['_id'];
|
|
2401
2312
|
|
|
2402
|
-
|
|
2403
|
-
|
|
2313
|
+
const counter = await db_module.find_couch_query('xuda_contacts', opt);
|
|
2314
|
+
contacts.total_docs = counter.docs.length;
|
|
2404
2315
|
}
|
|
2316
|
+
}
|
|
2405
2317
|
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2318
|
+
let requests_to = { docs: [], total_docs: 0 };
|
|
2319
|
+
let requests_from = { docs: [], total_docs: 0 };
|
|
2320
|
+
let shared_from = { docs: [], total_docs: 0 };
|
|
2409
2321
|
|
|
2410
|
-
|
|
2411
|
-
|
|
2322
|
+
let contact_docs = { docs: [], total_docs: contacts.total_docs };
|
|
2323
|
+
for await (let doc of contacts.docs) {
|
|
2324
|
+
const ret_to = requests_to.docs.find((e) => {
|
|
2325
|
+
return e.contact_uid === doc.contact_uid;
|
|
2326
|
+
});
|
|
2327
|
+
if (ret_to) continue;
|
|
2412
2328
|
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
let drive_req = { app_id: account_doc.account_project_id, uid, path: '/' };
|
|
2418
|
-
await drive_module.create_drive_folder_user({ ...drive_req, ...{ folder_name: 'Profile Images', is_system: true } }, job_id, headers);
|
|
2419
|
-
await drive_module.create_drive_folder_user({ ...drive_req, ...{ folder_name: 'Chat Thumbnails', is_system: true } }, job_id, headers);
|
|
2420
|
-
await drive_module.create_drive_folder_user({ ...drive_req, ...{ folder_name: 'Chat Attachments', is_system: true } }, job_id, headers);
|
|
2421
|
-
}
|
|
2422
|
-
}
|
|
2329
|
+
const ret_from = requests_from.docs.find((e) => {
|
|
2330
|
+
return e.contact_uid === doc.contact_uid;
|
|
2331
|
+
});
|
|
2332
|
+
if (ret_from) continue;
|
|
2423
2333
|
|
|
2424
|
-
|
|
2334
|
+
doc = await get_contact_info(uid, doc);
|
|
2425
2335
|
|
|
2426
|
-
if (
|
|
2427
|
-
|
|
2428
|
-
}
|
|
2429
|
-
if (!account_doc.account_profile_id) {
|
|
2430
|
-
const account_profile_ret = await create_account_profile({ uid, profile_name: account_doc.account_info.full_name, main: true });
|
|
2431
|
-
account_doc.account_profile_id = account_profile_ret.data.id;
|
|
2432
|
-
account_doc.account_info.active_account_profile_id = account_doc.account_profile_id;
|
|
2336
|
+
if (filter_type === 'online') {
|
|
2337
|
+
if (!doc.online) continue;
|
|
2433
2338
|
}
|
|
2434
|
-
account_doc.boarded_info = { headers, date_ts: Date.now() };
|
|
2435
|
-
account_doc.isBoarded = true;
|
|
2436
|
-
const save_ret = await db_module.save_couch_doc('xuda_accounts', account_doc);
|
|
2437
2339
|
|
|
2438
|
-
|
|
2340
|
+
contact_docs.docs.push(doc);
|
|
2341
|
+
}
|
|
2439
2342
|
|
|
2440
|
-
|
|
2441
|
-
if (
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
};
|
|
2446
|
-
}
|
|
2447
|
-
await db_module.save_app_couch_doc_native(account_doc.account_project_id, _design);
|
|
2448
|
-
///////
|
|
2343
|
+
if (!contact_id && with_requests) {
|
|
2344
|
+
if (filter_type === 'pending') {
|
|
2345
|
+
////// TO - OUT
|
|
2346
|
+
requests_to.docs = await get_pending_contact_out(uid);
|
|
2347
|
+
requests_to.total_docs = requests_to.docs.length;
|
|
2449
2348
|
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2349
|
+
////// FROM - IN
|
|
2350
|
+
requests_from.docs = await get_pending_contact_in(uid);
|
|
2351
|
+
requests_from.total_docs = requests_from.docs.length;
|
|
2352
|
+
shared_from.docs = await get_pending_share_contact_in(uid);
|
|
2353
|
+
shared_from.total_docs = shared_from.docs.length;
|
|
2354
|
+
}
|
|
2453
2355
|
}
|
|
2454
|
-
};
|
|
2455
2356
|
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
}
|
|
2463
|
-
console.error(err);
|
|
2464
|
-
}
|
|
2357
|
+
return {
|
|
2358
|
+
code: 1,
|
|
2359
|
+
data: {
|
|
2360
|
+
docs: [...shared_from.docs, ...requests_from.docs, ...requests_to.docs, ...contact_docs.docs],
|
|
2361
|
+
total_docs: shared_from.total_docs + requests_from.total_docs + requests_to.total_docs + contact_docs.total_docs,
|
|
2362
|
+
},
|
|
2363
|
+
};
|
|
2465
2364
|
};
|
|
2466
2365
|
|
|
2467
|
-
export const
|
|
2468
|
-
const {
|
|
2366
|
+
export const archive_contact = async function (req) {
|
|
2367
|
+
const { contact_id } = req;
|
|
2469
2368
|
try {
|
|
2470
|
-
const
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
const d = new Date();
|
|
2474
|
-
const curr_month = Number(String(d.getMonth() + 1).padStart(2, '0')); // months are 0-based
|
|
2475
|
-
const curr_year = d.getFullYear();
|
|
2369
|
+
const team_module = await import(`${module_path}/team_module/index.mjs`);
|
|
2370
|
+
await team_module.validate_share_exist(uid, 'contact', contact_id);
|
|
2476
2371
|
|
|
2477
|
-
|
|
2478
|
-
startkey: [year || curr_year, month || curr_month, day || 0],
|
|
2479
|
-
endkey: [year || curr_year, month || curr_month, day || 99],
|
|
2480
|
-
reduce: true,
|
|
2481
|
-
group_level: 999,
|
|
2482
|
-
});
|
|
2483
|
-
// console.log('ai_usage', ai_usage.rows);
|
|
2372
|
+
var contact_doc = await db_module.get_couch_doc_native('xuda_contacts', contact_id);
|
|
2484
2373
|
|
|
2485
|
-
|
|
2486
|
-
|
|
2374
|
+
if (contact_doc.uid !== uid && contact_doc?.account_profile_info?.uid !== uid) {
|
|
2375
|
+
throw new Error('Operation not allowed');
|
|
2376
|
+
}
|
|
2487
2377
|
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
const day = row.key[2];
|
|
2492
|
-
const account_profile_id = row.key[3];
|
|
2493
|
-
const uid = row.key[4];
|
|
2494
|
-
const model = row.key[5];
|
|
2495
|
-
const input_tokens = row.value[0];
|
|
2496
|
-
const output_tokens = row.value[1];
|
|
2497
|
-
const input_credits = row.value[2];
|
|
2498
|
-
const output_credits = row.value[3];
|
|
2499
|
-
if (!profile[account_profile_id]) {
|
|
2500
|
-
profile[account_profile_id] = {};
|
|
2501
|
-
}
|
|
2502
|
-
if (!profile[account_profile_id][uid]) {
|
|
2503
|
-
profile[account_profile_id][uid] = 0;
|
|
2504
|
-
}
|
|
2378
|
+
contact_doc.stat = 5;
|
|
2379
|
+
contact_doc.stat_ts = Date.now();
|
|
2380
|
+
contact_doc.stat_reason = 'archived by the user';
|
|
2505
2381
|
|
|
2506
|
-
|
|
2507
|
-
total_usage += input_credits + output_credits;
|
|
2508
|
-
}
|
|
2382
|
+
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
2509
2383
|
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2384
|
+
return contact_save_ret;
|
|
2385
|
+
} catch (err) {
|
|
2386
|
+
return {
|
|
2387
|
+
code: -22,
|
|
2388
|
+
data: err.message,
|
|
2389
|
+
};
|
|
2390
|
+
}
|
|
2391
|
+
};
|
|
2514
2392
|
|
|
2515
|
-
|
|
2393
|
+
export const delete_contact = async function (req, job_id, headers) {
|
|
2394
|
+
const { contact_id } = req;
|
|
2395
|
+
try {
|
|
2396
|
+
var contact_doc = await db_module.get_couch_doc_native('xuda_contacts', contact_id);
|
|
2397
|
+
if (contact_doc.stat !== 5) {
|
|
2398
|
+
throw new Error('A document can only be deleted after it has been archived');
|
|
2399
|
+
}
|
|
2400
|
+
contact_doc.stat = 4;
|
|
2401
|
+
contact_doc.stat_ts = Date.now();
|
|
2402
|
+
contact_doc.stat_reason = 'deleted by the user';
|
|
2516
2403
|
|
|
2517
|
-
|
|
2404
|
+
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
2405
|
+
const ai_module = await import(`${module_path}/ai_module/index.mjs`);
|
|
2406
|
+
ai_module.delete_depended_chats(uid, contact_id);
|
|
2407
|
+
return contact_save_ret;
|
|
2518
2408
|
} catch (err) {
|
|
2519
|
-
return {
|
|
2409
|
+
return {
|
|
2410
|
+
code: -22,
|
|
2411
|
+
data: err.message,
|
|
2412
|
+
};
|
|
2520
2413
|
}
|
|
2521
2414
|
};
|
|
2522
2415
|
|
|
2523
|
-
export const
|
|
2524
|
-
const {
|
|
2416
|
+
export const unarchive_contact = async function (req) {
|
|
2417
|
+
const { contact_id } = req;
|
|
2525
2418
|
try {
|
|
2526
|
-
|
|
2527
|
-
const { data: acc_obj } = await db_module.get_couch_doc('xuda_accounts', uid);
|
|
2419
|
+
var contact_doc = await db_module.get_couch_doc_native('xuda_contacts', contact_id);
|
|
2528
2420
|
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
stat: 3,
|
|
2533
|
-
date_created_ts: d,
|
|
2534
|
-
ts: d,
|
|
2535
|
-
docType: 'account_profile',
|
|
2421
|
+
if (contact_doc.stat !== 5) {
|
|
2422
|
+
throw new Error('contact is not archived');
|
|
2423
|
+
}
|
|
2536
2424
|
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
profile_email,
|
|
2541
|
-
profile_picture,
|
|
2542
|
-
profile_avatar,
|
|
2543
|
-
profile_picture_obj,
|
|
2544
|
-
profile_avatar_obj,
|
|
2545
|
-
main,
|
|
2546
|
-
};
|
|
2547
|
-
const save_ret = await db_module.save_couch_doc('xuda_accounts', doc);
|
|
2548
|
-
// acc_obj.active_profile_id = save_ret.data.id;
|
|
2425
|
+
contact_doc.stat = 3;
|
|
2426
|
+
contact_doc.stat_ts = Date.now();
|
|
2427
|
+
contact_doc.stat_reason = 'archived by the user';
|
|
2549
2428
|
|
|
2550
|
-
|
|
2551
|
-
|
|
2429
|
+
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
2430
|
+
|
|
2431
|
+
return contact_save_ret;
|
|
2552
2432
|
} catch (err) {
|
|
2553
|
-
return {
|
|
2433
|
+
return {
|
|
2434
|
+
code: -22,
|
|
2435
|
+
data: err.message,
|
|
2436
|
+
};
|
|
2554
2437
|
}
|
|
2555
2438
|
};
|
|
2556
2439
|
|
|
2557
|
-
export const
|
|
2558
|
-
const {
|
|
2559
|
-
const account_profile_properties = ['profile_name', 'profile_signature', 'profile_email', 'profile_picture', 'profile_avatar', 'profile_picture_obj', 'profile_avatar_obj', 'auto_respond', 'auto_respond_mode', 'auto_respond_agents'];
|
|
2440
|
+
export const unfriend_contact = async function (req) {
|
|
2441
|
+
const { contact_id } = req;
|
|
2560
2442
|
try {
|
|
2561
|
-
|
|
2443
|
+
const contact_ret = await db_module.get_couch_doc('xuda_contacts', contact_id);
|
|
2444
|
+
if (contact_ret.code < 0) {
|
|
2445
|
+
throw new Error(contact_ret.data);
|
|
2446
|
+
}
|
|
2447
|
+
var contact_doc = contact_ret.data;
|
|
2562
2448
|
|
|
2563
|
-
if (
|
|
2564
|
-
throw new Error('
|
|
2449
|
+
if (!contact_doc.team_req_id) {
|
|
2450
|
+
throw new Error('no friend relationship found');
|
|
2565
2451
|
}
|
|
2452
|
+
let req_doc = await db_module.get_couch_doc_native('xuda_team', contact_doc.team_req_id);
|
|
2453
|
+
req_doc.team_req_stat = 4;
|
|
2454
|
+
req_doc.team_req_stat_desc = 'unfriend by the user';
|
|
2455
|
+
await db_module.get_couch_doc_native('xuda_team', contact_doc.team_req_id);
|
|
2566
2456
|
|
|
2567
|
-
|
|
2457
|
+
contact_doc.team_req_id = null;
|
|
2458
|
+
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
2568
2459
|
|
|
2569
|
-
|
|
2570
|
-
let val = req[key];
|
|
2571
|
-
if (typeof val === 'undefined') continue;
|
|
2572
|
-
if (account_profile_doc[key] !== val) {
|
|
2573
|
-
changes_arr.push(key);
|
|
2574
|
-
account_profile_doc[key] = val;
|
|
2575
|
-
}
|
|
2576
|
-
}
|
|
2460
|
+
const req_save_ret = await db_module.save_couch_doc('xuda_team', req_doc);
|
|
2577
2461
|
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2462
|
+
return req_save_ret;
|
|
2463
|
+
} catch (err) {
|
|
2464
|
+
return {
|
|
2465
|
+
code: -21,
|
|
2466
|
+
data: err.message,
|
|
2467
|
+
};
|
|
2468
|
+
}
|
|
2469
|
+
};
|
|
2470
|
+
|
|
2471
|
+
export const pin_contact = async function (req) {
|
|
2472
|
+
const { uid, contact_id } = req;
|
|
2473
|
+
try {
|
|
2474
|
+
const contact_ret = await db_module.get_couch_doc('xuda_contacts', contact_id);
|
|
2475
|
+
if (contact_ret.code < 0) {
|
|
2476
|
+
return contact_ret;
|
|
2581
2477
|
}
|
|
2478
|
+
var contact_doc = contact_ret.data;
|
|
2479
|
+
contact_doc.pinned = true;
|
|
2582
2480
|
|
|
2583
|
-
|
|
2481
|
+
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
2584
2482
|
|
|
2585
|
-
|
|
2483
|
+
global[`_account_module_ch`].sendToQueue(
|
|
2484
|
+
'ws_dashboard_module',
|
|
2485
|
+
Buffer.from(
|
|
2486
|
+
JSON.stringify({
|
|
2487
|
+
method: 'emit_message_to_dashboard',
|
|
2488
|
+
data: {
|
|
2489
|
+
service: 'contact_pinned',
|
|
2490
|
+
to: [uid],
|
|
2491
|
+
data: await get_contact_info(uid, null, contact_id),
|
|
2492
|
+
},
|
|
2493
|
+
}),
|
|
2494
|
+
),
|
|
2495
|
+
);
|
|
2586
2496
|
|
|
2587
|
-
return
|
|
2497
|
+
return contact_save_ret;
|
|
2588
2498
|
} catch (err) {
|
|
2589
|
-
return {
|
|
2499
|
+
return {
|
|
2500
|
+
code: -24,
|
|
2501
|
+
data: err.message,
|
|
2502
|
+
};
|
|
2590
2503
|
}
|
|
2591
2504
|
};
|
|
2592
2505
|
|
|
2593
|
-
|
|
2594
|
-
const
|
|
2595
|
-
|
|
2506
|
+
export const unpin_contact = async function (req) {
|
|
2507
|
+
const { contact_id, uid } = req;
|
|
2508
|
+
try {
|
|
2509
|
+
const contact_ret = await db_module.get_couch_doc('xuda_contacts', contact_id);
|
|
2510
|
+
if (contact_ret.code < 0) {
|
|
2511
|
+
return contact_ret;
|
|
2512
|
+
}
|
|
2513
|
+
var contact_doc = contact_ret.data;
|
|
2514
|
+
contact_doc.pinned = false;
|
|
2596
2515
|
|
|
2597
|
-
|
|
2516
|
+
const contact_save_ret = await db_module.save_couch_doc('xuda_contacts', contact_doc);
|
|
2598
2517
|
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2518
|
+
global[`_account_module_ch`].sendToQueue(
|
|
2519
|
+
'ws_dashboard_module',
|
|
2520
|
+
Buffer.from(
|
|
2521
|
+
JSON.stringify({
|
|
2522
|
+
method: 'emit_message_to_dashboard',
|
|
2523
|
+
data: {
|
|
2524
|
+
service: 'contact_unpinned',
|
|
2525
|
+
to: [uid],
|
|
2526
|
+
data: await get_contact_info(uid, null, contact_id),
|
|
2527
|
+
},
|
|
2528
|
+
}),
|
|
2529
|
+
),
|
|
2530
|
+
);
|
|
2602
2531
|
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2532
|
+
return contact_save_ret;
|
|
2533
|
+
} catch (err) {
|
|
2534
|
+
return {
|
|
2535
|
+
code: -24,
|
|
2536
|
+
data: err.message,
|
|
2537
|
+
};
|
|
2538
|
+
}
|
|
2539
|
+
};
|
|
2540
|
+
|
|
2541
|
+
//////// PROFILES //////////////
|
|
2608
2542
|
|
|
2609
2543
|
export const get_pending_share_profile_in = async function (uid, _id) {
|
|
2610
2544
|
let docs = [];
|
|
@@ -2950,42 +2884,72 @@ export const unarchive_account_profile = async function (req) {
|
|
|
2950
2884
|
}
|
|
2951
2885
|
};
|
|
2952
2886
|
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
//
|
|
2957
|
-
|
|
2958
|
-
// return {
|
|
2959
|
-
// code: -21,
|
|
2960
|
-
// data: err.message,
|
|
2961
|
-
// };
|
|
2962
|
-
// }
|
|
2963
|
-
// };
|
|
2887
|
+
export const create_account_profile = async function (req, job_id, headers) {
|
|
2888
|
+
const { uid, profile_name, profile_signature, profile_email, profile_picture, profile_avatar, profile_picture_obj, profile_avatar_obj, main } = req;
|
|
2889
|
+
try {
|
|
2890
|
+
// const app_id = await get_account_default_project_id(uid);
|
|
2891
|
+
const { data: acc_obj } = await db_module.get_couch_doc('xuda_accounts', uid);
|
|
2964
2892
|
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2893
|
+
const d = Date.now();
|
|
2894
|
+
const doc = {
|
|
2895
|
+
_id: await _common.xuda_get_uuid('account_profile'),
|
|
2896
|
+
stat: 3,
|
|
2897
|
+
date_created_ts: d,
|
|
2898
|
+
ts: d,
|
|
2899
|
+
docType: 'account_profile',
|
|
2970
2900
|
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2901
|
+
uid,
|
|
2902
|
+
profile_name, //: profile_name || acc_obj.account_info.business_name || acc_obj.account_info.name,
|
|
2903
|
+
profile_signature,
|
|
2904
|
+
profile_email,
|
|
2905
|
+
profile_picture,
|
|
2906
|
+
profile_avatar,
|
|
2907
|
+
profile_picture_obj,
|
|
2908
|
+
profile_avatar_obj,
|
|
2909
|
+
main,
|
|
2910
|
+
};
|
|
2911
|
+
const save_ret = await db_module.save_couch_doc('xuda_accounts', doc);
|
|
2912
|
+
// acc_obj.active_profile_id = save_ret.data.id;
|
|
2978
2913
|
|
|
2979
|
-
//
|
|
2914
|
+
// return { code: 55, data: save_ret };
|
|
2915
|
+
return save_ret;
|
|
2916
|
+
} catch (err) {
|
|
2917
|
+
return { code: -55, data: err.message };
|
|
2918
|
+
}
|
|
2919
|
+
};
|
|
2980
2920
|
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2921
|
+
export const update_account_profile = async function (req, job_id, headers) {
|
|
2922
|
+
const { uid, _id } = req;
|
|
2923
|
+
const account_profile_properties = ['profile_name', 'profile_signature', 'profile_email', 'profile_picture', 'profile_avatar', 'profile_picture_obj', 'profile_avatar_obj', 'auto_respond', 'auto_respond_mode', 'auto_respond_agents'];
|
|
2924
|
+
try {
|
|
2925
|
+
let { data: account_profile_doc } = await db_module.get_couch_doc('xuda_accounts', _id);
|
|
2926
|
+
|
|
2927
|
+
if (account_profile_doc.docType !== 'account_profile') {
|
|
2928
|
+
throw new Error('not account profile doc');
|
|
2929
|
+
}
|
|
2930
|
+
|
|
2931
|
+
let changes_arr = [];
|
|
2932
|
+
|
|
2933
|
+
for (const key of account_profile_properties) {
|
|
2934
|
+
let val = req[key];
|
|
2935
|
+
if (typeof val === 'undefined') continue;
|
|
2936
|
+
if (account_profile_doc[key] !== val) {
|
|
2937
|
+
changes_arr.push(key);
|
|
2938
|
+
account_profile_doc[key] = val;
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
|
|
2942
|
+
if (!changes_arr.length) {
|
|
2943
|
+
// throw new Error('no change');
|
|
2944
|
+
return { code: 56, data: 'no change' };
|
|
2945
|
+
}
|
|
2946
|
+
|
|
2947
|
+
account_profile_doc.ts = Date.now();
|
|
2948
|
+
|
|
2949
|
+
const save_ret = await db_module.save_couch_doc('xuda_accounts', account_profile_doc);
|
|
2950
|
+
|
|
2951
|
+
return { code: 56, data: save_ret };
|
|
2952
|
+
} catch (err) {
|
|
2953
|
+
return { code: -56, data: err.message };
|
|
2954
|
+
}
|
|
2955
|
+
};
|