diff --git a/app/controllers/api/v1/accounts/channels/twilio_channels_controller.rb b/app/controllers/api/v1/accounts/channels/twilio_channels_controller.rb
index e6e5b63c3..d2d51baef 100644
--- a/app/controllers/api/v1/accounts/channels/twilio_channels_controller.rb
+++ b/app/controllers/api/v1/accounts/channels/twilio_channels_controller.rb
@@ -18,7 +18,11 @@ class Api::V1::Accounts::Channels::TwilioChannelsController < Api::V1::Accounts:
end
def authenticate_twilio
- client = Twilio::REST::Client.new(permitted_params[:account_sid], permitted_params[:auth_token])
+ client = if permitted_params[:api_key_sid].present?
+ Twilio::REST::Client.new(permitted_params[:api_key_sid], permitted_params[:auth_token], permitted_params[:account_sid])
+ else
+ Twilio::REST::Client.new(permitted_params[:account_sid], permitted_params[:auth_token])
+ end
client.messages.list(limit: 1)
end
@@ -40,6 +44,7 @@ class Api::V1::Accounts::Channels::TwilioChannelsController < Api::V1::Accounts:
@twilio_channel = Current.account.twilio_sms.create!(
account_sid: permitted_params[:account_sid],
auth_token: permitted_params[:auth_token],
+ api_key_sid: permitted_params[:api_key_sid],
messaging_service_sid: permitted_params[:messaging_service_sid].presence,
phone_number: phone_number,
medium: medium
@@ -52,7 +57,7 @@ class Api::V1::Accounts::Channels::TwilioChannelsController < Api::V1::Accounts:
def permitted_params
params.require(:twilio_channel).permit(
- :account_id, :messaging_service_sid, :phone_number, :account_sid, :auth_token, :name, :medium
+ :account_id, :messaging_service_sid, :phone_number, :account_sid, :auth_token, :name, :medium, :api_key_sid
)
end
end
diff --git a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json
index f77124121..99ac944a8 100644
--- a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json
+++ b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json
@@ -111,6 +111,17 @@
"PLACEHOLDER": "Please enter your Twilio Account SID",
"ERROR": "This field is required"
},
+ "API_KEY": {
+ "USE_API_KEY": "Use API Key Authentication",
+ "LABEL": "API Key SID",
+ "PLACEHOLDER": "Please enter your API Key SID",
+ "ERROR": "This field is required"
+ },
+ "API_KEY_SECRET": {
+ "LABEL": "API Key Secret",
+ "PLACEHOLDER": "Please enter your API Key Secret",
+ "ERROR": "This field is required"
+ },
"MESSAGING_SERVICE_SID": {
"LABEL": "Messaging Service SID",
"PLACEHOLDER": "Please enter your Twilio Messaging Service SID",
diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Twilio.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Twilio.vue
index 17596f8bc..1dfd6dfe0 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Twilio.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Twilio.vue
@@ -81,18 +81,45 @@
}}
+
+
+
+
+
+
@@ -123,11 +150,13 @@ export default {
data() {
return {
accountSID: '',
+ apiKeySID: '',
authToken: '',
medium: this.type,
channelName: '',
messagingServiceSID: '',
useMessagingService: false,
+ useAPIKey: false,
phoneNumber: '',
};
},
@@ -135,26 +164,39 @@ export default {
...mapGetters({
uiFlags: 'inboxes/getUIFlags',
}),
+ authTokeni18nKey() {
+ return this.useAPIKey ? 'API_KEY_SECRET' : 'AUTH_TOKEN';
+ },
},
validations() {
- if (this.phoneNumber) {
- return {
- channelName: { required },
- messagingServiceSID: {},
- phoneNumber: { required, isPhoneE164OrEmpty },
- authToken: { required },
- accountSID: { required },
- medium: { required },
- };
- }
- return {
+ let validations = {
channelName: { required },
- messagingServiceSID: { required },
- phoneNumber: {},
+
authToken: { required },
accountSID: { required },
medium: { required },
};
+ if (this.phoneNumber) {
+ validations = {
+ ...validations,
+ phoneNumber: { required, isPhoneE164OrEmpty },
+ messagingServiceSID: {},
+ };
+ } else {
+ validations = {
+ ...validations,
+ messagingServiceSID: { required },
+ phoneNumber: {},
+ };
+ }
+
+ if (this.useAPIKey) {
+ validations = {
+ ...validations,
+ apiKeySID: { required },
+ };
+ }
+ return validations;
},
methods: {
async createChannel() {
@@ -171,6 +213,7 @@ export default {
name: this.channelName,
medium: this.medium,
account_sid: this.accountSID,
+ api_key_sid: this.apiKeySID,
auth_token: this.authToken,
messaging_service_sid: this.messagingServiceSID,
phone_number: this.messagingServiceSID
diff --git a/app/models/channel/twilio_sms.rb b/app/models/channel/twilio_sms.rb
index d6c9177fb..05ca9a567 100644
--- a/app/models/channel/twilio_sms.rb
+++ b/app/models/channel/twilio_sms.rb
@@ -4,6 +4,7 @@
#
# id :bigint not null, primary key
# account_sid :string not null
+# api_key_sid :string
# auth_token :string not null
# medium :integer default("sms")
# messaging_service_sid :string
@@ -25,6 +26,7 @@ class Channel::TwilioSms < ApplicationRecord
self.table_name = 'channel_twilio_sms'
validates :account_sid, presence: true
+ # The same parameter is used to store api_key_secret if api_key authentication is opted
validates :auth_token, presence: true
# Must have _one_ of messaging_service_sid _or_ phone_number, and messaging_service_sid is preferred
@@ -51,7 +53,11 @@ class Channel::TwilioSms < ApplicationRecord
private
def client
- ::Twilio::REST::Client.new(account_sid, auth_token)
+ if api_key_sid.present?
+ Twilio::REST::Client.new(api_key_sid, auth_token, account_sid)
+ else
+ Twilio::REST::Client.new(account_sid, auth_token)
+ end
end
def send_message_from
diff --git a/db/migrate/20230714054138_add_api_key_sid_to_twilio_sms.rb b/db/migrate/20230714054138_add_api_key_sid_to_twilio_sms.rb
new file mode 100644
index 000000000..532d036e0
--- /dev/null
+++ b/db/migrate/20230714054138_add_api_key_sid_to_twilio_sms.rb
@@ -0,0 +1,5 @@
+class AddApiKeySidToTwilioSms < ActiveRecord::Migration[7.0]
+ def change
+ add_column :channel_twilio_sms, :api_key_sid, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index baa433702..ab3986e15 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2023_07_06_090122) do
+ActiveRecord::Schema[7.0].define(version: 2023_07_14_054138) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
enable_extension "pg_trgm"
@@ -330,6 +330,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_07_06_090122) do
t.datetime "updated_at", null: false
t.integer "medium", default: 0
t.string "messaging_service_sid"
+ t.string "api_key_sid"
t.index ["account_sid", "phone_number"], name: "index_channel_twilio_sms_on_account_sid_and_phone_number", unique: true
t.index ["messaging_service_sid"], name: "index_channel_twilio_sms_on_messaging_service_sid", unique: true
t.index ["phone_number"], name: "index_channel_twilio_sms_on_phone_number", unique: true