From 3e5ca9bca95df2c7ea5d1dc86e04f8a79724281f Mon Sep 17 00:00:00 2001
From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Date: Wed, 9 Jul 2025 09:23:20 +0530
Subject: [PATCH 1/6] fix: Widget message input resize issue (#11896)
---
app/javascript/shared/components/ResizableTextArea.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/javascript/shared/components/ResizableTextArea.vue b/app/javascript/shared/components/ResizableTextArea.vue
index 088753a23..4dda62cf9 100644
--- a/app/javascript/shared/components/ResizableTextArea.vue
+++ b/app/javascript/shared/components/ResizableTextArea.vue
@@ -69,7 +69,7 @@ export default {
},
},
watch: {
- value() {
+ modelValue() {
this.resizeTextarea();
// 🚨 watch triggers every time the value is changed, we cannot set this to focus then
// when this runs, it sets the cursor to the end of the body, ignoring the signature
From 5140deb6f682026594f1be847a643466829bbb96 Mon Sep 17 00:00:00 2001
From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Date: Wed, 9 Jul 2025 22:21:25 +0530
Subject: [PATCH 2/6] feat: Captain settings header component (#11912)
---
.../settings/SettingsHeader.story.vue | 28 +++++++++++++++++++
.../settings/SettingsHeader.vue | 19 +++++++++++++
2 files changed, 47 insertions(+)
create mode 100644 app/javascript/dashboard/components-next/captain/pageComponents/settings/SettingsHeader.story.vue
create mode 100644 app/javascript/dashboard/components-next/captain/pageComponents/settings/SettingsHeader.vue
diff --git a/app/javascript/dashboard/components-next/captain/pageComponents/settings/SettingsHeader.story.vue b/app/javascript/dashboard/components-next/captain/pageComponents/settings/SettingsHeader.story.vue
new file mode 100644
index 000000000..654e5ab16
--- /dev/null
+++ b/app/javascript/dashboard/components-next/captain/pageComponents/settings/SettingsHeader.story.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/components-next/captain/pageComponents/settings/SettingsHeader.vue b/app/javascript/dashboard/components-next/captain/pageComponents/settings/SettingsHeader.vue
new file mode 100644
index 000000000..dc6b7dda9
--- /dev/null
+++ b/app/javascript/dashboard/components-next/captain/pageComponents/settings/SettingsHeader.vue
@@ -0,0 +1,19 @@
+
+
+
+
+ {{ heading }}
+ {{ description }}
+
+
From 17500cc62d3fdf23c5ff1c8c238e866289de7dab Mon Sep 17 00:00:00 2001
From: Muhsin Keloth
Date: Thu, 10 Jul 2025 11:36:37 +0530
Subject: [PATCH 3/6] chore: Auto assign PR to author when PR opened (#11890)
- gh action to auto-assign PR to author when PR opened
---
.github/workflows/auto-assign-pr.yml | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 .github/workflows/auto-assign-pr.yml
diff --git a/.github/workflows/auto-assign-pr.yml b/.github/workflows/auto-assign-pr.yml
new file mode 100644
index 000000000..98df89707
--- /dev/null
+++ b/.github/workflows/auto-assign-pr.yml
@@ -0,0 +1,28 @@
+name: Auto-assign PR to Author
+
+on:
+ pull_request:
+ types: [opened]
+
+jobs:
+ auto-assign:
+ runs-on: ubuntu-latest
+ permissions:
+ pull-requests: write
+ steps:
+ - name: Auto-assign PR to author
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const { owner, repo } = context.repo;
+ const pull_number = context.payload.pull_request.number;
+ const author = context.payload.pull_request.user.login;
+
+ await github.rest.issues.addAssignees({
+ owner,
+ repo,
+ issue_number: pull_number,
+ assignees: [author]
+ });
+
+ console.log(`Assigned PR #${pull_number} to ${author}`);
\ No newline at end of file
From dd888f2cf016451d47ea7d7d9fb7845ab5e531e6 Mon Sep 17 00:00:00 2001
From: Tanmay Deep Sharma <32020192+tds-1@users.noreply.github.com>
Date: Thu, 10 Jul 2025 15:50:31 +0700
Subject: [PATCH 4/6] fix review changes
---
app/controllers/whatsapp/embedded_controller.rb | 3 +--
.../captain/pageComponents/document/DocumentForm.vue | 2 +-
app/services/whatsapp/embedded_signup_service.rb | 5 ++++-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/app/controllers/whatsapp/embedded_controller.rb b/app/controllers/whatsapp/embedded_controller.rb
index 625a11f3e..5589285d8 100644
--- a/app/controllers/whatsapp/embedded_controller.rb
+++ b/app/controllers/whatsapp/embedded_controller.rb
@@ -10,8 +10,7 @@ class Whatsapp::EmbeddedController < ApplicationController
render json: {
status: 'ready',
app_id: GlobalConfigService.load('WHATSAPP_APP_ID', ''),
- config_id: GlobalConfigService.load('WHATSAPP_CONFIGURATION_ID', ''),
- app_secret: GlobalConfigService.load('WHATSAPP_APP_SECRET', '')
+ config_id: GlobalConfigService.load('WHATSAPP_CONFIGURATION_ID', '')
}
end
diff --git a/app/javascript/dashboard/components-next/captain/pageComponents/document/DocumentForm.vue b/app/javascript/dashboard/components-next/captain/pageComponents/document/DocumentForm.vue
index d85ba8a06..dd0ff7962 100644
--- a/app/javascript/dashboard/components-next/captain/pageComponents/document/DocumentForm.vue
+++ b/app/javascript/dashboard/components-next/captain/pageComponents/document/DocumentForm.vue
@@ -19,7 +19,7 @@ const formState = {
};
const initialState = {
- name: '',
+ url: '',
assistantId: null,
};
diff --git a/app/services/whatsapp/embedded_signup_service.rb b/app/services/whatsapp/embedded_signup_service.rb
index 95ecfac2b..e7aa6a797 100644
--- a/app/services/whatsapp/embedded_signup_service.rb
+++ b/app/services/whatsapp/embedded_signup_service.rb
@@ -97,11 +97,14 @@ class Whatsapp::EmbeddedSignupService
end
def register_phone_number(phone_number_id, access_token)
+ # Generate a random 6-digit PIN
+ pin = SecureRandom.random_number(900_000) + 100_000
+
HTTParty.post(
"https://graph.facebook.com/#{whatsapp_api_version}/#{phone_number_id}/register",
{
headers: { 'Authorization' => "Bearer #{access_token}", 'Content-Type' => 'application/json' },
- body: { messaging_product: 'whatsapp', pin: '212834' }.to_json
+ body: { messaging_product: 'whatsapp', pin: pin.to_s }.to_json
}
)
end
From 07b1fc202e3d8ed4d1b73e9655053f9745271414 Mon Sep 17 00:00:00 2001
From: Tanmay Deep Sharma <32020192+tds-1@users.noreply.github.com>
Date: Thu, 10 Jul 2025 15:54:08 +0700
Subject: [PATCH 5/6] revert extra changes
---
.../captain/pageComponents/document/DocumentForm.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/javascript/dashboard/components-next/captain/pageComponents/document/DocumentForm.vue b/app/javascript/dashboard/components-next/captain/pageComponents/document/DocumentForm.vue
index dd0ff7962..d85ba8a06 100644
--- a/app/javascript/dashboard/components-next/captain/pageComponents/document/DocumentForm.vue
+++ b/app/javascript/dashboard/components-next/captain/pageComponents/document/DocumentForm.vue
@@ -19,7 +19,7 @@ const formState = {
};
const initialState = {
- url: '',
+ name: '',
assistantId: null,
};
From f8ad34a0b0af1a9b2647bc2fbc975b23e26af747 Mon Sep 17 00:00:00 2001
From: Tanmay Deep Sharma <32020192+tds-1@users.noreply.github.com>
Date: Thu, 10 Jul 2025 16:43:21 +0700
Subject: [PATCH 6/6] update test cases
---
.../whatsapp/embedded_controller_spec.rb | 3 +-
.../whatsapp/embedded_signup_service_spec.rb | 45 ++++++++++---------
2 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/spec/controllers/whatsapp/embedded_controller_spec.rb b/spec/controllers/whatsapp/embedded_controller_spec.rb
index 9d91a6488..fde3a1838 100644
--- a/spec/controllers/whatsapp/embedded_controller_spec.rb
+++ b/spec/controllers/whatsapp/embedded_controller_spec.rb
@@ -23,8 +23,7 @@ RSpec.describe 'WhatsApp Embedded API', type: :request do
expect(json_response).to include(
'status' => 'ready',
'app_id' => 'test_app_id',
- 'config_id' => 'test_config_id',
- 'app_secret' => 'test_app_secret'
+ 'config_id' => 'test_config_id'
)
end
end
diff --git a/spec/services/whatsapp/embedded_signup_service_spec.rb b/spec/services/whatsapp/embedded_signup_service_spec.rb
index 37269e5e1..7534407c9 100644
--- a/spec/services/whatsapp/embedded_signup_service_spec.rb
+++ b/spec/services/whatsapp/embedded_signup_service_spec.rb
@@ -2,15 +2,6 @@ require 'rails_helper'
describe Whatsapp::EmbeddedSignupService do
let(:account) { create(:account) }
- let(:code) { 'test_authorization_code' }
- let(:business_id) { 'test_business_id' }
- let(:waba_id) { 'test_waba_id' }
- let(:phone_number_id) { 'test_phone_number_id' }
- let(:access_token) { 'test_access_token' }
- let(:app_id) { 'test_app_id' }
- let(:app_secret) { 'test_app_secret' }
- let(:api_version) { 'v22.0' }
-
let(:service) do
described_class.new(
account: account,
@@ -20,9 +11,19 @@ describe Whatsapp::EmbeddedSignupService do
phone_number_id: phone_number_id
)
end
+ let(:code) { 'test_authorization_code' }
+ let(:business_id) { 'test_business_id' }
+ let(:waba_id) { 'test_waba_id' }
+ let(:phone_number_id) { 'test_phone_number_id' }
+ let(:access_token) { 'test_access_token' }
+ let(:app_id) { 'test_app_id' }
+ let(:app_secret) { 'test_app_secret' }
+ let(:api_version) { 'v22.0' }
+ let(:unique_phone_number) { "+123456789#{SecureRandom.hex(4)}" }
before do
- # Mock global configuration
+ # Clean up any existing WhatsApp channels before each test
+ Channel::Whatsapp.destroy_all
allow(GlobalConfigService).to receive(:load).with('WHATSAPP_APP_ID', '').and_return(app_id)
allow(GlobalConfigService).to receive(:load).with('WHATSAPP_APP_SECRET', '').and_return(app_secret)
allow(GlobalConfigService).to receive(:load).with('WHATSAPP_API_VERSION', 'v22.0').and_return(api_version)
@@ -64,7 +65,7 @@ describe Whatsapp::EmbeddedSignupService do
data: [
{
id: phone_number_id,
- display_phone_number: '1234567890',
+ display_phone_number: unique_phone_number.delete('+'),
verified_name: 'Test Business',
code_verification_status: 'VERIFIED'
}
@@ -123,7 +124,7 @@ describe Whatsapp::EmbeddedSignupService do
it 'successfully creates a new WhatsApp channel' do
expect { service.perform }.not_to raise_error
- channel = Channel::Whatsapp.find_by(account: account, phone_number: '+1234567890')
+ channel = Channel::Whatsapp.find_by(account: account, phone_number: unique_phone_number)
expect(channel).not_to be_nil
expect(channel.provider).to eq('whatsapp_cloud')
expect(channel.provider_config['api_key']).to eq(access_token)
@@ -135,20 +136,22 @@ describe Whatsapp::EmbeddedSignupService do
it 'creates an inbox for the channel' do
service.perform
- channel = Channel::Whatsapp.find_by(account: account, phone_number: '+1234567890')
+ channel = Channel::Whatsapp.find_by(account: account, phone_number: unique_phone_number)
inbox = Inbox.find_by(account: account, channel: channel)
expect(inbox).not_to be_nil
expect(inbox.name).to eq('Test Business WhatsApp')
end
it 'registers the phone number' do
+ # Mock SecureRandom to return a predictable value
+ allow(SecureRandom).to receive(:random_number).with(900_000).and_return(140_214)
service.perform
expect(WebMock).to have_requested(:post, "https://graph.facebook.com/#{api_version}/#{phone_number_id}/register")
.with(
body: {
messaging_product: 'whatsapp',
- pin: '212834'
+ pin: '240214'
}.to_json
)
end
@@ -156,7 +159,7 @@ describe Whatsapp::EmbeddedSignupService do
it 'sets up webhook subscription' do
service.perform
- channel = Channel::Whatsapp.find_by(account: account, phone_number: '+1234567890')
+ channel = Channel::Whatsapp.find_by(account: account, phone_number: unique_phone_number)
callback_url = "https://app.chatwoot.com/webhooks/whatsapp/#{channel.phone_number}"
expect(WebMock).to have_requested(:post, "https://graph.facebook.com/#{api_version}/#{waba_id}/subscribed_apps")
@@ -242,7 +245,7 @@ describe Whatsapp::EmbeddedSignupService do
data: [
{
id: phone_number_id,
- display_phone_number: '1234567890',
+ display_phone_number: unique_phone_number.delete('+'),
verified_name: 'Test Business',
code_verification_status: 'VERIFIED'
}
@@ -287,7 +290,7 @@ describe Whatsapp::EmbeddedSignupService do
)
# Create existing channel
- create(:channel_whatsapp, account: account, phone_number: '+1234567890')
+ create(:channel_whatsapp, account: account, phone_number: unique_phone_number)
end
it 'raises an error' do
@@ -333,7 +336,7 @@ describe Whatsapp::EmbeddedSignupService do
data: [
{
id: phone_number_id,
- display_phone_number: '1234567890',
+ display_phone_number: unique_phone_number.delete('+'),
verified_name: 'Test Business',
code_verification_status: 'VERIFIED'
}
@@ -415,7 +418,7 @@ describe Whatsapp::EmbeddedSignupService do
data: [
{
id: phone_number_id,
- display_phone_number: '1234567890',
+ display_phone_number: unique_phone_number.delete('+'),
verified_name: 'Test Business',
code_verification_status: 'VERIFIED'
}
@@ -524,7 +527,7 @@ describe Whatsapp::EmbeddedSignupService do
data: [
{
id: phone_number_id,
- display_phone_number: '1234567890',
+ display_phone_number: unique_phone_number.delete('+'),
verified_name: 'Test Business',
code_verification_status: 'VERIFIED'
}
@@ -538,7 +541,7 @@ describe Whatsapp::EmbeddedSignupService do
result = service.send(:fetch_phone_info_via_waba, waba_id, phone_number_id, access_token)
expect(result).to eq({
phone_number_id: phone_number_id,
- phone_number: '+1234567890',
+ phone_number: unique_phone_number,
verified: true,
business_name: 'Test Business'
})