From 520b9ef3fa9ba8fad5f98d066ea81ee0ae1f9388 Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:10:15 +0200 Subject: [PATCH 1/3] Add dial in --- app/Http/Resources/Room.php | 4 + app/Services/RoomService.php | 7 +- config/bigbluebutton.php | 2 +- ...2_171150_add_dial_in_to_meetings_table.php | 30 +++++ package-lock.json | 118 +++++++++++++++--- package.json | 2 + 6 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 database/migrations/2024_06_12_171150_add_dial_in_to_meetings_table.php diff --git a/app/Http/Resources/Room.php b/app/Http/Resources/Room.php index 0923c671d..bedb23c24 100644 --- a/app/Http/Resources/Room.php +++ b/app/Http/Resources/Room.php @@ -82,6 +82,10 @@ public function getLastMeeting($latestMeeting) 'usage' => $this->when($latestMeeting->end == null, [ 'participant_count' => $this->participant_count, ]), + 'dial_in' => $this->when($latestMeeting->end == null && ! in_array($latestMeeting->dial_number, config('bigbluebutton.invalid_dial_numbers')), [ + 'number' => $latestMeeting->dial_number, + 'pin' => $latestMeeting->voice_bridge, + ]), 'server_connection_issues' => $latestMeeting->end == null && $latestMeeting->server->error_count > 0, ]; } diff --git a/app/Services/RoomService.php b/app/Services/RoomService.php index 6346b1f09..9246507d7 100644 --- a/app/Services/RoomService.php +++ b/app/Services/RoomService.php @@ -84,7 +84,10 @@ public function start(bool $agreedToAttendance = false, bool $agreedToRecord = f $meetingService = new MeetingService($meeting); Log::info('Starting new meeting for room {room} on server {server}', ['room' => $this->room->getLogLabel(), 'server' => $server->getLogLabel()]); - if (! $meetingService->start()) { + + $createMeetingResponse = $meetingService->start(); + + if (! $createMeetingResponse) { // Creating Meeting failed, remove meeting $meeting->forceDelete(); @@ -99,6 +102,8 @@ public function start(bool $agreedToAttendance = false, bool $agreedToRecord = f // but the api call has not been completed yet therefore the meeting will not be found on the server // and the server poller will mark the meeting as ended immediately $meeting->start = date('Y-m-d H:i:s'); + $meeting->dial_number = $createMeetingResponse->getDialNumber(); + $meeting->voice_bridge = $createMeetingResponse->getVoiceBridge(); $meeting->save(); // Change latest meeting or the room to newly created meeting diff --git a/config/bigbluebutton.php b/config/bigbluebutton.php index 13b26b5c3..302f8f2b3 100644 --- a/config/bigbluebutton.php +++ b/config/bigbluebutton.php @@ -16,7 +16,7 @@ 'room_refresh_rate' => (int) env('ROOM_REFRESH_RATE', 30), 'server_online_threshold' => (int) env('BBB_SERVER_ONLINE_THRESHOLD', 3), 'server_offline_threshold' => (int) env('BBB_SERVER_OFFLINE_THRESHOLD', 3), - + 'invalid_dial_numbers' => ['0', '613-555-1212', '613-555-1234', '0000'], 'load_new_meeting_min_user_count' => (int) env('BBB_LOAD_MIN_USER_COUNT', 15), 'load_new_meeting_min_user_interval' => (int) env('BBB_LOAD_MIN_USER_INTERVAL', 15), diff --git a/database/migrations/2024_06_12_171150_add_dial_in_to_meetings_table.php b/database/migrations/2024_06_12_171150_add_dial_in_to_meetings_table.php new file mode 100644 index 000000000..a421bd7f1 --- /dev/null +++ b/database/migrations/2024_06_12_171150_add_dial_in_to_meetings_table.php @@ -0,0 +1,30 @@ +string('dial_number')->nullable(); + $table->integer('voice_bridge')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('meetings', function (Blueprint $table) { + $table->dropColumn('dial_number'); + $table->dropColumn('voice_bridge'); + }); + } +}; diff --git a/package-lock.json b/package-lock.json index 1c332841c..961020719 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@vitejs/plugin-vue": "^5.2.1", "@vueuse/components": "^12.5.0", "@vueuse/core": "^12.5.0", + "@vueuse/integrations": "^12.5.0", "autoprefixer": "^10.4.20", "axe-core": "^4.10.2", "axios": "^1.7.9", @@ -37,6 +38,7 @@ "postcss": "^8.5.1", "primeicons": "^7.0.0", "primevue": "^4.2.5", + "qrcode": "^1.5.4", "sass": "^1.83.4", "tailwindcss": "^3.4.17", "tailwindcss-primeui": "^0.4.0", @@ -4645,6 +4647,72 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/@vueuse/integrations": { + "version": "12.5.0", + "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.5.0.tgz", + "integrity": "sha512-HYLt8M6mjUfcoUOzyBcX2RjpfapIwHPBmQJtTmXOQW845Y/Osu9VuTJ5kPvnmWJ6IUa05WpblfOwZ+P0G4iZsQ==", + "license": "MIT", + "dependencies": { + "@vueuse/core": "12.5.0", + "@vueuse/shared": "12.5.0", + "vue": "^3.5.13" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "async-validator": "^4", + "axios": "^1", + "change-case": "^5", + "drauu": "^0.4", + "focus-trap": "^7", + "fuse.js": "^7", + "idb-keyval": "^6", + "jwt-decode": "^4", + "nprogress": "^0.2", + "qrcode": "^1.5", + "sortablejs": "^1", + "universal-cookie": "^7" + }, + "peerDependenciesMeta": { + "async-validator": { + "optional": true + }, + "axios": { + "optional": true + }, + "change-case": { + "optional": true + }, + "drauu": { + "optional": true + }, + "focus-trap": { + "optional": true + }, + "fuse.js": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "jwt-decode": { + "optional": true + }, + "nprogress": { + "optional": true + }, + "qrcode": { + "optional": true + }, + "sortablejs": { + "optional": true + }, + "universal-cookie": { + "optional": true + } + } + }, "node_modules/@vueuse/metadata": { "version": "12.5.0", "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.5.0.tgz", @@ -5873,7 +5941,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -6097,7 +6164,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -6109,7 +6175,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -6536,7 +6601,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -6645,6 +6709,12 @@ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "license": "Apache-2.0" }, + "node_modules/dijkstrajs": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", + "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==", + "license": "MIT" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -8048,7 +8118,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -10891,7 +10960,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -10956,7 +11024,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11805,6 +11872,32 @@ "node": ">=6" } }, + "node_modules/qrcode": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", + "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", + "license": "MIT", + "dependencies": { + "dijkstrajs": "^1.0.1", + "pngjs": "^5.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "qrcode": "bin/qrcode" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/qrcode/node_modules/pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -12128,7 +12221,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12149,7 +12241,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, "license": "ISC" }, "node_modules/require-relative": { @@ -12559,7 +12650,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, "license": "ISC" }, "node_modules/set-function-length": { @@ -14511,7 +14601,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true, "license": "ISC" }, "node_modules/which-typed-array": { @@ -14644,7 +14733,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, "license": "ISC" }, "node_modules/yallist": { @@ -14688,7 +14776,6 @@ "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, "license": "MIT", "dependencies": { "cliui": "^6.0.0", @@ -14711,7 +14798,6 @@ "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, "license": "ISC", "dependencies": { "camelcase": "^5.0.0", @@ -14725,7 +14811,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -14739,7 +14824,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -14752,7 +14836,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -14768,7 +14851,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" diff --git a/package.json b/package.json index 2fa5124fa..5e60108da 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "@vitejs/plugin-vue": "^5.2.1", "@vueuse/components": "^12.5.0", "@vueuse/core": "^12.5.0", + "@vueuse/integrations": "^12.5.0", "autoprefixer": "^10.4.20", "axe-core": "^4.10.2", "axios": "^1.7.9", @@ -73,6 +74,7 @@ "postcss": "^8.5.1", "primeicons": "^7.0.0", "primevue": "^4.2.5", + "qrcode": "^1.5.4", "sass": "^1.83.4", "tailwindcss": "^3.4.17", "tailwindcss-primeui": "^0.4.0", From d7195ec6a0e1e0dccb48b7240f87e799aa7fa82c Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:01:07 +0200 Subject: [PATCH 2/3] Join by phone --- lang/en/rooms.php | 8 ++ .../js/components/RoomJoinByPhoneButton.vue | 91 +++++++++++++++++++ resources/js/views/RoomsView.vue | 5 + 3 files changed, 104 insertions(+) create mode 100644 resources/js/components/RoomJoinByPhoneButton.vue diff --git a/lang/en/rooms.php b/lang/en/rooms.php index 0e577c348..ab120934e 100644 --- a/lang/en/rooms.php +++ b/lang/en/rooms.php @@ -265,6 +265,14 @@ 'enabled' => 'You will be notified by your browser when the room starts. Do not close this window/tab.', ], 'only_used_by_authenticated_users' => 'This room can only be used by authenticated users.', + 'phone' => [ + 'join_by_phone' => 'Join by phone', + 'title' => 'Phone number and PIN', + 'number' => 'Phone number', + 'pin' => 'PIN', + 'qrcode' => 'QR-Code', + 'call' => 'Call', + ], 'placeholder_name' => 'John Doe', 'recording_accept' => 'I consent to the recording.', 'recording_attendance_accept' => 'I consent to the attendance logging.', diff --git a/resources/js/components/RoomJoinByPhoneButton.vue b/resources/js/components/RoomJoinByPhoneButton.vue new file mode 100644 index 000000000..28c7d9925 --- /dev/null +++ b/resources/js/components/RoomJoinByPhoneButton.vue @@ -0,0 +1,91 @@ + + + + + + + + {{ $t("rooms.phone.title") }} + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/js/views/RoomsView.vue b/resources/js/views/RoomsView.vue index 24eb4af41..daac82ecc 100644 --- a/resources/js/views/RoomsView.vue +++ b/resources/js/views/RoomsView.vue @@ -202,6 +202,11 @@ @guests-not-allowed="handleGuestsNotAllowed" @changed="reload" /> + Date: Thu, 23 Jan 2025 12:42:22 +0100 Subject: [PATCH 3/3] Make invalid_dial_numbers configurable --- config/bigbluebutton.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/bigbluebutton.php b/config/bigbluebutton.php index 302f8f2b3..26a424c71 100644 --- a/config/bigbluebutton.php +++ b/config/bigbluebutton.php @@ -16,7 +16,7 @@ 'room_refresh_rate' => (int) env('ROOM_REFRESH_RATE', 30), 'server_online_threshold' => (int) env('BBB_SERVER_ONLINE_THRESHOLD', 3), 'server_offline_threshold' => (int) env('BBB_SERVER_OFFLINE_THRESHOLD', 3), - 'invalid_dial_numbers' => ['0', '613-555-1212', '613-555-1234', '0000'], + 'invalid_dial_numbers' => explode(',', env('BBB_INVALID_DIAL_NUMBERS', '0,613-555-1212,613-555-1234,0000')), 'load_new_meeting_min_user_count' => (int) env('BBB_LOAD_MIN_USER_COUNT', 15), 'load_new_meeting_min_user_interval' => (int) env('BBB_LOAD_MIN_USER_INTERVAL', 15),