@winible/winible-typed 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/README.md +32 -0
  2. package/dist/index.js +20 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/migrations/20220601151258-custom_name_describing_your_migration.js +19 -0
  5. package/dist/migrations/20220601151258-custom_name_describing_your_migration.js.map +1 -0
  6. package/dist/migrations/20220605225655-create-dashboard-user-permissions.js +27 -0
  7. package/dist/migrations/20220605225655-create-dashboard-user-permissions.js.map +1 -0
  8. package/dist/migrations/20220606001300-update-dashboard-user-permissions.js +14 -0
  9. package/dist/migrations/20220606001300-update-dashboard-user-permissions.js.map +1 -0
  10. package/dist/migrations/20220607091109-add-read-date-for-message.js +19 -0
  11. package/dist/migrations/20220607091109-add-read-date-for-message.js.map +1 -0
  12. package/dist/migrations/20220616225456-add-delete-columns.js +21 -0
  13. package/dist/migrations/20220616225456-add-delete-columns.js.map +1 -0
  14. package/dist/migrations/20220709202211-disable-feed.js +24 -0
  15. package/dist/migrations/20220709202211-disable-feed.js.map +1 -0
  16. package/dist/migrations/20220723215213-limit-promotion-claims.js +18 -0
  17. package/dist/migrations/20220723215213-limit-promotion-claims.js.map +1 -0
  18. package/dist/migrations/20220723220233-num_claims.js +12 -0
  19. package/dist/migrations/20220723220233-num_claims.js.map +1 -0
  20. package/dist/migrations/20220723221907-default_false_promos.js +17 -0
  21. package/dist/migrations/20220723221907-default_false_promos.js.map +1 -0
  22. package/dist/migrations/20220724172559-default_zero_claims.js +13 -0
  23. package/dist/migrations/20220724172559-default_zero_claims.js.map +1 -0
  24. package/dist/migrations/20220724201419-pinned_post.js +13 -0
  25. package/dist/migrations/20220724201419-pinned_post.js.map +1 -0
  26. package/dist/migrations/20220729164625-unsend_mass.js +12 -0
  27. package/dist/migrations/20220729164625-unsend_mass.js.map +1 -0
  28. package/dist/migrations/20220823033002-interval-unit.js +14 -0
  29. package/dist/migrations/20220823033002-interval-unit.js.map +1 -0
  30. package/dist/migrations/20220830193530-processorId.js +15 -0
  31. package/dist/migrations/20220830193530-processorId.js.map +1 -0
  32. package/dist/migrations/20220907121932-add-processor-to-sub.js +15 -0
  33. package/dist/migrations/20220907121932-add-processor-to-sub.js.map +1 -0
  34. package/dist/migrations/20220907212232-add-trans-id.js +12 -0
  35. package/dist/migrations/20220907212232-add-trans-id.js.map +1 -0
  36. package/dist/migrations/20220907220423-big-int-trans.js +12 -0
  37. package/dist/migrations/20220907220423-big-int-trans.js.map +1 -0
  38. package/dist/migrations/20220909161902-add-stale.js +13 -0
  39. package/dist/migrations/20220909161902-add-stale.js.map +1 -0
  40. package/dist/migrations/20220922000225-verified-spender.js +13 -0
  41. package/dist/migrations/20220922000225-verified-spender.js.map +1 -0
  42. package/dist/migrations/20220922212108-verified-spender-2.js +16 -0
  43. package/dist/migrations/20220922212108-verified-spender-2.js.map +1 -0
  44. package/dist/migrations/20221013223648-product-subscription-list.js +12 -0
  45. package/dist/migrations/20221013223648-product-subscription-list.js.map +1 -0
  46. package/dist/migrations/20221014001037-product-subscription-list.js +75 -0
  47. package/dist/migrations/20221014001037-product-subscription-list.js.map +1 -0
  48. package/dist/migrations/20221026055245-update-type.js +15 -0
  49. package/dist/migrations/20221026055245-update-type.js.map +1 -0
  50. package/dist/scripts/authorizeTransfer.js +188 -0
  51. package/dist/scripts/authorizeTransfer.js.map +1 -0
  52. package/dist/scripts/createDashboardLink.js +30 -0
  53. package/dist/scripts/createDashboardLink.js.map +1 -0
  54. package/dist/scripts/deleteMalformedImages.js +84 -0
  55. package/dist/scripts/deleteMalformedImages.js.map +1 -0
  56. package/dist/scripts/importMixpanelEvents.js +44 -0
  57. package/dist/scripts/importMixpanelEvents.js.map +1 -0
  58. package/dist/scripts/payoutSubscriptions.js +185 -0
  59. package/dist/scripts/payoutSubscriptions.js.map +1 -0
  60. package/dist/scripts/removeUnreferenceSubs.js +39 -0
  61. package/dist/scripts/removeUnreferenceSubs.js.map +1 -0
  62. package/dist/scripts/test.js +33 -0
  63. package/dist/scripts/test.js.map +1 -0
  64. package/dist/server/index.js +30 -0
  65. package/dist/server/index.js.map +1 -0
  66. package/dist/server/middlewares/slack-auth.js +40 -0
  67. package/dist/server/middlewares/slack-auth.js.map +1 -0
  68. package/dist/server/v1/bypassCreator.js +81 -0
  69. package/dist/server/v1/bypassCreator.js.map +1 -0
  70. package/dist/server/v1/cancelSubscription.js +35 -0
  71. package/dist/server/v1/cancelSubscription.js.map +1 -0
  72. package/dist/server/v1/changeName.js +41 -0
  73. package/dist/server/v1/changeName.js.map +1 -0
  74. package/dist/server/v1/checkAuthSub.js +58 -0
  75. package/dist/server/v1/checkAuthSub.js.map +1 -0
  76. package/dist/server/v1/dashboardLink.js +30 -0
  77. package/dist/server/v1/dashboardLink.js.map +1 -0
  78. package/dist/server/v1/getSuspendedSubs.js +76 -0
  79. package/dist/server/v1/getSuspendedSubs.js.map +1 -0
  80. package/dist/server/v1/index.js +28 -0
  81. package/dist/server/v1/index.js.map +1 -0
  82. package/dist/server/v1/manualCreateSub.js +159 -0
  83. package/dist/server/v1/manualCreateSub.js.map +1 -0
  84. package/dist/server/v1/refund.js +78 -0
  85. package/dist/server/v1/refund.js.map +1 -0
  86. package/dist/server/v1/retrySubscription.js +81 -0
  87. package/dist/server/v1/retrySubscription.js.map +1 -0
  88. package/dist/server/v1/searchUser.js +169 -0
  89. package/dist/server/v1/searchUser.js.map +1 -0
  90. package/dist/server/v1/slack.js +14 -0
  91. package/dist/server/v1/slack.js.map +1 -0
  92. package/dist/src/index.js +24 -0
  93. package/dist/src/index.js.map +1 -0
  94. package/dist/src/pk-client.js +1103 -0
  95. package/dist/src/pk-client.js.map +1 -0
  96. package/dist/src/pk-sub.js +310 -0
  97. package/dist/src/pk-sub.js.map +1 -0
  98. package/dist/src/slack-client.js +48 -0
  99. package/dist/src/slack-client.js.map +1 -0
  100. package/dist/src/types.js +3 -0
  101. package/dist/src/types.js.map +1 -0
  102. package/dist/support/index.js +19 -0
  103. package/dist/support/index.js.map +1 -0
  104. package/dist/support/metrics.js +21 -0
  105. package/dist/support/metrics.js.map +1 -0
  106. package/dist/support/mixpanel.js +7 -0
  107. package/dist/support/mixpanel.js.map +1 -0
  108. package/dist/support/slack-client.js +51 -0
  109. package/dist/support/slack-client.js.map +1 -0
  110. package/dist/support/uploadcare.js +140 -0
  111. package/dist/support/uploadcare.js.map +1 -0
  112. package/dist/support/utils.js +69 -0
  113. package/dist/support/utils.js.map +1 -0
  114. package/dist/typed-model/asset-category.js +38 -0
  115. package/dist/typed-model/asset-category.js.map +1 -0
  116. package/dist/typed-model/asset-constent-person.js +56 -0
  117. package/dist/typed-model/asset-constent-person.js.map +1 -0
  118. package/dist/typed-model/blocked-ip.js +34 -0
  119. package/dist/typed-model/blocked-ip.js.map +1 -0
  120. package/dist/typed-model/category-tag.js +46 -0
  121. package/dist/typed-model/category-tag.js.map +1 -0
  122. package/dist/typed-model/consent-person.js +55 -0
  123. package/dist/typed-model/consent-person.js.map +1 -0
  124. package/dist/typed-model/content-category-tag.js +58 -0
  125. package/dist/typed-model/content-category-tag.js.map +1 -0
  126. package/dist/typed-model/content-like.js +58 -0
  127. package/dist/typed-model/content-like.js.map +1 -0
  128. package/dist/typed-model/credit-payment.js +389 -0
  129. package/dist/typed-model/credit-payment.js.map +1 -0
  130. package/dist/typed-model/credit-payout.js +42 -0
  131. package/dist/typed-model/credit-payout.js.map +1 -0
  132. package/dist/typed-model/credit-purchase.js +46 -0
  133. package/dist/typed-model/credit-purchase.js.map +1 -0
  134. package/dist/typed-model/customer-profile.js +51 -0
  135. package/dist/typed-model/customer-profile.js.map +1 -0
  136. package/dist/typed-model/dashboard-user-permissions.js +34 -0
  137. package/dist/typed-model/dashboard-user-permissions.js.map +1 -0
  138. package/dist/typed-model/dashboard-user.js +109 -0
  139. package/dist/typed-model/dashboard-user.js.map +1 -0
  140. package/dist/typed-model/fan-list.js +46 -0
  141. package/dist/typed-model/fan-list.js.map +1 -0
  142. package/dist/typed-model/fraud.js +41 -0
  143. package/dist/typed-model/fraud.js.map +1 -0
  144. package/dist/typed-model/index.js +101 -0
  145. package/dist/typed-model/index.js.map +1 -0
  146. package/dist/typed-model/list-member.js +47 -0
  147. package/dist/typed-model/list-member.js.map +1 -0
  148. package/dist/typed-model/mass-message.js +43 -0
  149. package/dist/typed-model/mass-message.js.map +1 -0
  150. package/dist/typed-model/media-asset.js +73 -0
  151. package/dist/typed-model/media-asset.js.map +1 -0
  152. package/dist/typed-model/media-category.js +49 -0
  153. package/dist/typed-model/media-category.js.map +1 -0
  154. package/dist/typed-model/media.js +59 -0
  155. package/dist/typed-model/media.js.map +1 -0
  156. package/dist/typed-model/message-media.js +53 -0
  157. package/dist/typed-model/message-media.js.map +1 -0
  158. package/dist/typed-model/message.js +191 -0
  159. package/dist/typed-model/message.js.map +1 -0
  160. package/dist/typed-model/notification.js +84 -0
  161. package/dist/typed-model/notification.js.map +1 -0
  162. package/dist/typed-model/pb-sequelize.js +25 -0
  163. package/dist/typed-model/pb-sequelize.js.map +1 -0
  164. package/dist/typed-model/phone-chat-participation.js +127 -0
  165. package/dist/typed-model/phone-chat-participation.js.map +1 -0
  166. package/dist/typed-model/phone-chat.js +118 -0
  167. package/dist/typed-model/phone-chat.js.map +1 -0
  168. package/dist/typed-model/phone-owner.js +266 -0
  169. package/dist/typed-model/phone-owner.js.map +1 -0
  170. package/dist/typed-model/phone-user.js +109 -0
  171. package/dist/typed-model/phone-user.js.map +1 -0
  172. package/dist/typed-model/premium-content.js +123 -0
  173. package/dist/typed-model/premium-content.js.map +1 -0
  174. package/dist/typed-model/purchased-content.js +69 -0
  175. package/dist/typed-model/purchased-content.js.map +1 -0
  176. package/dist/typed-model/short-url.js +88 -0
  177. package/dist/typed-model/short-url.js.map +1 -0
  178. package/dist/typed-model/subscription-bundle.js +53 -0
  179. package/dist/typed-model/subscription-bundle.js.map +1 -0
  180. package/dist/typed-model/subscription-category-tags.js +58 -0
  181. package/dist/typed-model/subscription-category-tags.js.map +1 -0
  182. package/dist/typed-model/subscription-plan.js +126 -0
  183. package/dist/typed-model/subscription-plan.js.map +1 -0
  184. package/dist/typed-model/subscription-promotion.js +93 -0
  185. package/dist/typed-model/subscription-promotion.js.map +1 -0
  186. package/dist/typed-model/subscription.js +123 -0
  187. package/dist/typed-model/subscription.js.map +1 -0
  188. package/dist/typed-model/twilio-phone.js +92 -0
  189. package/dist/typed-model/twilio-phone.js.map +1 -0
  190. package/dist/typed-model/user-follow.js +103 -0
  191. package/dist/typed-model/user-follow.js.map +1 -0
  192. package/dist/typed-model/verification-code.js +52 -0
  193. package/dist/typed-model/verification-code.js.map +1 -0
  194. package/index.ts +3 -0
  195. package/package.json +72 -0
  196. package/src/index.ts +2 -0
  197. package/src/pk-client.ts +1650 -0
  198. package/src/pk-sub.ts +455 -0
  199. package/src/types.ts +40 -0
  200. package/support/index.ts +2 -0
  201. package/support/slack-client.ts +43 -0
  202. package/support/uploadcare.ts +191 -0
  203. package/support/utils.ts +72 -0
  204. package/typed-model/asset-category.ts +57 -0
  205. package/typed-model/asset-constent-person.ts +82 -0
  206. package/typed-model/blocked-ip.ts +52 -0
  207. package/typed-model/category-tag.ts +66 -0
  208. package/typed-model/consent-person.ts +78 -0
  209. package/typed-model/content-category-tag.ts +79 -0
  210. package/typed-model/content-like.ts +79 -0
  211. package/typed-model/credit-payment.ts +678 -0
  212. package/typed-model/credit-payout.ts +62 -0
  213. package/typed-model/credit-purchase.ts +67 -0
  214. package/typed-model/customer-profile.ts +70 -0
  215. package/typed-model/dashboard-user-permissions.ts +51 -0
  216. package/typed-model/dashboard-user.ts +146 -0
  217. package/typed-model/fan-list.ts +68 -0
  218. package/typed-model/fraud.ts +62 -0
  219. package/typed-model/index.ts +58 -0
  220. package/typed-model/list-member.ts +67 -0
  221. package/typed-model/mass-message.ts +64 -0
  222. package/typed-model/media-asset.ts +99 -0
  223. package/typed-model/media-category.ts +70 -0
  224. package/typed-model/media.ts +85 -0
  225. package/typed-model/message-media.ts +74 -0
  226. package/typed-model/message.ts +258 -0
  227. package/typed-model/notification.ts +130 -0
  228. package/typed-model/pb-sequelize.ts +25 -0
  229. package/typed-model/phone-chat-participation.ts +166 -0
  230. package/typed-model/phone-chat.ts +185 -0
  231. package/typed-model/phone-owner.ts +341 -0
  232. package/typed-model/phone-user.ts +146 -0
  233. package/typed-model/premium-content.ts +164 -0
  234. package/typed-model/purchased-content.ts +100 -0
  235. package/typed-model/short-url.ts +120 -0
  236. package/typed-model/subscription-bundle.ts +75 -0
  237. package/typed-model/subscription-category-tags.ts +79 -0
  238. package/typed-model/subscription-plan.ts +171 -0
  239. package/typed-model/subscription-promotion.ts +125 -0
  240. package/typed-model/subscription.ts +170 -0
  241. package/typed-model/twilio-phone.ts +149 -0
  242. package/typed-model/user-follow.ts +141 -0
  243. package/typed-model/verification-code.ts +74 -0
