kapso-client-ruby 1.0.1 → 1.0.2
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +81 -81
- data/CHANGELOG.md +262 -91
- data/Gemfile +20 -20
- data/RAILS_INTEGRATION.md +477 -477
- data/README.md +1053 -752
- data/Rakefile +40 -40
- data/TEMPLATE_TOOLS_GUIDE.md +120 -120
- data/WHATSAPP_24_HOUR_GUIDE.md +133 -133
- data/examples/advanced_features.rb +352 -349
- data/examples/advanced_messaging.rb +241 -0
- data/examples/basic_messaging.rb +139 -136
- data/examples/enhanced_interactive.rb +400 -0
- data/examples/flows_usage.rb +307 -0
- data/examples/interactive_messages.rb +343 -0
- data/examples/media_management.rb +256 -253
- data/examples/rails/jobs.rb +387 -387
- data/examples/rails/models.rb +239 -239
- data/examples/rails/notifications_controller.rb +226 -226
- data/examples/template_management.rb +393 -390
- data/kapso-ruby-logo.jpg +0 -0
- data/lib/kapso_client_ruby/client.rb +321 -316
- data/lib/kapso_client_ruby/errors.rb +348 -329
- data/lib/kapso_client_ruby/rails/generators/install_generator.rb +75 -75
- data/lib/kapso_client_ruby/rails/generators/templates/env.erb +20 -20
- data/lib/kapso_client_ruby/rails/generators/templates/initializer.rb.erb +32 -32
- data/lib/kapso_client_ruby/rails/generators/templates/message_service.rb.erb +137 -137
- data/lib/kapso_client_ruby/rails/generators/templates/webhook_controller.rb.erb +61 -61
- data/lib/kapso_client_ruby/rails/railtie.rb +54 -54
- data/lib/kapso_client_ruby/rails/service.rb +188 -188
- data/lib/kapso_client_ruby/rails/tasks.rake +166 -166
- data/lib/kapso_client_ruby/resources/calls.rb +172 -172
- data/lib/kapso_client_ruby/resources/contacts.rb +190 -190
- data/lib/kapso_client_ruby/resources/conversations.rb +103 -103
- data/lib/kapso_client_ruby/resources/flows.rb +382 -0
- data/lib/kapso_client_ruby/resources/media.rb +205 -205
- data/lib/kapso_client_ruby/resources/messages.rb +760 -380
- data/lib/kapso_client_ruby/resources/phone_numbers.rb +85 -85
- data/lib/kapso_client_ruby/resources/templates.rb +283 -283
- data/lib/kapso_client_ruby/types.rb +348 -262
- data/lib/kapso_client_ruby/version.rb +5 -5
- data/lib/kapso_client_ruby.rb +75 -74
- data/scripts/.env.example +17 -17
- data/scripts/kapso_template_finder.rb +91 -91
- data/scripts/sdk_setup.rb +404 -404
- data/scripts/test.rb +60 -60
- metadata +12 -3
data/examples/rails/models.rb
CHANGED
|
@@ -1,240 +1,240 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Example Rails model integration showing WhatsApp messaging hooks
|
|
4
|
-
class User < ApplicationRecord
|
|
5
|
-
has_many :orders, dependent: :destroy
|
|
6
|
-
has_many :whatsapp_messages, dependent: :destroy
|
|
7
|
-
|
|
8
|
-
# Validations
|
|
9
|
-
validates :email, presence: true, uniqueness: true
|
|
10
|
-
validates :phone_number, format: { with: /\A\+\d{10,15}\z/, message: "must be in E.164 format" }, allow_blank: true
|
|
11
|
-
validates :preferred_language, inclusion: { in: %w[en es fr], message: "must be a supported language" }
|
|
12
|
-
|
|
13
|
-
# Callbacks for WhatsApp integration
|
|
14
|
-
after_create :send_welcome_message, if: :phone_number?
|
|
15
|
-
after_update :send_phone_verification, if: :phone_number_changed?
|
|
16
|
-
|
|
17
|
-
# Scopes
|
|
18
|
-
scope :with_phone_number, -> { where.not(phone_number: nil) }
|
|
19
|
-
scope :opted_in_for_notifications, -> { where(notifications_enabled: true) }
|
|
20
|
-
|
|
21
|
-
# Instance methods
|
|
22
|
-
|
|
23
|
-
def send_welcome_message
|
|
24
|
-
SendWelcomeMessageJob.perform_later(self)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def send_phone_verification
|
|
28
|
-
return unless phone_number.present?
|
|
29
|
-
|
|
30
|
-
SendPhoneVerificationJob.perform_later(self)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def send_notification(message, type: 'general')
|
|
34
|
-
return unless phone_number.present? && notifications_enabled?
|
|
35
|
-
|
|
36
|
-
SendNotificationJob.perform_later(self, message, type)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def send_order_confirmation(order)
|
|
40
|
-
return unless phone_number.present?
|
|
41
|
-
|
|
42
|
-
SendOrderConfirmationJob.perform_later(self, order)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Format phone number for WhatsApp (ensure E.164 format)
|
|
46
|
-
def formatted_phone_number
|
|
47
|
-
return nil unless phone_number.present?
|
|
48
|
-
|
|
49
|
-
# Remove any non-digit characters except the leading +
|
|
50
|
-
cleaned = phone_number.gsub(/[^\d+]/, '')
|
|
51
|
-
|
|
52
|
-
# Ensure it starts with +
|
|
53
|
-
cleaned.start_with?('+') ? cleaned : "+#{cleaned}"
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Check if user can receive WhatsApp messages
|
|
57
|
-
def can_receive_whatsapp?
|
|
58
|
-
phone_number.present? && notifications_enabled?
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# Get recent WhatsApp messages
|
|
62
|
-
def recent_whatsapp_messages(limit = 10)
|
|
63
|
-
whatsapp_messages.order(created_at: :desc).limit(limit)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Check if user has received a specific message type recently
|
|
67
|
-
def received_message_type_recently?(message_type, within: 24.hours)
|
|
68
|
-
whatsapp_messages
|
|
69
|
-
.where(message_type: message_type)
|
|
70
|
-
.where('created_at > ?', within.ago)
|
|
71
|
-
.exists?
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
private
|
|
75
|
-
|
|
76
|
-
def phone_number_changed?
|
|
77
|
-
saved_change_to_phone_number? && phone_number.present?
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# Example Order model with WhatsApp integration
|
|
82
|
-
class Order < ApplicationRecord
|
|
83
|
-
belongs_to :user
|
|
84
|
-
has_many :order_items, dependent: :destroy
|
|
85
|
-
has_many :whatsapp_messages, through: :user
|
|
86
|
-
|
|
87
|
-
# Order statuses
|
|
88
|
-
enum status: {
|
|
89
|
-
pending: 0,
|
|
90
|
-
confirmed: 1,
|
|
91
|
-
processing: 2,
|
|
92
|
-
shipped: 3,
|
|
93
|
-
delivered: 4,
|
|
94
|
-
cancelled: 5
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
# Callbacks for WhatsApp notifications
|
|
98
|
-
after_create :send_order_confirmation
|
|
99
|
-
after_update :send_status_update, if: :saved_change_to_status?
|
|
100
|
-
|
|
101
|
-
# Instance methods
|
|
102
|
-
|
|
103
|
-
def send_order_confirmation
|
|
104
|
-
return unless user.can_receive_whatsapp?
|
|
105
|
-
|
|
106
|
-
SendOrderConfirmationJob.perform_later(user, self)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def send_status_update
|
|
110
|
-
return unless user.can_receive_whatsapp?
|
|
111
|
-
|
|
112
|
-
# Don't send updates for pending status (already sent confirmation)
|
|
113
|
-
return if status == 'pending'
|
|
114
|
-
|
|
115
|
-
SendOrderStatusUpdateJob.perform_later(user, self)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def total_amount_in_cents
|
|
119
|
-
(total_amount * 100).to_i
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def formatted_total
|
|
123
|
-
"$#{'%.2f' % total_amount}"
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def estimated_delivery_date
|
|
127
|
-
return nil unless shipped?
|
|
128
|
-
|
|
129
|
-
shipped_at + 3.days # Example: 3 days for delivery
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# Example WhatsAppMessage model for tracking sent messages
|
|
134
|
-
class WhatsappMessage < ApplicationRecord
|
|
135
|
-
belongs_to :user
|
|
136
|
-
belongs_to :messageable, polymorphic: true, optional: true # Could be Order, User, etc.
|
|
137
|
-
|
|
138
|
-
# Message types
|
|
139
|
-
enum message_type: {
|
|
140
|
-
welcome: 0,
|
|
141
|
-
order_confirmation: 1,
|
|
142
|
-
order_status_update: 2,
|
|
143
|
-
phone_verification: 3,
|
|
144
|
-
general_notification: 4,
|
|
145
|
-
marketing: 5,
|
|
146
|
-
support: 6
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
# Message status from WhatsApp API
|
|
150
|
-
enum status: {
|
|
151
|
-
sent: 0,
|
|
152
|
-
delivered: 1,
|
|
153
|
-
read: 2,
|
|
154
|
-
failed: 3
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
# Validations
|
|
158
|
-
validates :message_id, presence: true, uniqueness: true
|
|
159
|
-
validates :phone_number, presence: true
|
|
160
|
-
validates :message_type, presence: true
|
|
161
|
-
|
|
162
|
-
# Scopes
|
|
163
|
-
scope :recent, -> { order(created_at: :desc) }
|
|
164
|
-
scope :successful, -> { where(status: [:sent, :delivered, :read]) }
|
|
165
|
-
scope :failed, -> { where(status: :failed) }
|
|
166
|
-
|
|
167
|
-
# Class methods
|
|
168
|
-
|
|
169
|
-
def self.track_message(user:, message_id:, message_type:, phone_number:, messageable: nil)
|
|
170
|
-
create!(
|
|
171
|
-
user: user,
|
|
172
|
-
message_id: message_id,
|
|
173
|
-
message_type: message_type,
|
|
174
|
-
phone_number: phone_number,
|
|
175
|
-
messageable: messageable,
|
|
176
|
-
status: :sent,
|
|
177
|
-
sent_at: Time.current
|
|
178
|
-
)
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
def self.update_status_from_webhook(message_id, new_status, timestamp = nil)
|
|
182
|
-
message = find_by(message_id: message_id)
|
|
183
|
-
return unless message
|
|
184
|
-
|
|
185
|
-
status_mapping = {
|
|
186
|
-
'sent' => :sent,
|
|
187
|
-
'delivered' => :delivered,
|
|
188
|
-
'read' => :read,
|
|
189
|
-
'failed' => :failed
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
mapped_status = status_mapping[new_status.to_s.downcase]
|
|
193
|
-
return unless mapped_status
|
|
194
|
-
|
|
195
|
-
message.update!(
|
|
196
|
-
status: mapped_status,
|
|
197
|
-
status_updated_at: timestamp ? Time.at(timestamp) : Time.current
|
|
198
|
-
)
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
# Instance methods
|
|
202
|
-
|
|
203
|
-
def delivered?
|
|
204
|
-
%w[delivered read].include?(status)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def failed?
|
|
208
|
-
status == 'failed'
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
def delivery_time
|
|
212
|
-
return nil unless delivered? && sent_at.present? && status_updated_at.present?
|
|
213
|
-
|
|
214
|
-
status_updated_at - sent_at
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# Example migration for WhatsApp messages tracking
|
|
219
|
-
#
|
|
220
|
-
# class CreateWhatsappMessages < ActiveRecord::Migration[8.0]
|
|
221
|
-
# def change
|
|
222
|
-
# create_table :whatsapp_messages do |t|
|
|
223
|
-
# t.references :user, null: false, foreign_key: true
|
|
224
|
-
# t.references :messageable, polymorphic: true, null: true
|
|
225
|
-
# t.string :message_id, null: false, index: { unique: true }
|
|
226
|
-
# t.string :phone_number, null: false
|
|
227
|
-
# t.integer :message_type, null: false
|
|
228
|
-
# t.integer :status, default: 0
|
|
229
|
-
# t.datetime :sent_at
|
|
230
|
-
# t.datetime :status_updated_at
|
|
231
|
-
# t.text :error_message
|
|
232
|
-
# t.json :metadata # Store additional message data
|
|
233
|
-
#
|
|
234
|
-
# t.timestamps
|
|
235
|
-
# end
|
|
236
|
-
#
|
|
237
|
-
# add_index :whatsapp_messages, [:user_id, :message_type]
|
|
238
|
-
# add_index :whatsapp_messages, [:message_type, :status]
|
|
239
|
-
# end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Example Rails model integration showing WhatsApp messaging hooks
|
|
4
|
+
class User < ApplicationRecord
|
|
5
|
+
has_many :orders, dependent: :destroy
|
|
6
|
+
has_many :whatsapp_messages, dependent: :destroy
|
|
7
|
+
|
|
8
|
+
# Validations
|
|
9
|
+
validates :email, presence: true, uniqueness: true
|
|
10
|
+
validates :phone_number, format: { with: /\A\+\d{10,15}\z/, message: "must be in E.164 format" }, allow_blank: true
|
|
11
|
+
validates :preferred_language, inclusion: { in: %w[en es fr], message: "must be a supported language" }
|
|
12
|
+
|
|
13
|
+
# Callbacks for WhatsApp integration
|
|
14
|
+
after_create :send_welcome_message, if: :phone_number?
|
|
15
|
+
after_update :send_phone_verification, if: :phone_number_changed?
|
|
16
|
+
|
|
17
|
+
# Scopes
|
|
18
|
+
scope :with_phone_number, -> { where.not(phone_number: nil) }
|
|
19
|
+
scope :opted_in_for_notifications, -> { where(notifications_enabled: true) }
|
|
20
|
+
|
|
21
|
+
# Instance methods
|
|
22
|
+
|
|
23
|
+
def send_welcome_message
|
|
24
|
+
SendWelcomeMessageJob.perform_later(self)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def send_phone_verification
|
|
28
|
+
return unless phone_number.present?
|
|
29
|
+
|
|
30
|
+
SendPhoneVerificationJob.perform_later(self)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def send_notification(message, type: 'general')
|
|
34
|
+
return unless phone_number.present? && notifications_enabled?
|
|
35
|
+
|
|
36
|
+
SendNotificationJob.perform_later(self, message, type)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def send_order_confirmation(order)
|
|
40
|
+
return unless phone_number.present?
|
|
41
|
+
|
|
42
|
+
SendOrderConfirmationJob.perform_later(self, order)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Format phone number for WhatsApp (ensure E.164 format)
|
|
46
|
+
def formatted_phone_number
|
|
47
|
+
return nil unless phone_number.present?
|
|
48
|
+
|
|
49
|
+
# Remove any non-digit characters except the leading +
|
|
50
|
+
cleaned = phone_number.gsub(/[^\d+]/, '')
|
|
51
|
+
|
|
52
|
+
# Ensure it starts with +
|
|
53
|
+
cleaned.start_with?('+') ? cleaned : "+#{cleaned}"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Check if user can receive WhatsApp messages
|
|
57
|
+
def can_receive_whatsapp?
|
|
58
|
+
phone_number.present? && notifications_enabled?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Get recent WhatsApp messages
|
|
62
|
+
def recent_whatsapp_messages(limit = 10)
|
|
63
|
+
whatsapp_messages.order(created_at: :desc).limit(limit)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Check if user has received a specific message type recently
|
|
67
|
+
def received_message_type_recently?(message_type, within: 24.hours)
|
|
68
|
+
whatsapp_messages
|
|
69
|
+
.where(message_type: message_type)
|
|
70
|
+
.where('created_at > ?', within.ago)
|
|
71
|
+
.exists?
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def phone_number_changed?
|
|
77
|
+
saved_change_to_phone_number? && phone_number.present?
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Example Order model with WhatsApp integration
|
|
82
|
+
class Order < ApplicationRecord
|
|
83
|
+
belongs_to :user
|
|
84
|
+
has_many :order_items, dependent: :destroy
|
|
85
|
+
has_many :whatsapp_messages, through: :user
|
|
86
|
+
|
|
87
|
+
# Order statuses
|
|
88
|
+
enum status: {
|
|
89
|
+
pending: 0,
|
|
90
|
+
confirmed: 1,
|
|
91
|
+
processing: 2,
|
|
92
|
+
shipped: 3,
|
|
93
|
+
delivered: 4,
|
|
94
|
+
cancelled: 5
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# Callbacks for WhatsApp notifications
|
|
98
|
+
after_create :send_order_confirmation
|
|
99
|
+
after_update :send_status_update, if: :saved_change_to_status?
|
|
100
|
+
|
|
101
|
+
# Instance methods
|
|
102
|
+
|
|
103
|
+
def send_order_confirmation
|
|
104
|
+
return unless user.can_receive_whatsapp?
|
|
105
|
+
|
|
106
|
+
SendOrderConfirmationJob.perform_later(user, self)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def send_status_update
|
|
110
|
+
return unless user.can_receive_whatsapp?
|
|
111
|
+
|
|
112
|
+
# Don't send updates for pending status (already sent confirmation)
|
|
113
|
+
return if status == 'pending'
|
|
114
|
+
|
|
115
|
+
SendOrderStatusUpdateJob.perform_later(user, self)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def total_amount_in_cents
|
|
119
|
+
(total_amount * 100).to_i
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def formatted_total
|
|
123
|
+
"$#{'%.2f' % total_amount}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def estimated_delivery_date
|
|
127
|
+
return nil unless shipped?
|
|
128
|
+
|
|
129
|
+
shipped_at + 3.days # Example: 3 days for delivery
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Example WhatsAppMessage model for tracking sent messages
|
|
134
|
+
class WhatsappMessage < ApplicationRecord
|
|
135
|
+
belongs_to :user
|
|
136
|
+
belongs_to :messageable, polymorphic: true, optional: true # Could be Order, User, etc.
|
|
137
|
+
|
|
138
|
+
# Message types
|
|
139
|
+
enum message_type: {
|
|
140
|
+
welcome: 0,
|
|
141
|
+
order_confirmation: 1,
|
|
142
|
+
order_status_update: 2,
|
|
143
|
+
phone_verification: 3,
|
|
144
|
+
general_notification: 4,
|
|
145
|
+
marketing: 5,
|
|
146
|
+
support: 6
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# Message status from WhatsApp API
|
|
150
|
+
enum status: {
|
|
151
|
+
sent: 0,
|
|
152
|
+
delivered: 1,
|
|
153
|
+
read: 2,
|
|
154
|
+
failed: 3
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
# Validations
|
|
158
|
+
validates :message_id, presence: true, uniqueness: true
|
|
159
|
+
validates :phone_number, presence: true
|
|
160
|
+
validates :message_type, presence: true
|
|
161
|
+
|
|
162
|
+
# Scopes
|
|
163
|
+
scope :recent, -> { order(created_at: :desc) }
|
|
164
|
+
scope :successful, -> { where(status: [:sent, :delivered, :read]) }
|
|
165
|
+
scope :failed, -> { where(status: :failed) }
|
|
166
|
+
|
|
167
|
+
# Class methods
|
|
168
|
+
|
|
169
|
+
def self.track_message(user:, message_id:, message_type:, phone_number:, messageable: nil)
|
|
170
|
+
create!(
|
|
171
|
+
user: user,
|
|
172
|
+
message_id: message_id,
|
|
173
|
+
message_type: message_type,
|
|
174
|
+
phone_number: phone_number,
|
|
175
|
+
messageable: messageable,
|
|
176
|
+
status: :sent,
|
|
177
|
+
sent_at: Time.current
|
|
178
|
+
)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def self.update_status_from_webhook(message_id, new_status, timestamp = nil)
|
|
182
|
+
message = find_by(message_id: message_id)
|
|
183
|
+
return unless message
|
|
184
|
+
|
|
185
|
+
status_mapping = {
|
|
186
|
+
'sent' => :sent,
|
|
187
|
+
'delivered' => :delivered,
|
|
188
|
+
'read' => :read,
|
|
189
|
+
'failed' => :failed
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
mapped_status = status_mapping[new_status.to_s.downcase]
|
|
193
|
+
return unless mapped_status
|
|
194
|
+
|
|
195
|
+
message.update!(
|
|
196
|
+
status: mapped_status,
|
|
197
|
+
status_updated_at: timestamp ? Time.at(timestamp) : Time.current
|
|
198
|
+
)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Instance methods
|
|
202
|
+
|
|
203
|
+
def delivered?
|
|
204
|
+
%w[delivered read].include?(status)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def failed?
|
|
208
|
+
status == 'failed'
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def delivery_time
|
|
212
|
+
return nil unless delivered? && sent_at.present? && status_updated_at.present?
|
|
213
|
+
|
|
214
|
+
status_updated_at - sent_at
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Example migration for WhatsApp messages tracking
|
|
219
|
+
#
|
|
220
|
+
# class CreateWhatsappMessages < ActiveRecord::Migration[8.0]
|
|
221
|
+
# def change
|
|
222
|
+
# create_table :whatsapp_messages do |t|
|
|
223
|
+
# t.references :user, null: false, foreign_key: true
|
|
224
|
+
# t.references :messageable, polymorphic: true, null: true
|
|
225
|
+
# t.string :message_id, null: false, index: { unique: true }
|
|
226
|
+
# t.string :phone_number, null: false
|
|
227
|
+
# t.integer :message_type, null: false
|
|
228
|
+
# t.integer :status, default: 0
|
|
229
|
+
# t.datetime :sent_at
|
|
230
|
+
# t.datetime :status_updated_at
|
|
231
|
+
# t.text :error_message
|
|
232
|
+
# t.json :metadata # Store additional message data
|
|
233
|
+
#
|
|
234
|
+
# t.timestamps
|
|
235
|
+
# end
|
|
236
|
+
#
|
|
237
|
+
# add_index :whatsapp_messages, [:user_id, :message_type]
|
|
238
|
+
# add_index :whatsapp_messages, [:message_type, :status]
|
|
239
|
+
# end
|
|
240
240
|
# end
|