+
diff --git a/app/javascript/dashboard/store/modules/reports.js b/app/javascript/dashboard/store/modules/reports.js
index c4068b54f..74da87d32 100644
--- a/app/javascript/dashboard/store/modules/reports.js
+++ b/app/javascript/dashboard/store/modules/reports.js
@@ -4,10 +4,7 @@ import Report from '../../api/reports';
import { downloadCsvFile, generateFileName } from '../../helper/downloadHelper';
import AnalyticsHelper from '../../helper/AnalyticsHelper';
import { REPORTS_EVENTS } from '../../helper/AnalyticsHelper/events';
-import {
- reconcileHeatmapData,
- clampDataBetweenTimeline,
-} from 'shared/helpers/ReportsDataHelper';
+import { clampDataBetweenTimeline } from 'shared/helpers/ReportsDataHelper';
const state = {
fetchingStatus: false,
@@ -114,11 +111,6 @@ export const actions = {
let { data } = heatmapData;
data = clampDataBetweenTimeline(data, reportObj.from, reportObj.to);
- data = reconcileHeatmapData(
- data,
- state.overview.accountConversationHeatmap
- );
-
commit(types.default.SET_HEATMAP_DATA, data);
commit(types.default.TOGGLE_HEATMAP_LOADING, false);
});
@@ -234,7 +226,7 @@ export const actions = {
});
},
downloadAccountConversationHeatmap(_, reportObj) {
- Report.getConversationTrafficCSV()
+ Report.getConversationTrafficCSV({ daysBefore: reportObj.daysBefore })
.then(response => {
downloadCsvFile(
generateFileName({
diff --git a/app/javascript/shared/helpers/IntegrationHelper.js b/app/javascript/shared/helpers/IntegrationHelper.js
index 442a78c66..8d8be822b 100644
--- a/app/javascript/shared/helpers/IntegrationHelper.js
+++ b/app/javascript/shared/helpers/IntegrationHelper.js
@@ -1,5 +1,5 @@
-const DYTE_MEETING_LINK = 'https://app.dyte.in/meeting/stage/';
+const DYTE_MEETING_LINK = 'https://app.dyte.io/v2/meeting';
-export const buildDyteURL = (roomName, dyteAuthToken) => {
- return `${DYTE_MEETING_LINK}${roomName}?authToken=${dyteAuthToken}&showSetupScreen=true&disableVideoBackground=true`;
+export const buildDyteURL = dyteAuthToken => {
+ return `${DYTE_MEETING_LINK}?authToken=${dyteAuthToken}&showSetupScreen=true&disableVideoBackground=true`;
};
diff --git a/app/javascript/widget/components/template/IntegrationCard.vue b/app/javascript/widget/components/template/IntegrationCard.vue
index 9a6cdb784..e8e3db5d2 100644
--- a/app/javascript/widget/components/template/IntegrationCard.vue
+++ b/app/javascript/widget/components/template/IntegrationCard.vue
@@ -14,10 +14,6 @@ export default {
type: Number,
required: true,
},
- meetingData: {
- type: Object,
- default: () => ({}),
- },
},
data() {
return { isLoading: false, dyteAuthToken: '', isSDKMounted: false };
@@ -28,18 +24,18 @@ export default {
return getContrastingTextColor(this.widgetColor);
},
meetingLink() {
- return buildDyteURL(this.meetingData.room_name, this.dyteAuthToken);
+ return buildDyteURL(this.dyteAuthToken);
},
},
methods: {
async joinTheCall() {
this.isLoading = true;
try {
- const { data: { authResponse: { authToken = '' } = {} } = {} } =
- await IntegrationAPIClient.addParticipantToDyteMeeting(
- this.messageId
- );
- this.dyteAuthToken = authToken;
+ const response = await IntegrationAPIClient.addParticipantToDyteMeeting(
+ this.messageId
+ );
+ const { data: { token } = {} } = response;
+ this.dyteAuthToken = token;
} catch (error) {
// Ignore Error for now
} finally {
diff --git a/lib/dyte.rb b/lib/dyte.rb
index e090dbc5e..96750da08 100644
--- a/lib/dyte.rb
+++ b/lib/dyte.rb
@@ -1,9 +1,10 @@
class Dyte
- BASE_URL = 'https://api.cluster.dyte.in/v1'.freeze
+ BASE_URL = 'https://api.dyte.io/v2'.freeze
API_KEY_HEADER = 'Authorization'.freeze
+ PRESET_NAME = 'group_call_host'.freeze
def initialize(organization_id, api_key)
- @api_key = api_key
+ @api_key = Base64.strict_encode64("#{organization_id}:#{api_key}")
@organization_id = organization_id
raise ArgumentError, 'Missing Credentials' if @api_key.blank? || @organization_id.blank?
@@ -11,15 +12,9 @@ class Dyte
def create_a_meeting(title)
payload = {
- 'title': title,
- 'authorization': {
- 'waitingRoom': false,
- 'closed': false
- },
- 'recordOnStart': false,
- 'liveStreamOnStart': false
+ 'title': title
}
- path = "organizations/#{@organization_id}/meeting"
+ path = 'meetings'
response = post(path, payload)
process_response(response)
end
@@ -28,13 +23,12 @@ class Dyte
raise ArgumentError, 'Missing information' if meeting_id.blank? || client_id.blank? || name.blank? || avatar_url.blank?
payload = {
- 'clientSpecificId': client_id.to_s,
- 'userDetails': {
- 'name': name,
- 'picture': avatar_url
- }
+ 'custom_participant_id': client_id.to_s,
+ 'name': name,
+ 'picture': avatar_url,
+ 'preset_name': PRESET_NAME
}
- path = "organizations/#{@organization_id}/meetings/#{meeting_id}/participant"
+ path = "meetings/#{meeting_id}/participants"
response = post(path, payload)
process_response(response)
end
@@ -50,7 +44,7 @@ class Dyte
def post(path, payload)
HTTParty.post(
"#{BASE_URL}/#{path}", {
- headers: { API_KEY_HEADER => @api_key, 'Content-Type' => 'application/json' },
+ headers: { API_KEY_HEADER => "Basic #{@api_key}", 'Content-Type' => 'application/json' },
body: payload.to_json
}
)
diff --git a/lib/integrations/dyte/processor_service.rb b/lib/integrations/dyte/processor_service.rb
index e33731738..dbe429776 100644
--- a/lib/integrations/dyte/processor_service.rb
+++ b/lib/integrations/dyte/processor_service.rb
@@ -7,7 +7,7 @@ class Integrations::Dyte::ProcessorService
return response if response[:error].present?
- meeting = response['meeting']
+ meeting = response
message = create_a_dyte_integration_message(meeting, title, agent)
message.push_event_data
end
@@ -29,8 +29,7 @@ class Integrations::Dyte::ProcessorService
content_attributes: {
type: 'dyte',
data: {
- meeting_id: meeting['id'],
- room_name: meeting['roomName']
+ meeting_id: meeting['id']
}
},
sender: agent
diff --git a/lib/integrations/slack/send_on_slack_service.rb b/lib/integrations/slack/send_on_slack_service.rb
index 20a65905c..c1454b869 100644
--- a/lib/integrations/slack/send_on_slack_service.rb
+++ b/lib/integrations/slack/send_on_slack_service.rb
@@ -119,12 +119,14 @@ class Integrations::Slack::SendOnSlackService < Base::SendOnChannelService
def upload_file
return unless message.attachments.first.with_attached_file?
- result = slack_client.files_upload({
- channels: hook.reference_id,
+ result = slack_client.files_upload_v2(
+ filename: message.attachments.first.file.filename,
+ content: message.attachments.first.file.download,
initial_comment: 'Attached File!',
- thread_ts: conversation.identifier
- }.merge(file_information))
- Rails.logger.info(result)
+ thread_ts: conversation.identifier,
+ channel_id: hook.reference_id
+ )
+ Rails.logger.info "slack_upload_result: #{result}"
end
def file_type
diff --git a/package.json b/package.json
index 93611cde3..d3973a84a 100644
--- a/package.json
+++ b/package.json
@@ -72,6 +72,7 @@
"highlight.js": "^11.10.0",
"idb": "^8.0.0",
"js-cookie": "^3.0.5",
+ "lettersanitizer": "^1.0.6",
"libphonenumber-js": "^1.11.9",
"markdown-it": "^13.0.2",
"markdown-it-link-attributes": "^4.0.1",
@@ -92,7 +93,7 @@
"vue-datepicker-next": "^1.0.3",
"vue-dompurify-html": "^5.2.0",
"vue-i18n": "9.14.2",
- "vue-letter": "^0.2.0",
+ "vue-letter": "^0.2.1",
"vue-multiselect": "3.1.0",
"vue-router": "~4.4.5",
"vue-upload-component": "^3.1.17",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index bc3cbac29..d5deb9517 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -136,6 +136,9 @@ importers:
js-cookie:
specifier: ^3.0.5
version: 3.0.5
+ lettersanitizer:
+ specifier: ^1.0.6
+ version: 1.0.6
libphonenumber-js:
specifier: ^1.11.9
version: 1.11.9
@@ -197,8 +200,8 @@ importers:
specifier: 9.14.2
version: 9.14.2(vue@3.5.12(typescript@5.6.2))
vue-letter:
- specifier: ^0.2.0
- version: 0.2.0
+ specifier: ^0.2.1
+ version: 0.2.1
vue-multiselect:
specifier: 3.1.0
version: 3.1.0
@@ -1734,8 +1737,8 @@ packages:
'@types/node@22.7.0':
resolution: {integrity: sha512-MOdOibwBs6KW1vfqz2uKMlxq5xAfAZ98SZjO8e3XnAbFnTJtAspqhWk7hrdSAs9/Y14ZWMiy7/MxMUzAOadYEw==}
- '@types/trusted-types@2.0.2':
- resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==}
+ '@types/trusted-types@2.0.7':
+ resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
@@ -3339,8 +3342,8 @@ packages:
launch-editor@2.9.1:
resolution: {integrity: sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==}
- lettersanitizer@1.0.5:
- resolution: {integrity: sha512-OEJjdlRE96uKB0VfMi4nb3hBctYl1Ss6DQg9SPXRpGcjaBjcmDaibp0ZIdQu1TPwMAEvWC8xRqIcTAooElSDIg==}
+ lettersanitizer@1.0.6:
+ resolution: {integrity: sha512-2vj0tUtBRjlmTCFsgVlFmfi04p049Zwv/4eBGWBUOKropEoL+q+jTQQfFyDu50j7gL76pycMvrqD0uV0vxX2zg==}
levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
@@ -4851,8 +4854,8 @@ packages:
peerDependencies:
vue: ^3.0.0
- vue-letter@0.2.0:
- resolution: {integrity: sha512-p4qHpw89GKidKyGcg4J4IjUcMQuVaTJq83c6UE4616claaLF9rj2Bg/Hq19uDCmokd+SvzEwxq6/ctfaaednkw==}
+ vue-letter@0.2.1:
+ resolution: {integrity: sha512-IYWp47XUikjKfEniWYlFxeJFKABZwAE5IEjz866qCBytBr2dzqVDdjoMDpBP//krxkzN/QZYyHe6C09y/IODYg==}
vue-multiselect@3.1.0:
resolution: {integrity: sha512-+i/fjTqFBpaay9NP+lU7obBeNaw2DdFDFs4mqhsM0aEtKRdvIf7CfREAx2o2B4XDmPrBt1r7x1YCM3BOMLaUgQ==}
@@ -6594,7 +6597,7 @@ snapshots:
dependencies:
undici-types: 6.19.8
- '@types/trusted-types@2.0.2': {}
+ '@types/trusted-types@2.0.7': {}
'@types/trusted-types@2.0.7':
optional: true
@@ -8566,7 +8569,7 @@ snapshots:
picocolors: 1.1.0
shell-quote: 1.8.1
- lettersanitizer@1.0.5: {}
+ lettersanitizer@1.0.6: {}
levn@0.4.1:
dependencies:
@@ -8628,7 +8631,7 @@ snapshots:
lit-html@2.8.0:
dependencies:
- '@types/trusted-types': 2.0.2
+ '@types/trusted-types': 2.0.7
lit@2.2.6:
dependencies:
@@ -10232,9 +10235,9 @@ snapshots:
'@vue/devtools-api': 6.6.4
vue: 3.5.12(typescript@5.6.2)
- vue-letter@0.2.0:
+ vue-letter@0.2.1:
dependencies:
- lettersanitizer: 1.0.5
+ lettersanitizer: 1.0.6
vue-multiselect@3.1.0: {}
diff --git a/public/brand-assets/logo_thumbnail.svg b/public/brand-assets/logo_thumbnail.svg
index 16529675d..d8715e722 100644
--- a/public/brand-assets/logo_thumbnail.svg
+++ b/public/brand-assets/logo_thumbnail.svg
@@ -1,12 +1,25 @@
-
-
\ No newline at end of file
+
diff --git a/spec/controllers/api/v1/accounts/integrations/dyte_controller_spec.rb b/spec/controllers/api/v1/accounts/integrations/dyte_controller_spec.rb
index c70ecc845..3182402f3 100644
--- a/spec/controllers/api/v1/accounts/integrations/dyte_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts/integrations/dyte_controller_spec.rb
@@ -39,10 +39,10 @@ RSpec.describe 'Dyte Integration API', type: :request do
context 'when it is an agent with inbox access and the Dyte API is a success' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meeting')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings')
.to_return(
status: 200,
- body: { success: true, data: { meeting: { id: 'meeting_id', roomName: 'room_name' } } }.to_json,
+ body: { success: true, data: { id: 'meeting_id' } }.to_json,
headers: headers
)
end
@@ -62,7 +62,7 @@ RSpec.describe 'Dyte Integration API', type: :request do
context 'when it is an agent with inbox access and the Dyte API is errored' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meeting')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings')
.to_return(
status: 422,
body: { success: false, data: { message: 'Title is required' } }.to_json,
@@ -112,24 +112,24 @@ RSpec.describe 'Dyte Integration API', type: :request do
context 'when it is an agent with inbox access and message_type is integrations' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meetings/m_id/participant')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings/m_id/participants')
.to_return(
status: 200,
- body: { success: true, data: { authResponse: { userAdded: true, id: 'random_uuid', auth_token: 'json-web-token' } } }.to_json,
+ body: { success: true, data: { id: 'random_uuid', auth_token: 'json-web-token' } }.to_json,
headers: headers
)
end
- it 'returns authResponse' do
+ it 'returns auth_token' do
post add_participant_to_meeting_api_v1_account_integrations_dyte_url(account),
params: { message_id: integration_message.id },
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
response_body = response.parsed_body
- expect(response_body['authResponse']).to eq(
+ expect(response_body).to eq(
{
- 'userAdded' => true, 'id' => 'random_uuid', 'auth_token' => 'json-web-token'
+ 'id' => 'random_uuid', 'auth_token' => 'json-web-token'
}
)
end
diff --git a/spec/controllers/api/v1/widget/integrations/dyte_controller_spec.rb b/spec/controllers/api/v1/widget/integrations/dyte_controller_spec.rb
index 8479fcda5..01585cee3 100644
--- a/spec/controllers/api/v1/widget/integrations/dyte_controller_spec.rb
+++ b/spec/controllers/api/v1/widget/integrations/dyte_controller_spec.rb
@@ -46,15 +46,15 @@ RSpec.describe '/api/v1/widget/integrations/dyte', type: :request do
context 'when message is an integration message' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meetings/m_id/participant')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings/m_id/participants')
.to_return(
status: 200,
- body: { success: true, data: { authResponse: { userAdded: true, id: 'random_uuid', auth_token: 'json-web-token' } } }.to_json,
+ body: { success: true, data: { id: 'random_uuid', auth_token: 'json-web-token' } }.to_json,
headers: { 'Content-Type' => 'application/json' }
)
end
- it 'returns authResponse' do
+ it 'returns auth_token' do
post add_participant_to_meeting_api_v1_widget_integrations_dyte_url,
headers: { 'X-Auth-Token' => token },
params: { website_token: web_widget.website_token, message_id: integration_message.id },
@@ -62,9 +62,9 @@ RSpec.describe '/api/v1/widget/integrations/dyte', type: :request do
expect(response).to have_http_status(:success)
response_body = response.parsed_body
- expect(response_body['authResponse']).to eq(
+ expect(response_body).to eq(
{
- 'userAdded' => true, 'id' => 'random_uuid', 'auth_token' => 'json-web-token'
+ 'id' => 'random_uuid', 'auth_token' => 'json-web-token'
}
)
end
diff --git a/spec/lib/dyte_spec.rb b/spec/lib/dyte_spec.rb
index 56b29b133..0963bfffe 100644
--- a/spec/lib/dyte_spec.rb
+++ b/spec/lib/dyte_spec.rb
@@ -11,23 +11,23 @@ describe Dyte do
context 'when create_a_meeting is called' do
context 'when API response is success' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meeting')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings')
.to_return(
status: 200,
- body: { success: true, data: { meeting: { id: 'meeting_id' } } }.to_json,
+ body: { success: true, data: { id: 'meeting_id' } }.to_json,
headers: headers
)
end
it 'returns api response' do
response = dyte_client.create_a_meeting('title_of_the_meeting')
- expect(response).to eq({ 'meeting' => { 'id' => 'meeting_id' } })
+ expect(response).to eq({ 'id' => 'meeting_id' })
end
end
context 'when API response is invalid' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meeting')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings')
.to_return(status: 422, body: { message: 'Title is required' }.to_json, headers: headers)
end
@@ -47,23 +47,23 @@ describe Dyte do
context 'when API response is success' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meetings/m_id/participant')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings/m_id/participants')
.to_return(
status: 200,
- body: { success: true, data: { authResponse: { userAdded: true, id: 'random_uuid', auth_token: 'json-web-token' } } }.to_json,
+ body: { success: true, data: { id: 'random_uuid', auth_token: 'json-web-token' } }.to_json,
headers: headers
)
end
it 'returns api response' do
response = dyte_client.add_participant_to_meeting('m_id', 'c_id', 'name', 'https://avatar.url')
- expect(response).to eq({ 'authResponse' => { 'userAdded' => true, 'id' => 'random_uuid', 'auth_token' => 'json-web-token' } })
+ expect(response).to eq({ 'id' => 'random_uuid', 'auth_token' => 'json-web-token' })
end
end
context 'when API response is invalid' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meetings/m_id/participant')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings/m_id/participants')
.to_return(status: 422, body: { message: 'Meeting ID is invalid' }.to_json, headers: headers)
end
diff --git a/spec/lib/integrations/dyte/processor_service_spec.rb b/spec/lib/integrations/dyte/processor_service_spec.rb
index 586190b8d..e914ce4cf 100644
--- a/spec/lib/integrations/dyte/processor_service_spec.rb
+++ b/spec/lib/integrations/dyte/processor_service_spec.rb
@@ -15,10 +15,10 @@ describe Integrations::Dyte::ProcessorService do
describe '#create_a_meeting' do
context 'when the API response is success' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meeting')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings')
.to_return(
status: 200,
- body: { success: true, data: { meeting: { id: 'meeting_id', roomName: 'room_name' } } }.to_json,
+ body: { success: true, data: { id: 'meeting_id' } }.to_json,
headers: headers
)
end
@@ -32,7 +32,7 @@ describe Integrations::Dyte::ProcessorService do
context 'when the API response is errored' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meeting')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings')
.to_return(
status: 422,
body: { success: false, data: { message: 'Title is required' } }.to_json,
@@ -51,17 +51,17 @@ describe Integrations::Dyte::ProcessorService do
describe '#add_participant_to_meeting' do
context 'when the API response is success' do
before do
- stub_request(:post, 'https://api.cluster.dyte.in/v1/organizations/org_id/meetings/m_id/participant')
+ stub_request(:post, 'https://api.dyte.io/v2/meetings/m_id/participants')
.to_return(
status: 200,
- body: { success: true, data: { authResponse: { userAdded: true, id: 'random_uuid', auth_token: 'json-web-token' } } }.to_json,
+ body: { success: true, data: { id: 'random_uuid', auth_token: 'json-web-token' } }.to_json,
headers: headers
)
end
it 'return the authResponse' do
response = processor.add_participant_to_meeting('m_id', agent)
- expect(response[:authResponse]).not_to be_nil
+ expect(response).not_to be_nil
end
end
end
diff --git a/spec/lib/integrations/slack/send_on_slack_service_spec.rb b/spec/lib/integrations/slack/send_on_slack_service_spec.rb
index 6524154b4..684f2bc54 100644
--- a/spec/lib/integrations/slack/send_on_slack_service_spec.rb
+++ b/spec/lib/integrations/slack/send_on_slack_service_spec.rb
@@ -162,15 +162,13 @@ describe Integrations::Slack::SendOnSlackService do
attachment = message.attachments.new(account_id: message.account_id, file_type: :image)
attachment.file.attach(io: Rails.root.join('spec/assets/avatar.png').open, filename: 'avatar.png', content_type: 'image/png')
- expect(slack_client).to receive(:files_upload).with(hash_including(
- channels: hook.reference_id,
- thread_ts: conversation.identifier,
- initial_comment: 'Attached File!',
- filetype: 'png',
- content: anything,
- filename: attachment.file.filename,
- title: attachment.file.filename
- )).and_return(file_attachment)
+ expect(slack_client).to receive(:files_upload_v2).with(
+ filename: attachment.file.filename,
+ content: anything,
+ channel_id: hook.reference_id,
+ thread_ts: conversation.identifier,
+ initial_comment: 'Attached File!'
+ ).and_return(file_attachment)
message.save!