@@ -0,0 +1,130 @@
1
+ import {
2
+ Model,
3
+ InferAttributes,
4
+ InferCreationAttributes,
5
+ CreationOptional,
6
+ DataTypes,
7
+ fn,
8
+ NOW,
9
+ } from "sequelize";
10
+
11
+ import sequelize from "./pb-sequelize";
12
+ import PhoneUser from "./phone-user";
13
+ import ContentLike from "./content-like";
14
+
15
+ type NotificationType =
16
+ | "unlock_message"
17
+ | "follow"
18
+ | "like"
19
+ | "tip"
20
+ | "subscription"
21
+ | "content";
22
+
23
+ // order of InferAttributes & InferCreationAttributes is important.
24
+ class Notification extends Model<
25
+ InferAttributes<Notification>,
26
+ InferCreationAttributes<Notification>
27
+ > {
28
+ // 'CreationOptional' is a special type that marks the field as optional
29
+ // when creating an instance of the model (such as using Model.create()).
30
+ declare id: CreationOptional<string>;
31
+ declare ownerId: string;
32
+ declare userId?: string;
33
+ declare isRead?: boolean;
34
+ declare type: NotificationType;
35
+ declare creditPaymentId?: string;
36
+ declare purchasedContentId?: string;
37
+ declare userFollowId?: string;
38
+ declare contentLikeId?: string;
39
+ declare messageId?: string;
40
+ declare createdAt: CreationOptional<Date>;
41
+ declare updatedAt: CreationOptional<Date>;
42
+ static readNotifications: (
43
+ ownerId: string,
44
+ type: NotificationType
45
+ ) => Promise<void>;
46
+ }
47
+
48
+ Notification.init(
49
+ {
50
+ id: {
51
+ type: DataTypes.BIGINT,
52
+ defaultValue: fn("next_id"),
53
+ allowNull: false,
54
+ primaryKey: true,
55
+ },
56
+ ownerId: {
57
+ type: DataTypes.BIGINT,
58
+ field: "owner_id",
59
+ allowNull: false,
60
+ },
61
+ userId: {
62
+ type: DataTypes.BIGINT,
63
+ field: "user_id",
64
+ allowNull: false,
65
+ },
66
+ isRead: {
67
+ field: "is_read",
68
+ type: DataTypes.BOOLEAN,
69
+ defaultValue: false,
70
+ },
71
+ type: {
72
+ field: "type",
73
+ type: DataTypes.STRING,
74
+ },
75
+ creditPaymentId: {
76
+ field: "credit_payment_id",
77
+ type: DataTypes.BIGINT,
78
+ },
79
+ purchasedContentId: {
80
+ field: "purchased_content_id",
81
+ type: DataTypes.BIGINT,
82
+ },
83
+ userFollowId: {
84
+ field: "user_follow_id",
85
+ type: DataTypes.BIGINT,
86
+ },
87
+ contentLikeId: {
88
+ field: "content_like_id",
89
+ type: DataTypes.BIGINT,
90
+ },
91
+ messageId: {
92
+ field: "messageId",
93
+ type: DataTypes.BIGINT,
94
+ },
95
+ createdAt: DataTypes.DATE,
96
+ updatedAt: DataTypes.DATE,
97
+ },
98
+ {
99
+ tableName: "notifications",
100
+ sequelize,
101
+ }
102
+ );
103
+
104
+ /*
105
+ ====================================================================
106
+ Class functions
107
+ ====================================================================
108
+ */
109
+
110
+ Notification.readNotifications = async (
111
+ ownerId: string,
112
+ type: NotificationType
113
+ ) => {
114
+ await sequelize.query(
115
+ `UPDATE notifications SET is_read=true WHERE owner_id=${ownerId} AND type=${type}`
116
+ );
117
+ };
118
+
119
+ Notification.hasOne(PhoneUser, {
120
+ foreignKey: "id",
121
+ sourceKey: "userId",
122
+ constraints: false,
123
+ });
124
+ Notification.hasOne(ContentLike, {
125
+ foreignKey: "id",
126
+ sourceKey: "contentLikeId",
127
+ constraints: false,
128
+ });
129
+
130
+ export default Notification;
@@ -0,0 +1,25 @@
1
+ /* global process */
2
+ /* eslint-disable */
3
+ import dotenv = require("dotenv");
4
+ dotenv.config();
5
+ /* eslint-enable */
6
+
7
+ import { Sequelize } from "sequelize";
8
+
9
+ /**
10
+ * To prevent accidental connection with production while running test cases
11
+ */
12
+ const dbUrl =
13
+ process.env.ENVIRONMENT === "test"
14
+ ? process.env.TESTING_DATABASE_URL
15
+ : process.env.DATABASE_URL;
16
+ export default new Sequelize(dbUrl!, {
17
+ logging: false,
18
+ minifyAliases: true,
19
+ dialectOptions: {
20
+ ssl: {
21
+ require: true,
22
+ rejectUnauthorized: false, // <<<<<<< YOU NEED THIS
23
+ },
24
+ },
25
+ });
@@ -0,0 +1,166 @@
1
+ import {
2
+ Model,
3
+ InferAttributes,
4
+ InferCreationAttributes,
5
+ CreationOptional,
6
+ DataTypes,
7
+ fn,
8
+ } from "sequelize";
9
+
10
+ import sequelize from "./pb-sequelize";
11
+ import PhoneUser from "./phone-user";
12
+
13
+ // order of InferAttributes & InferCreationAttributes is important.
14
+ class PhoneChatParticipant extends Model<
15
+ InferAttributes<PhoneChatParticipant>,
16
+ InferCreationAttributes<PhoneChatParticipant>
17
+ > {
18
+ // 'CreationOptional' is a special type that marks the field as optional
19
+ // when creating an instance of the model (such as using Model.create()).
20
+ declare id: CreationOptional<string>;
21
+ declare chatId: string;
22
+ declare userId: string;
23
+ declare sentMessageCount?: number;
24
+ declare messageCountToBill?: number;
25
+ declare totalCallLength?: number;
26
+ declare callLengthToBill?: number;
27
+ declare totalTipAmount?: number;
28
+ declare tipAmountToBill?: number;
29
+ declare isTipping?: boolean;
30
+ declare isActive?: boolean;
31
+ declare stripePaymentIntentId?: string;
32
+ declare createdAt: CreationOptional<Date>;
33
+ declare updatedAt: CreationOptional<Date>;
34
+ static getAllByChatId: (chatId: string) => Promise<PhoneChatParticipant[]>;
35
+ static getByChatIdAndUserId: (
36
+ chatId: string,
37
+ userId: string
38
+ ) => Promise<PhoneChatParticipant | null>;
39
+ }
40
+
41
+ PhoneChatParticipant.init(
42
+ {
43
+ id: {
44
+ type: DataTypes.BIGINT,
45
+ primaryKey: true,
46
+ allowNull: false,
47
+ defaultValue: sequelize.fn("next_id"),
48
+ },
49
+ chatId: {
50
+ type: DataTypes.BIGINT,
51
+ allowNull: false,
52
+ field: "chat_id",
53
+ },
54
+ userId: {
55
+ type: DataTypes.BIGINT,
56
+ allowNull: false,
57
+ field: "user_id",
58
+ },
59
+ sentMessageCount: {
60
+ type: DataTypes.INTEGER,
61
+ allowNull: false,
62
+ field: "sent_message_count",
63
+ defaultValue: 0,
64
+ },
65
+ messageCountToBill: {
66
+ type: DataTypes.INTEGER,
67
+ allowNull: false,
68
+ field: "message_count_to_bill",
69
+ defaultValue: 0,
70
+ },
71
+ totalCallLength: {
72
+ type: DataTypes.INTEGER,
73
+ allowNull: false,
74
+ field: "total_call_length",
75
+ defaultValue: 0,
76
+ },
77
+ callLengthToBill: {
78
+ type: DataTypes.INTEGER,
79
+ allowNull: false,
80
+ field: "call_length_to_bill",
81
+ defaultValue: 0,
82
+ },
83
+ totalTipAmount: {
84
+ type: DataTypes.INTEGER,
85
+ allowNull: false,
86
+ field: "total_tip_amount",
87
+ defaultValue: 0,
88
+ },
89
+ tipAmountToBill: {
90
+ type: DataTypes.INTEGER,
91
+ allowNull: false,
92
+ field: "tip_amount_to_bill",
93
+ defaultValue: 0,
94
+ },
95
+ isTipping: {
96
+ type: DataTypes.BOOLEAN,
97
+ allowNull: false,
98
+ field: "is_tipping",
99
+ defaultValue: false,
100
+ },
101
+ isActive: {
102
+ type: DataTypes.BOOLEAN,
103
+ allowNull: false,
104
+ field: "is_active",
105
+ defaultValue: true,
106
+ },
107
+ stripePaymentIntentId: {
108
+ type: DataTypes.STRING,
109
+ field: "stripe_payment_intent_id",
110
+ },
111
+ createdAt: DataTypes.DATE,
112
+ updatedAt: DataTypes.DATE,
113
+ },
114
+ {
115
+ // Other model options go here
116
+ tableName: "chat_participants",
117
+ sequelize,
118
+ }
119
+ );
120
+
121
+ /*
122
+ ====================================================================
123
+ Class functions
124
+ ====================================================================
125
+ */
126
+
127
+ PhoneChatParticipant.getAllByChatId = async (chatId: string) => {
128
+ return await PhoneChatParticipant.findAll({
129
+ where: {
130
+ chatId,
131
+ isActive: true,
132
+ },
133
+ include: [
134
+ {
135
+ model: PhoneUser,
136
+ required: true,
137
+ },
138
+ ],
139
+ });
140
+ };
141
+
142
+ PhoneChatParticipant.getByChatIdAndUserId = async (
143
+ chatId: string,
144
+ userId: string
145
+ ) => {
146
+ return await PhoneChatParticipant.findOne({
147
+ where: {
148
+ chatId,
149
+ userId,
150
+ isActive: true,
151
+ },
152
+ });
153
+ };
154
+
155
+ PhoneUser.hasMany(PhoneChatParticipant, {
156
+ foreignKey: "user_id",
157
+ onDelete: "NO ACTION",
158
+ constraints: false,
159
+ });
160
+ PhoneChatParticipant.belongsTo(PhoneUser, {
161
+ foreignKey: "user_id",
162
+ onDelete: "NO ACTION",
163
+ constraints: false,
164
+ });
165
+
166
+ export default PhoneChatParticipant;
@@ -0,0 +1,185 @@
1
+ import {
2
+ Model,
3
+ InferAttributes,
4
+ InferCreationAttributes,
5
+ CreationOptional,
6
+ DataTypes,
7
+ fn,
8
+ } from "sequelize";
9
+
10
+ import sequelize from "./pb-sequelize";
11
+ import PhoneChatParticipant from "./phone-chat-participation";
12
+ import PhoneOwner from "./phone-owner";
13
+ import PhoneUser from "./phone-user";
14
+ import TwilioPhone from "./twilio-phone";
15
+
16
+ // order of InferAttributes & InferCreationAttributes is important.
17
+ class PhoneChat extends Model<
18
+ InferAttributes<PhoneChat>,
19
+ InferCreationAttributes<PhoneChat>
20
+ > {
21
+ // 'CreationOptional' is a special type that marks the field as optional
22
+ // when creating an instance of the model (such as using Model.create()).
23
+ declare id: CreationOptional<string>;
24
+ declare twilioPhoneId: string;
25
+ declare ownerId: string;
26
+ declare status?: string;
27
+ declare chatRateInCents?: number;
28
+ declare audioRateInCents?: number;
29
+ declare createdAt: CreationOptional<Date>;
30
+ declare updatedAt: CreationOptional<Date>;
31
+ static getParticipationByUserIdAndOwnerId: (
32
+ userId: string,
33
+ ownerId: string
34
+ ) => Promise<PhoneChat>;
35
+ static createChatForUserAndOwner: (
36
+ user: PhoneUser,
37
+ owner: PhoneOwner
38
+ ) => Promise<any>;
39
+ }
40
+
41
+ PhoneChat.init(
42
+ {
43
+ id: {
44
+ type: DataTypes.BIGINT,
45
+ primaryKey: true,
46
+ allowNull: false,
47
+ defaultValue: sequelize.fn("next_id"),
48
+ },
49
+ twilioPhoneId: {
50
+ type: DataTypes.BIGINT,
51
+ allowNull: false,
52
+ field: "twilio_phone_id",
53
+ },
54
+ ownerId: {
55
+ type: DataTypes.BIGINT,
56
+ allowNull: false,
57
+ field: "owner_id",
58
+ },
59
+ chatRateInCents: {
60
+ type: DataTypes.INTEGER,
61
+ field: "chat_rate_in_cents",
62
+ },
63
+ audioRateInCents: {
64
+ type: DataTypes.INTEGER,
65
+ field: "audio_rate_in_cents",
66
+ },
67
+ status: {
68
+ type: DataTypes.STRING,
69
+ field: "status",
70
+ },
71
+ createdAt: DataTypes.DATE,
72
+ updatedAt: DataTypes.DATE,
73
+ },
74
+ {
75
+ // Other model options go here
76
+ tableName: "chats",
77
+ sequelize,
78
+ }
79
+ );
80
+
81
+ /*
82
+ ====================================================================
83
+ Class functions
84
+ ====================================================================
85
+ */
86
+
87
+ PhoneChat.getParticipationByUserIdAndOwnerId = async (
88
+ userId: string,
89
+ ownerId: string
90
+ ) => {
91
+ console.log(userId, ownerId);
92
+ let response = await PhoneChat.findAll({
93
+ where: {
94
+ ownerId,
95
+ },
96
+ include: [
97
+ {
98
+ model: PhoneChatParticipant,
99
+ required: true,
100
+ where: { userId, isActive: true },
101
+ },
102
+ ],
103
+ });
104
+ return response && response[0];
105
+ };
106
+
107
+ PhoneChat.createChatForUserAndOwner = async (
108
+ user: PhoneUser,
109
+ owner: PhoneOwner
110
+ ) => {
111
+ let phone;
112
+ let chat = await PhoneChat.getParticipationByUserIdAndOwnerId(
113
+ user.id,
114
+ owner.id
115
+ );
116
+
117
+ if (chat) {
118
+ phone = await TwilioPhone.getById(chat.twilioPhoneId);
119
+ } else {
120
+ phone = await TwilioPhone.getAvailableChatPhone(user.id, owner.id);
121
+ if (!phone) {
122
+ throw Error(
123
+ "There are no available phone numbers for this host or user."
124
+ );
125
+ }
126
+ chat = await PhoneChat.create({
127
+ ownerId: owner.id,
128
+ chatRateInCents: owner.defaultChatRateInCents,
129
+ audioRateInCents: owner.defaultAudioRateInCents,
130
+ twilioPhoneId: phone.id,
131
+ });
132
+
133
+ let chatParticipation = await PhoneChatParticipant.create({
134
+ chatId: chat.id,
135
+ userId: user.id,
136
+ });
137
+
138
+ await TwilioPhone.sendMessageToPhone(
139
+ phone,
140
+ owner.phone!,
141
+ `Woo! ${
142
+ user.name || "Someone"
143
+ } wants to message you! Start chatting with them 1:1 below! 💬\n\nFans can respond with TIP to send you tips\n\nReply with LOCK to send a locked image or link\n\nWatch this video to learn how to use Paychat SMS: https://www.youtube.com/watch?v=1JLhgFxyhdI`
144
+ );
145
+ }
146
+
147
+ let contactCardUrl;
148
+ // try {
149
+ // contactCardUrl = await ContactWrapper.createOwnerChatContactCard(chat, owner, phone, host);
150
+ // chat.contactCardUrl = contactCardUrl;
151
+ // } catch(err) {
152
+ // console.log("Failed to attach contact card");
153
+ // console.log(err);
154
+ // }
155
+
156
+ if (owner.chatMessage) {
157
+ await TwilioPhone.sendMessageToPhone(
158
+ phone!,
159
+ user.phone!,
160
+ owner.chatMessage,
161
+ owner.chatImageUrl!
162
+ );
163
+ }
164
+ await TwilioPhone.sendMessageToPhone(
165
+ phone!,
166
+ user.phone!,
167
+ `Hey, this is ${owner.name}! We can chat over this phone number now. Add this as my contact in your phone! 🙂\n\nReply with TIP if you ever want to send me something extra.`,
168
+ undefined
169
+ );
170
+
171
+ return chat;
172
+ };
173
+
174
+ PhoneChat.hasMany(PhoneChatParticipant, {
175
+ foreignKey: "chat_id",
176
+ onDelete: "NO ACTION",
177
+ constraints: false,
178
+ });
179
+ PhoneChatParticipant.belongsTo(PhoneChat, {
180
+ foreignKey: "chat_id",
181
+ onDelete: "NO ACTION",
182
+ constraints: false,
183
+ });
184
+
185
+ export default PhoneChat;