├── .github ├── FUNDING.yml └── workflows │ └── tests.yml ├── .styleci.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── composer.json ├── config └── bigbluebutton.php └── src ├── Bbb.php ├── Bigbluebutton.php ├── BigbluebuttonServiceProvider.php ├── Facades └── Bigbluebutton.php ├── Services ├── InitHooks.php ├── InitMeeting.php └── InitRecordings.php └── helpers.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ["https://www.paypal.me/joisarjignesh","https://www.buymeacoffee.com/joisarjignesh"] 2 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: BigBlueButton Tests 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | build: 9 | strategy: 10 | matrix: 11 | operating-system: [ubuntu-latest, windows-latest, macos-latest] 12 | php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] 13 | 14 | runs-on: ${{ matrix.operating-system }} 15 | 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v2 19 | 20 | - name: Setup PHP, with composer and extensions 21 | uses: shivammathur/setup-php@v2 22 | with: 23 | php-version: ${{ matrix.php-versions }} 24 | coverage: none 25 | extensions: curl, libxml, mbstring, zip 26 | 27 | - name: Get composer cache directory 28 | id: composercache 29 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 30 | 31 | - name: Cache composer dependencies 32 | uses: actions/cache@v2 33 | with: 34 | path: ${{ steps.composercache.outputs.dir }} 35 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 36 | restore-keys: ${{ runner.os }}-composer- 37 | 38 | - name: Install dependencies 39 | run: composer install --no-progress --prefer-dist --optimize-autoloader 40 | 41 | - name: Test with phpunit 42 | run: vendor/bin/phpunit --coverage-text 43 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: laravel 2 | 3 | disabled: 4 | - single_class_element_per_statement 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `bigbluebutton` will be documented in this file 4 | 5 | ## 1.0.0 - 201X-XX-XX 6 | 7 | - initial release 8 | 9 | ## 1.1.3 - 2020 10 | - pass custom parameters on attendee join 11 | 12 | ## 1.1.4 - 2020-09-06 13 | - multiple server support 14 | - for a specific server create,connect,join same as default 15 | - by default if you not specify a server it will use default server 16 | 17 | ## 1.1.5 - 2020-09-10 18 | - add laravel 8 support 19 | 20 | ## 1.1.6 - 2020-09-20 21 | - replace static to basic server method 22 | - added helper method of bigbluebutton (support default and specific server) 23 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | Please read and understand the contribution guide before creating an issue or pull request. 6 | 7 | ## Etiquette 8 | 9 | This project is open source, and as such, the maintainers give their free time to build and maintain the source code 10 | held within. They make the code freely available in the hope that it will be of use to other developers. It would be 11 | extremely unfair for them to suffer abuse or anger for their hard work. 12 | 13 | Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the 14 | world that developers are civilized and selfless people. 15 | 16 | It's the duty of the maintainer to ensure that all submissions to the project are of sufficient 17 | quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. 18 | 19 | ## Viability 20 | 21 | When requesting or submitting new features, first consider whether it might be useful to others. Open 22 | source projects are used by many developers, who may have entirely different needs to your own. Think about 23 | whether or not your feature is likely to be used by other users of the project. 24 | 25 | ## Procedure 26 | 27 | Before filing an issue: 28 | 29 | - Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. 30 | - Check to make sure your feature suggestion isn't already present within the project. 31 | - Check the pull requests tab to ensure that the bug doesn't have a fix in progress. 32 | - Check the pull requests tab to ensure that the feature isn't already in progress. 33 | 34 | Before submitting a pull request: 35 | 36 | - Check the codebase to ensure that your feature doesn't already exist. 37 | - Check the pull requests to ensure that another person hasn't already submitted the feature or fix. 38 | 39 | ## Requirements 40 | 41 | If the project maintainer has any additional requirements, you will find them listed here. 42 | 43 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer). 44 | 45 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 46 | 47 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 48 | 49 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. 50 | 51 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 52 | 53 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 54 | 55 | **Happy coding**! 56 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Jignesh Joisar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![laravel-bigbluebutton](https://user-images.githubusercontent.com/17031402/87796124-93327b80-c866-11ea-8a77-cdfa844b3d63.jpg) 2 | # BigBlueButton Server API Library for Laravel 3 | [![License](https://img.shields.io/packagist/l/joisarjignesh/bigbluebutton.svg)](https://github.com/joisarjignesh/bigbluebutton/LICENSE.md) 4 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/joisarjignesh/bigbluebutton.svg?style=flat-square)](https://packagist.org/packages/joisarjignesh/bigbluebutton) 5 | [![Build Status](https://img.shields.io/badge/build-passing-brightgreen)](https://travis-ci.org/joisarjignesh/bigbluebutton) 6 | [![Quality Score](https://img.shields.io/scrutinizer/g/joisarjignesh/bigbluebutton.svg?style=flat-square)](https://scrutinizer-ci.com/g/joisarjignesh/bigbluebutton) 7 | [![Total Downloads](https://img.shields.io/packagist/dt/joisarjignesh/bigbluebutton.svg?style=flat-square)](https://packagist.org/packages/joisarjignesh/bigbluebutton) 8 | ![Laravel Framework](https://img.shields.io/badge/laravel-%3E%3D5.5-blue) 9 | 10 | 11 | Package that provides easily communicate between BigBlueButton server and laravel framework 12 | 13 | * [Requirements](#requirements) 14 | * [Installation](#installation) 15 | * [Usage](#usage) 16 | * [Api](#Api) 17 | * [Check a url and secret working](#check-a-url-and-secret-working) 18 | * [Meeting](#meeting) 19 | * [Create a meeting](#create-a-meeting) 20 | * [Upload slides](#upload-slides) 21 | * [End meeting callback url](#end-meeting-callback-url) 22 | * [Recording ready callback URL](#recording-ready-callback-url) 23 | * [Join a meeting](#join-a-meeting) 24 | * [Get a list of meetings](#get-a-list-of-meetings) 25 | * [Get meeting info](#get-meeting-info) 26 | * [Is a meeting running?](#is-a-meeting-running) 27 | * [Close a meeting](#close-a-meeting) 28 | * [Recording](#recording) 29 | * [Get recordings](#get-recordings) 30 | * [Publish recordings](#publish-recordings) 31 | * [Delete recordings](#delete-recordings) 32 | * [Update recordings](#update-recordings) 33 | * [Hooks](#hooks) 34 | * [Create Hooks](#hooks-create) 35 | * [Destroy Hooks](#hooks-destroy) 36 | * [Other](#other) 37 | * [Get API version](#get-api-version) 38 | * [Unofficial](#unofficial) 39 | * [Start a meeting](#start-a-meeting) 40 | 41 | 42 | 43 | ## Requirements 44 | - Laravel 5.5 or above. 45 | 46 | ## Installation 47 | You can install the package via composer: 48 | 49 | ```bash 50 | composer require joisarjignesh/bigbluebutton 51 | ``` 52 | After install package publish config file 53 | ``` 54 | php artisan vendor:publish --tag=bigbluebutton-config 55 | ``` 56 | 57 | ## Usage 58 | - Define in config/bigbluebutton.php file 59 | 60 | ``` 61 | BBB_SECURITY_SALT=bbb_secret_key 62 | BBB_SERVER_BASE_URL=https://example.com/bigbluebutton/ 63 | ``` 64 | 65 | - For Specific server configuration (only for multiple server by default is optional) 66 | ``` 67 | 'servers' => [ 68 | 'server1' => [ 69 | 'BBB_SECURITY_SALT' => '', 70 | 'BBB_SERVER_BASE_URL' => '', 71 | ], 72 | ] 73 | ``` 74 | 75 | After Define salt and url clear old configurations 76 | ``` 77 | php artisan config:clear 78 | ``` 79 | ## Api 80 | 81 | ### Check a url and secret working 82 | ```php 83 | dd(\Bigbluebutton::isConnect()); //default 84 | dd(\Bigbluebutton::server('server1')->isConnect()); //for specific server 85 | dd(bigbluebutton()->isConnect()); //using helper method 86 | ``` 87 | 88 | ### Meeting 89 | #### Create a meeting 90 | - You can create meeting in three ways [document](https://docs.bigbluebutton.org/dev/api.html#create) 91 | 92 | 1.By Passing Array 93 | ```php 94 | \Bigbluebutton::create([ 95 | 'meetingID' => 'tamku', 96 | 'meetingName' => 'test meeting', 97 | 'attendeePW' => 'attendee', 98 | 'moderatorPW' => 'moderator' 99 | ]); 100 | ``` 101 | 102 | 2.By passing CreateMeetingParameters object for customize create meeting 103 | ```php 104 | use BigBlueButton\Parameters\CreateMeetingParameters; 105 | 106 | $meetingParams = new CreateMeetingParameters($meetingID, $meetingName); 107 | $meetingParams->setModeratorPW('moderatorPassword'); 108 | $meetingParams->setAttendeePW('attendeePassword'); 109 | 110 | \Bigbluebutton::create($meetingParams); 111 | ``` 112 | 113 | 3.By passing array it will return CreateMeetingParameters object for overwrite methods 114 | ```php 115 | $createMeeting = \Bigbluebutton::initCreateMeeting([ 116 | 'meetingID' => 'tamku', 117 | 'meetingName' => 'test meeting', 118 | 'attendeePW' => 'attendee', 119 | 'moderatorPW' => 'moderator', 120 | ]); 121 | 122 | $createMeeting->setDuration(100); //overwrite default configuration 123 | \Bigbluebutton::create($createMeeting); 124 | ``` 125 | 126 | ##### Upload slides 127 | - You can upload slides within the create a meeting call. If you do this, the BigBlueButton server will immediately 128 | download and process the [slides](https://docs.bigbluebutton.org/dev/api.html#pre-upload-slides) 129 | ```php 130 | \Bigbluebutton::create([ 131 | 'meetingID' => 'tamku', 132 | 'meetingName' => 'test meeting', 133 | 'attendeePW' => 'attendee', 134 | 'moderatorPW' => 'moderator', 135 | 'presentation' => [ //must be array 136 | ['link' => 'https://www.example.com/doc.pdf', 'fileName' => 'doc.pdf'], //first will be default and current slide in meeting 137 | ['link' => 'https://www.example.com/php_tutorial.pptx', 'fileName' => 'php_tutorial.pptx'], 138 | ], 139 | ]); 140 | ``` 141 | 142 | ##### End meeting callback [URL](https://docs.bigbluebutton.org/dev/api.html#end-meeting-callback-url) 143 | - You can ask the BigBlueButton server to make a callback to your application when the meeting ends. Upon receiving 144 | the callback your application could, for example, change the interface for the user to hide the ‘join’ button. 145 | 146 | ##### Note : End meeting callback URL will notify silently, User won't redirect to that page. 147 | - For testing endCallbackUrl see [webhook site](https://webhook.site) 148 | 149 | If you want to redirect users to that page after meeting end then can use logoutURL 150 | ```php 151 | \Bigbluebutton::create([ 152 | 'meetingID' => 'tamku', 153 | 'meetingName' => 'test meeting', 154 | 'attendeePW' => 'attendee', 155 | 'moderatorPW' => 'moderator', 156 | 'endCallbackUrl' => 'www.example.com/callback', 157 | 'logoutUrl' => 'www.example.com/logout', 158 | ]); 159 | ``` 160 | 161 | ##### Recording ready callback [URL](https://docs.bigbluebutton.org/dev/api.html#recording-ready-callback-url) 162 | - You can ask the BigBlueButton server to make a callback to your application when the recording for a meeting is ready for viewing. Upon receiving the callback your application could, for example, send the presenter an e-mail to notify them that their recording is ready 163 | 164 | ##### Note : Recording ready callback URL will notify silently, User won't redirect to that page. 165 | - For testing Recording ready callback see [webhook site](https://webhook.site) 166 | ```php 167 | \Bigbluebutton::create([ 168 | 'meetingID' => 'tamku', 169 | 'meetingName' => 'test meeting', 170 | 'attendeePW' => 'attendee', 171 | 'moderatorPW' => 'moderator', 172 | 'bbb-recording-ready-url' => 'https://example.com/api/v1/recording_status', 173 | ]); 174 | ``` 175 | 176 | #### Join a meeting 177 | - Join meeting ( by default it will redirect into BigBlueButton Server And Join Meeting) [document](https://docs.bigbluebutton.org/dev/api.html#join) 178 | ```php 179 | use JoisarJignesh\Bigbluebutton\Facades\Bigbluebutton; 180 | 181 | return redirect()->to( 182 | Bigbluebutton::join([ 183 | 'meetingID' => 'tamku', 184 | 'userName' => 'disa', 185 | 'password' => 'attendee' //which user role want to join set password here 186 | ]) 187 | ); 188 | ``` 189 | 190 | - Join meeting but does want to redirect into BigBlueButton server and pass other parameters 191 | ```php 192 | \Bigbluebutton::join([ 193 | 'meetingID' => 'tamku', 194 | 'userName' => 'disa', 195 | 'password' => 'attendee', //which user role want to join set password here 196 | 'redirect' => false, //it will not redirect into bigblueserver 197 | 'userId' => "54575", 198 | 'customParameters' => [ 199 | 'foo' => 'bar', 200 | 'key' => 'value' 201 | ] 202 | ]); 203 | ``` 204 | 205 | #### Get a list of meetings 206 | - Get all meetings [document](https://docs.bigbluebutton.org/dev/api.html#getmeetings) 207 | ```php 208 | \Bigbluebutton::all(); //using facade 209 | bigbluebutton()->all(); //using helper method 210 | ``` 211 | 212 | #### Get meeting info 213 | - Get meeting info [document](https://docs.bigbluebutton.org/dev/api.html#getmeetinginfo) 214 | ```php 215 | use JoisarJignesh\Bigbluebutton\Facades\Bigbluebutton; 216 | 217 | Bigbluebutton::getMeetingInfo([ 218 | 'meetingID' => 'tamku', 219 | 'moderatorPW' => 'moderator' //moderator password set here 220 | ]); 221 | ``` 222 | 223 | #### Is a meeting running 224 | - Is meeting running [document](https://docs.bigbluebutton.org/dev/api.html#ismeetingrunning) 225 | ```php 226 | Bigbluebutton::isMeetingRunning([ 227 | 'meetingID' => 'tamku', 228 | ]); 229 | 230 | Bigbluebutton::isMeetingRunning('tamku'); //second way 231 | ``` 232 | 233 | #### Close a meeting 234 | - Close meeting [document](https://docs.bigbluebutton.org/dev/api.html#end) 235 | ```php 236 | use JoisarJignesh\Bigbluebutton\Facades\Bigbluebutton; 237 | 238 | Bigbluebutton::close([ 239 | 'meetingID' => 'tamku', 240 | 'moderatorPW' => 'moderator' //moderator password set here 241 | ]); 242 | ``` 243 | 244 | ### Recording 245 | #### Get recordings 246 | - Get recordings [document](https://docs.bigbluebutton.org/dev/api.html#getrecordings) 247 | ```php 248 | \Bigbluebutton::getRecordings([ 249 | 'meetingID' => 'tamku', 250 | //'meetingID' => ['tamku','xyz'], //pass as array if get multiple recordings 251 | //'recordID' => 'a3f1s', 252 | //'recordID' => ['xyz.1','pqr.1'] //pass as array note :If a recordID is specified, the meetingID is ignored. 253 | // 'state' => 'any' // It can be a set of states separate by commas 254 | ]); 255 | ``` 256 | 257 | #### Publish recordings 258 | - Publish Recordings [document](https://docs.bigbluebutton.org/dev/api.html#publishrecordings) 259 | ```php 260 | \Bigbluebutton::publishRecordings([ 261 | 'recordID' => 'a3f1s', 262 | //'recordID' => ['xyz.1','pqr.1'] //pass as array if publish multiple recordings 263 | 'state' => true //default is true 264 | ]); 265 | ``` 266 | 267 | #### Delete recordings 268 | - Delete recordings [document](https://docs.bigbluebutton.org/dev/api.html#deleterecordings) 269 | ```php 270 | \Bigbluebutton::deleteRecordings([ 271 | //'recordID' => 'a3f1s', 272 | 'recordID' => ['a3f1s','a4ff2'] //pass array if multiple delete recordings 273 | ]); 274 | ``` 275 | #### Update recordings 276 | - Update recordings [document](https://docs.bigbluebutton.org/dev/api.html#updaterecordings) 277 | ```php 278 | \Bigbluebutton::updateRecordings([ 279 | //'recordID' => 'a3f1s', 280 | 'recordID' => ['a3f1s','a4ff2'] //pass array if multiple delete recordings 281 | ]); 282 | ``` 283 | 284 | ### Hooks 285 | #### Hooks create 286 | - Hooks Create [document](https://docs.bigbluebutton.org/dev/webhooks.html#hookscreate) 287 | ```php 288 | dd(Bigbluebutton::hooksCreate([ 289 | 'callbackURL' => 'example.test', //required 290 | 'meetingID' => 'tamku', //optional if not set then hooks set for all meeting id 291 | 'getRaw' => true //optional 292 | ])); 293 | ``` 294 | 295 | #### Hooks destroy 296 | - Hooks Destroy [document](https://docs.bigbluebutton.org/dev/webhooks.html#hooksdestroy) 297 | ```php 298 | dd(Bigbluebutton::hooksDestroy([ 299 | 'hooksID' => 33 300 | ])); 301 | 302 | dd(Bigbluebutton::hooksDestroy('53')); //second way 303 | ``` 304 | 305 | ### Other 306 | #### Get api version 307 | - Get api version 308 | ```php 309 | dd(\Bigbluebutton::getApiVersion()); //return as collection 310 | ``` 311 | 312 | ### Unofficial 313 | #### Start a meeting 314 | - Start meeting (first check meeting is exists or not if not then create a meeting and join a meeting otherwise 315 | meeting is exists then it will directly join a meeting) (by default user join as moderator) 316 | ```php 317 | $url = \Bigbluebutton::start([ 318 | 'meetingID' => 'tamku', 319 | 'meetingName' => 'test meeting name', 320 | 'moderatorPW' => 'moderator', //moderator password set here 321 | 'attendeePW' => 'attendee', //attendee password here 322 | 'userName' => 'John Deo',//for join meeting 323 | //'redirect' => false // only want to create and meeting and get join url then use this parameter 324 | ]); 325 | 326 | return redirect()->to($url); 327 | ``` 328 | 329 | ### More Information Read This [wiki](https://github.com/bigbluebutton/bigbluebutton-api-php/wiki) 330 | ### For Bigbluebutton Api Testing See This [ApiMate](https://mconf.github.io/api-mate/) 331 | ### See Bigbluebutton Official dev Api [Bigbluebutton](https://docs.bigbluebutton.org/dev/api.html) 332 | 333 | ### Support 334 | 335 | 336 | Buy Me A Coffee 337 | 338 | 339 | Donate 340 | 341 | ### Changelog 342 | 343 | Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently. 344 | 345 | ## Contributing 346 | 347 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details. 348 | 349 | ### Security 350 | 351 | If you discover any security related issues, please email jigneshjoisar@gmail.com instead of using the issue tracker. 352 | 353 | ## Credits 354 | 355 | - [Jignesh Joisar](https://github.com/joisarjignesh) 356 | - [All Contributors](../../contributors) 357 | 358 | ## License 359 | 360 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 361 | 362 | 363 | 364 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "joisarjignesh/bigbluebutton", 3 | "description": "BigBlueButton Server API Library for Laravel", 4 | "keywords": [ 5 | "joisarjignesh", 6 | "bigbluebutton", 7 | "api", 8 | "bbb", 9 | "meeting", 10 | "package", 11 | "laravel-package", 12 | "laravel", 13 | "php" 14 | ], 15 | "homepage": "https://github.com/joisarjignesh/bigbluebutton", 16 | "license": "MIT", 17 | "version": "v2.9", 18 | "type": "library", 19 | "authors": [ 20 | { 21 | "name": "Jignesh Joisar", 22 | "email": "jigneshjoisar@gmail.com", 23 | "homepage": "https://jigneshjoisar.web.app", 24 | "role": "Developer" 25 | } 26 | ], 27 | "require": { 28 | "php": "^7.4|^8.0|^8.1|^8.2", 29 | "illuminate/support": "^5.5|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", 30 | "littleredbutton/bigbluebutton-api-php": "~5.0" 31 | }, 32 | "require-dev": { 33 | "orchestra/testbench": "^4.0|^7.0|^8.0|^10.0", 34 | "phpunit/phpunit": "^8.0|^9.0|^10.0|^11.5.3" 35 | }, 36 | "autoload": { 37 | "psr-4": { 38 | "JoisarJignesh\\Bigbluebutton\\": "src/" 39 | }, 40 | "files": [ 41 | "src/helpers.php" 42 | ] 43 | }, 44 | "autoload-dev": { 45 | "psr-4": { 46 | "JoisarJignesh\\Bigbluebutton\\Tests\\": "tests/" 47 | } 48 | }, 49 | "scripts": { 50 | "test": "vendor/bin/phpunit", 51 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage" 52 | }, 53 | "config": { 54 | "sort-packages": true 55 | }, 56 | "minimum-stability": "dev", 57 | "prefer-stable": true, 58 | "support": { 59 | "source": "https://github.com/joisarjignesh/bigbluebutton", 60 | "issues": "https://github.com/joisarjignesh/bigbluebutton/issues", 61 | "docs": "https://github.com/joisarjignesh/bigbluebutton/blob/master/README.md" 62 | }, 63 | "extra": { 64 | "laravel": { 65 | "providers": [ 66 | "JoisarJignesh\\Bigbluebutton\\BigbluebuttonServiceProvider" 67 | ], 68 | "aliases": { 69 | "Bigbluebutton": "JoisarJignesh\\Bigbluebutton\\Facades\\Bigbluebutton" 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /config/bigbluebutton.php: -------------------------------------------------------------------------------- 1 | env('BBB_SECURITY_SALT', ''), 9 | 'BBB_SERVER_BASE_URL' => env('BBB_SERVER_BASE_URL', ''), 10 | 11 | /* 12 | * available hash algorithm sha1,sha256,sha512,sha384 13 | */ 14 | 'hash_algorithm' => 'sha1', 15 | 16 | /** 17 | * For Multiple BigBlueButton Server Configurations 18 | * For Each server you must be specify salt and url with define server name 19 | * Note : if you want to used multiple server configuration you must specify servername. 20 | */ 21 | 'servers' => [ 22 | 'server1' => [ 23 | 'BBB_SECURITY_SALT' => '', 24 | 'BBB_SERVER_BASE_URL' => '', 25 | ], 26 | 'server2' => [ 27 | 'BBB_SECURITY_SALT' => '', 28 | 'BBB_SERVER_BASE_URL' => '', 29 | ], 30 | ], 31 | 32 | 'create' => [ 33 | /** 34 | * if user does not pass attendee or moderator password then 35 | * generate random password (length should be there). 36 | * 37 | * var @numeric 38 | */ 39 | 'passwordLength' => 8, 40 | 41 | /** 42 | * A welcome message that gets displayed on the chat window when the participant joins 43 | * if null then default server welcome message will be show.. 44 | * var @mixed. 45 | **/ 46 | 'welcomeMessage' => null, 47 | 48 | /** 49 | * The dial access number that participants can call in using regular phone. 50 | * 51 | * var @string 52 | */ 53 | 'dialNumber' => null, 54 | 55 | /** 56 | * Set the maximum number of users allowed to joined the conference at the same time. 57 | * Note : zero means unlimited participants 58 | * var @numeric. 59 | */ 60 | 'maxParticipants' => 0, 61 | 62 | /** 63 | * The URL that the BigBlueButton client will go to after users click the OK button. 64 | * 65 | * var @string 66 | */ 67 | 'logoutUrl' => null, 68 | 69 | /** 70 | * Setting ‘record=true’ instructs the BigBlueButton server to record the media and 71 | * events in the session for later playback. The default is false. 72 | * 73 | * In order for a playback file to be generated, a moderator must click the Start/Stop Recording 74 | * button at least once during the session; otherwise, in the absence of any recording marks, 75 | * the record and playback scripts will not generate a playback file. 76 | * See also the autoStartRecording and allowStartStopRecording parameters 77 | * var @bool 78 | */ 79 | 'record' => false, 80 | 81 | /** 82 | * The maximum length (in minutes) for the meeting. 83 | * If duration contains a non-zero value, 84 | * then when the length of the meeting exceeds the duration value the server will immediately end the meeting 85 | * Note : zero means unlimited participants. 86 | * 87 | * var @numeric 88 | */ 89 | 'duration' => 0, 90 | 91 | /** 92 | * Must be set to true to create a breakout room. default set false. 93 | * 94 | * var @bool 95 | */ 96 | 'isBreakout' => false, 97 | 98 | /** 99 | * Display a message to all moderators in the public chat. 100 | * The value is interpreted in the same way as the welcome parameter. 101 | * 102 | * var @string 103 | */ 104 | 'moderatorOnlyMessage' => null, 105 | 106 | /** 107 | * Whether to automatically start recording when first user joins (default false). 108 | * When this parameter is true, the recording UI in BigBlueButton will be initially active. 109 | * Moderators in the session can still pause and restart recording using the UI control. 110 | * 111 | * NOTE: Don’t pass autoStartRecording=false and allowStartStopRecording=false 112 | * the moderator won’t be able to start recording! 113 | * 114 | * var @bool 115 | */ 116 | 'autoStartRecording' => false, 117 | 118 | /** 119 | * Allow the user to start/stop recording. (default true) 120 | * If you set both allowStartStopRecording=false and autoStartRecording=true, 121 | * then the entire length of the session will be recorded, 122 | * and the moderators in the session will not be able to pause/resume the recording. 123 | * 124 | * var @bool 125 | */ 126 | 'allowStartStopRecording' => true, 127 | 128 | /** 129 | * Setting webcamsOnlyForModerator=true will cause all webcams 130 | * shared by viewers during this meeting to only appear for moderators (added 1.1). 131 | * 132 | * var @bool 133 | */ 134 | 'webcamsOnlyForModerator' => false, 135 | 136 | /** 137 | * Will set the banner text in the client. (added 2.0). 138 | * 139 | * var @string 140 | */ 141 | 'bannerText' => null, 142 | 143 | /** 144 | * Will set the banner background color in the client. The required format is color hex #FFFFFF. (added 2.0). 145 | * 146 | * var @string 147 | */ 148 | 'bannerColor' => '#FFFFFF', 149 | 150 | /** 151 | * Setting logo=http://www.example.com/my-custom-logo.png will replace 152 | * the default logo in the Flash client. (added 2.0). 153 | * 154 | * var @string 155 | */ 156 | 'logo' => null, 157 | 158 | /** 159 | * Will set the banner text in the client. (added 2.0). 160 | * 161 | * var @string 162 | */ 163 | // 'bannerText' => null, 164 | 165 | /** 166 | * Will set the banner background color in the client. 167 | * The required format is color hex #FFFFFF. (added 2.0). 168 | * 169 | * var @string 170 | */ 171 | //'bannerColor' => null, 172 | 173 | /** 174 | * Setting copyright=My custom copyright will replace 175 | * the default copyright on the footer of the Flash client. (added 2.0). 176 | * 177 | * var @string 178 | */ 179 | 'copyright' => null, 180 | 181 | /** 182 | * Setting muteOnStart=true will mute all users when the meeting starts. (added 2.0). 183 | * 184 | * var @bool 185 | */ 186 | 'muteOnStart' => false, 187 | 188 | /** 189 | * Default allowModsToUnmuteUsers=false. 190 | * Setting to allowModsToUnmuteUsers=true will allow moderators to unmute other users in the meeting. (added 2.2). 191 | * 192 | * var @bool 193 | */ 194 | 'allowModsToUnmuteUsers' => false, 195 | 196 | /** 197 | * Default lockSettingsDisableCam=false. 198 | * Setting lockSettingsDisableCam=true will prevent users from sharing their camera in the meeting. (added 2.2). 199 | * 200 | * var @bool 201 | */ 202 | 'lockSettingsDisableCam' => false, 203 | 204 | /** 205 | * Default lockSettingsDisableMic=false. 206 | * Setting to lockSettingsDisableMic=true will only allow user to join listen only. (added 2.2). 207 | * 208 | * var @bool 209 | */ 210 | 'lockSettingsDisableMic' => false, 211 | 212 | /** 213 | * Default lockSettingsDisablePrivateChat=false. 214 | * Setting to lockSettingsDisablePrivateChat=true will disable private chats in the meeting. (added 2.2). 215 | * 216 | * var @bool 217 | */ 218 | 'lockSettingsDisablePrivateChat' => false, 219 | 220 | /** 221 | * Default lockSettingsDisablePublicChat=false. 222 | * Setting to lockSettingsDisablePublicChat=true will disable public chat in the meeting. (added 2.2). 223 | * 224 | * var @bool 225 | */ 226 | 'lockSettingsDisablePublicChat' => false, 227 | 228 | /** 229 | * Default lockSettingsDisableNote=false. 230 | * Setting to lockSettingsDisableNote=true will disable notes in the meeting. (added 2.2). 231 | * 232 | * var @bool 233 | **/ 234 | 'lockSettingsDisableNote' => false, 235 | 236 | /** 237 | * Default lockSettingsLockedLayout=false. 238 | * Setting to lockSettingsLockedLayout=true will lock the layout in the meeting. (added 2.2). 239 | * 240 | * var @bool 241 | */ 242 | 'lockSettingsLockedLayout' => false, 243 | 244 | /** 245 | * Default lockSettingsLockOnJoin=true. 246 | * Setting to lockSettingsLockOnJoin=false will not apply lock setting to users when they join. (added 2.2). 247 | * 248 | * var @bool 249 | */ 250 | 'lockSettingsLockOnJoin' => false, 251 | 252 | /** 253 | * Default lockSettingsLockOnJoinConfigurable=false. 254 | * Setting to lockSettingsLockOnJoinConfigurable=true will allow applying of lockSettingsLockOnJoin param. (added 2.2). 255 | * 256 | * var @bool 257 | */ 258 | 'lockSettingsLockOnJoinConfigurable' => false, 259 | 260 | /** 261 | * Default guestPolicy=ALWAYS_ACCEPT. 262 | * Will set the guest policy for the meeting. 263 | * The guest policy determines whether or not users 264 | * who send a join request with guest=true will be allowed to join the meeting. 265 | * Possible values are ALWAYS_ACCEPT, ALWAYS_DENY, and ASK_MODERATOR. 266 | * 267 | * var @string 268 | */ 269 | 'guestPolicy' => 'ALWAYS_ACCEPT', 270 | 271 | /** 272 | * Defaults to the value of defaultKeepEvents. 273 | * If meetingKeepEvents is true BigBlueButton saves meeting events even if the meeting is not recorded (added in 2.3). 274 | * 275 | * var @bool 276 | */ 277 | 'meetingKeepEvents' => false, 278 | 279 | /** 280 | * Default endWhenNoModerator=false. 281 | * If endWhenNoModerator is true the meeting will end automatically after a delay - see endWhenNoModeratorDelayInMinutes (added in 2.3). 282 | * 283 | * var @bool 284 | */ 285 | 'endWhenNoModerator' => false, 286 | 287 | /** 288 | * Defaults to the value of endWhenNoModeratorDelayInMinutes=1. 289 | * If endWhenNoModerator is true, the meeting will be automatically ended after this many minutes (added in 2.2). 290 | * 291 | * var @integer 292 | */ 293 | 'endWhenNoModeratorDelayInMinutes' => 1, 294 | 295 | /** 296 | * Will set the default layout for the meeting. 297 | * Possible values are: CUSTOM_LAYOUT, SMART_LAYOUT, PRESENTATION_FOCUS, VIDEO_FOCUS. (added 2.4) 298 | * Default: SMART_LAYOUT. 299 | * 300 | * var @enum 301 | */ 302 | 'meetingLayout' => 'SMART_LAYOUT', 303 | 304 | /** 305 | * Default learningDashboardCleanupDelayInMinutes=2. 306 | * This option set the delay (in minutes) before the Learning Dashboard become unavailable after the end of the meeting. 307 | * If this value is zero, the Learning Dashboard will keep available permanently. (added 2.4). 308 | * 309 | * var @integer 310 | */ 311 | 'learningDashboardCleanupDelayInMinutes' => 2, 312 | 313 | /** 314 | * Setting to true will allow moderators to close other users cameras in the meeting. (added 2.4) 315 | * Default: false. 316 | * 317 | * var @bool 318 | */ 319 | 'allowModsToEjectCameras' => false, 320 | 321 | /** 322 | * Setting to true will allow users to join meetings without session cookie's validation. (added 2.4.3) 323 | * Default: false. 324 | * 325 | * var @bool 326 | */ 327 | 'allowRequestsWithoutSession' => false, 328 | 329 | /** 330 | * Setting to 0 will disable this threshold. 331 | * Defines the max number of webcams a single user can share simultaneously. (added 2.4.5) 332 | * Default: 3. 333 | * 334 | * var @integer 335 | */ 336 | 'userCameraCap' => 3, 337 | ], 338 | 'join' => [ 339 | /** 340 | * var @bool. 341 | */ 342 | 'redirect' => true, 343 | ], 344 | 'getRecordings' => [ 345 | /** 346 | * if the recording is [processing|processed|published|unpublished|deleted]. 347 | * The parameter state can be used to filter results. It can be a set of states separate by commas. 348 | * If it is not specified only the states [published|unpublished] are considered 349 | * (same as in previous versions). If it is specified as “any”, 350 | * recordings in all states are included. 351 | * 352 | * var @string 353 | */ 354 | 'state' => 'any', //'published,unpublished' 355 | ], 356 | ]; 357 | -------------------------------------------------------------------------------- /src/Bbb.php: -------------------------------------------------------------------------------- 1 | bbb = $bbb; 45 | } 46 | 47 | /** 48 | * for specific server instance. 49 | * 50 | * @param $serverName 51 | * @return Bbb 52 | * 53 | * @throws \Exception 54 | */ 55 | public function server($serverName) 56 | { 57 | if (is_null(config("bigbluebutton.servers.{$serverName}", null))) { 58 | throw new \Exception("Could not found {$serverName} server configuration in config file"); 59 | } 60 | 61 | return new self( 62 | new BigBlueButtonServer( 63 | config("bigbluebutton.servers.{$serverName}.BBB_SERVER_BASE_URL"), 64 | config("bigbluebutton.servers.{$serverName}.BBB_SECURITY_SALT") 65 | ) 66 | ); 67 | } 68 | 69 | /** 70 | * @return self 71 | */ 72 | public function make() 73 | { 74 | return $this; 75 | } 76 | 77 | /** 78 | * @return BigBlueButton 79 | */ 80 | public function source() 81 | { 82 | return $this->bbb; 83 | } 84 | 85 | /** 86 | * check url and secret is working. 87 | * 88 | * @return bool 89 | */ 90 | public function isConnect() 91 | { 92 | return $this->bbb->isConnectionWorking(); 93 | } 94 | 95 | /** 96 | * Return a list of all meetings. 97 | * 98 | * @return \Illuminate\Support\Collection 99 | */ 100 | public function all() 101 | { 102 | $this->response = $this->bbb->getMeetings(); 103 | if ($this->response->success()) { 104 | if (! is_null($this->response->getRawXml()->meetings->meeting) && count($this->response->getRawXml()->meetings->meeting) > 0) { 105 | $meetings = []; 106 | foreach ($this->response->getRawXml()->meetings->meeting as $meeting) { 107 | $meetings[] = XmlToArray($meeting); 108 | } 109 | 110 | return collect(XmlToArray($meetings)); 111 | } 112 | } 113 | 114 | return collect([]); 115 | } 116 | 117 | /** 118 | * $meeting. 119 | * 120 | * @param $meeting 121 | * 122 | * required fields 123 | * meetingID 124 | * meetingName 125 | * @return mixed 126 | */ 127 | public function create($meeting) 128 | { 129 | if (! $meeting instanceof CreateMeetingParameters) { 130 | $meeting = $this->initCreateMeeting($meeting); 131 | } 132 | 133 | $this->response = $this->bbb->createMeeting($meeting); 134 | if ($this->response->failed()) { 135 | return $this->response->getMessage(); 136 | } else { 137 | return collect(XmlToArray($this->response->getRawXml())); 138 | } 139 | } 140 | 141 | /** 142 | * @param $meeting 143 | * 144 | * required fields: 145 | * meetingID 146 | * @return bool 147 | */ 148 | public function isMeetingRunning($meeting) 149 | { 150 | if (! $meeting instanceof IsMeetingRunningParameters) { 151 | $meeting = $this->initIsMeetingRunning($meeting); 152 | } 153 | 154 | $this->response = $this->bbb->isMeetingRunning($meeting); 155 | if ($this->response->success()) { 156 | $response = XmlToArray($this->response->getRawXml()); 157 | if (isset($response['running']) && $response['running'] == 'true') { 158 | return true; 159 | } 160 | } 161 | 162 | return false; 163 | } 164 | 165 | /** 166 | * Join meeting. 167 | * 168 | * @param $meeting 169 | * required fields 170 | * 171 | * meetingID 172 | * userName join by name 173 | * password which role want to join 174 | * @return string 175 | */ 176 | public function join($meeting) 177 | { 178 | if (! $meeting instanceof JoinMeetingParameters) { 179 | $meeting = $this->initJoinMeeting($meeting); 180 | } 181 | 182 | if ($meeting->isRedirect()) { 183 | return $this->bbb->getJoinMeetingURL($meeting); 184 | } 185 | 186 | return $this->bbb->joinMeeting($meeting)->getUrl(); 187 | } 188 | 189 | /** 190 | * Returns information about the meeting. 191 | * 192 | * @param $meeting 193 | * required fields 194 | * meetingID 195 | * moderatorPW must be there moderator password 196 | * @return \Illuminate\Support\Collection 197 | */ 198 | public function getMeetingInfo($meeting) 199 | { 200 | if (! $meeting instanceof GetMeetingInfoParameters) { 201 | $meeting = $this->initGetMeetingInfo($meeting); 202 | } 203 | 204 | $this->response = $this->bbb->getMeetingInfo($meeting); 205 | if ($this->response->success()) { 206 | return collect(XmlToArray($this->response->getRawXml())); 207 | } 208 | 209 | return collect([]); 210 | } 211 | 212 | /** 213 | * @param $parameters 214 | * 215 | * required fields 216 | * meetingID 217 | * meetingName 218 | * userName 219 | * attendeePW 220 | * moderatorPW 221 | * @return mixed 222 | */ 223 | public function start($parameters) 224 | { 225 | return $this->initStart($parameters); 226 | } 227 | 228 | /** 229 | * Close meeting. 230 | * 231 | * @param $meeting 232 | * required fields: 233 | * meetingID 234 | * moderatorPW close meeting must be there moderator password 235 | * @return bool 236 | */ 237 | public function close($meeting) 238 | { 239 | if (! $meeting instanceof EndMeetingParameters) { 240 | $meeting = $this->initCloseMeeting($meeting); 241 | } 242 | 243 | $this->response = $this->bbb->endMeeting($meeting); 244 | if ($this->response->success()) { 245 | return true; 246 | } 247 | 248 | return false; 249 | } 250 | 251 | /** 252 | * @param $recording 253 | * required fields 254 | * meetingID 255 | * 256 | * optional fields 257 | * recordID 258 | * state 259 | * @return \Illuminate\Support\Collection 260 | */ 261 | public function getRecordings($recording) 262 | { 263 | if (! $recording instanceof GetRecordingsParameters) { 264 | $recording = $this->initGetRecordings($recording); 265 | } 266 | 267 | $this->response = $this->bbb->getRecordings($recording); 268 | if ($this->response->success() && ! is_null($this->response->getRawXml()->recordings->recording) && count($this->response->getRawXml()->recordings->recording) > 0) { 269 | $recordings = []; 270 | foreach ($this->response->getRawXml()->recordings->recording as $r) { 271 | $recordings[] = XmlToArray($r); 272 | } 273 | 274 | return collect($recordings); 275 | } 276 | 277 | return collect([]); 278 | } 279 | 280 | /** 281 | * @param $recording 282 | * recordID as string(separated by comma) 283 | * publish as bool 284 | * @return bool 285 | */ 286 | public function publishRecordings($recording) 287 | { 288 | if (! $recording instanceof PublishRecordingsParameters) { 289 | $recording = $this->initPublishRecordings($recording); 290 | } 291 | 292 | $this->response = $this->bbb->publishRecordings($recording); 293 | if ($this->response->success()) { 294 | $response = XmlToArray($this->response->getRawXml()); 295 | if (isset($response['published']) && $response['published'] == 'true') { 296 | return true; 297 | } 298 | } 299 | 300 | return false; 301 | } 302 | 303 | /** 304 | * @param $recording 305 | * 306 | * required fields 307 | * recordingID 308 | * @return \Illuminate\Support\Collection 309 | */ 310 | public function deleteRecordings($recording) 311 | { 312 | if (! $recording instanceof DeleteRecordingsParameters) { 313 | $recording = $this->initDeleteRecordings($recording); 314 | } 315 | 316 | $this->response = $this->bbb->deleteRecordings($recording); 317 | 318 | return collect(XmlToArray($this->response->getRawXml())); 319 | } 320 | 321 | /** 322 | * @param $recording 323 | * 324 | * required fields 325 | * recordingID 326 | * @return \Illuminate\Support\Collection 327 | */ 328 | public function updateRecordings($recording) 329 | { 330 | if (! $recording instanceof UpdateRecordingsParameters) { 331 | $recording = $this->initUpdateRecordings($recording); 332 | } 333 | 334 | $this->response = $this->bbb->updateRecordings($recording); 335 | 336 | return collect(XmlToArray($this->response->getRawXml())); 337 | } 338 | 339 | /** 340 | * @return \Illuminate\Support\Collection 341 | */ 342 | public function getApiVersion() 343 | { 344 | $this->response = $this->bbb->getApiVersion(); 345 | 346 | return collect(XmlToArray($this->response->getRawXml())); 347 | } 348 | 349 | /** 350 | * @param $hooks 351 | * @return \Illuminate\Support\Collection 352 | */ 353 | public function hooksCreate($hooks) 354 | { 355 | if (! $hooks instanceof HooksCreateParameters) { 356 | $hooks = $this->initHooksCreate($hooks); 357 | } 358 | 359 | $this->response = $this->bbb->hooksCreate($hooks); 360 | 361 | return collect(XmlToArray($this->response->getRawXml())); 362 | } 363 | 364 | /** 365 | * @param $hooks 366 | * @return \Illuminate\Support\Collection 367 | */ 368 | public function hooksDestroy($hooks) 369 | { 370 | if (! $hooks instanceof HooksDestroyParameters) { 371 | $hooks = $this->initHooksDestroy($hooks); 372 | } 373 | 374 | $this->response = $this->bbb->hooksDestroy($hooks); 375 | 376 | return collect(XmlToArray($this->response->getRawXml())); 377 | } 378 | } 379 | -------------------------------------------------------------------------------- /src/Bigbluebutton.php: -------------------------------------------------------------------------------- 1 | bbbServerBaseUrl = Str::finish(trim($bbbServerBaseUrl), '/'); 23 | $this->securitySecret = trim($securitySecret); 24 | $this->urlBuilder = new UrlBuilder($this->securitySecret, $this->bbbServerBaseUrl, config('bigbluebutton.hash_algorithm', 'sha1')); 25 | $this->transport = $transport ?? CurlTransport::createWithDefaultOptions(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/BigbluebuttonServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 15 | $this->publishes([ 16 | __DIR__.'/../config/bigbluebutton.php' => config_path('bigbluebutton.php'), 17 | ], 'bigbluebutton-config'); 18 | } 19 | } 20 | 21 | /** 22 | * Register the application services. 23 | */ 24 | public function register() 25 | { 26 | $this->mergeConfigFrom(__DIR__.'/../config/bigbluebutton.php', 'bigbluebutton'); 27 | 28 | $this->app->singleton('Bigbluebutton', function () { 29 | return new Bbb( 30 | new Bigbluebutton( 31 | $this->app['config']->get('bigbluebutton.BBB_SERVER_BASE_URL'), 32 | $this->app['config']->get('bigbluebutton.BBB_SECURITY_SALT') 33 | ) 34 | ); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Facades/Bigbluebutton.php: -------------------------------------------------------------------------------- 1 | get('callbackURL')); 25 | if (! empty($parameters->get('meetingID'))) { 26 | $hooksCreate->setMeetingID($parameters->meetingID); 27 | } 28 | $hooksCreate->setGetRaw($parameters->get('getRaw', false)); 29 | 30 | return $hooksCreate; 31 | } 32 | 33 | /** 34 | * @param mixed $parameters 35 | * @return HooksDestroyParameters 36 | */ 37 | public function initHooksDestroy($parameters) 38 | { 39 | $hooksID = ''; 40 | if (is_array($parameters)) { 41 | $hooksID = Fluent($parameters)->get('hooksID'); 42 | } else { 43 | $hooksID = $parameters; 44 | } 45 | 46 | return new HooksDestroyParameters($hooksID); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Services/InitMeeting.php: -------------------------------------------------------------------------------- 1 | get('meetingID', Str::uuid()), 30 | $request->get('meetingName', 'default meeting name '.Str::random(7)) 31 | ); 32 | $meetingParams->setModeratorPW($request->get('moderatorPW', Str::random(config('bigbluebutton.create.passwordLength', 8)))); 33 | $meetingParams->setAttendeePW($request->get('attendeePW', Str::random(config('bigbluebutton.create.passwordLength', 8)))); 34 | $meetingParams->setDuration($request->get('duration', config('bigbluebutton.create.duration', 0))); 35 | $meetingParams->setRecord($request->get('record', config('bigbluebutton.create.record', false))); 36 | $meetingParams->setMaxParticipants($request->get('maxParticipants', config('bigbluebutton.create.maxParticipants', 0))); 37 | if (! is_null($request->get('logoutUrl', config('bigbluebutton.create.logoutUrl', null)))) { 38 | $meetingParams->setLogoutURL($request->get('logoutUrl', config('bigbluebutton.create.logoutUrl', null))); 39 | } 40 | $meetingParams->setGuestPolicy( 41 | $request->get('guestPolicy', config('bigbluebutton.create.guestPolicy', 'ALWAYS_ACCEPT')) 42 | ); 43 | if (! is_null($request->get('welcomeMessage', config('bigbluebutton.create.welcomeMessage', null)))) { 44 | $meetingParams->setWelcome( 45 | $request->get('welcomeMessage', config('bigbluebutton.create.welcomeMessage', null)) 46 | ); 47 | } 48 | if (! is_null($request->get('welcome', config('bigbluebutton.create.welcomeMessage', null)))) { 49 | $meetingParams->setWelcome( 50 | $request->get('welcome', config('bigbluebutton.create.welcomeMessage', null)) 51 | ); 52 | } 53 | $meetingParams->setDialNumber( 54 | $request->get('dialNumber', config('bigbluebutton.create.dialNumber', null)) 55 | ); 56 | 57 | if (! empty($request->get('voiceBridge'))) { 58 | $meetingParams->setVoiceBridge( 59 | $request->get('voiceBridge', null) 60 | ); 61 | } 62 | 63 | $meetingParams->setBreakout( 64 | $request->get('isBreakout', config('bigbluebutton.create.isBreakout', false)) 65 | ); 66 | 67 | $meetingParams->setParentMeetingID( 68 | $request->get('parentMeetingID', '') 69 | ); 70 | 71 | $meetingParams->setSequence( 72 | $request->get('sequence', rand(1, 10000)) 73 | ); 74 | 75 | $meetingParams->setModeratorOnlyMessage( 76 | $request->get('moderatorOnlyMessage', config('bigbluebutton.create.moderatorOnlyMessage', null)) 77 | ); 78 | $meetingParams->setAutoStartRecording( 79 | $request->get('autoStartRecording', config('bigbluebutton.create.autoStartRecording', false)) 80 | ); 81 | $meetingParams->setAllowStartStopRecording( 82 | $request->get('allowStartStopRecording', config('bigbluebutton.create.allowStartStopRecording', true)) 83 | ); 84 | $meetingParams->setWebcamsOnlyForModerator( 85 | $request->get('webcamsOnlyForModerator', config('bigbluebutton.create.webcamsOnlyForModerator', false)) 86 | ); 87 | $meetingParams->setBannerText( 88 | $request->get('bannerText', config('bigbluebutton.create.bannerText', null)) 89 | ); 90 | $meetingParams->setBannerColor( 91 | $request->get('bannerColor', null) 92 | ); 93 | $meetingParams->setLogo( 94 | $request->get('logo', config('bigbluebutton.create.logo', null)) 95 | ); 96 | $meetingParams->setCopyright( 97 | $request->get('copyright', config('bigbluebutton.create.copyright', null)) 98 | ); 99 | $meetingParams->setMuteOnStart( 100 | $request->get('muteOnStart', config('bigbluebutton.create.muteOnStart', false)) 101 | ); 102 | $meetingParams->setAllowModsToUnmuteUsers( 103 | $request->get('allowModsToUnmuteUsers', config('bigbluebutton.create.allowModsToUnmuteUsers', false)) 104 | ); 105 | $meetingParams->setLockSettingsDisableCam( 106 | $request->get('lockSettingsDisableCam', config('bigbluebutton.create.lockSettingsDisableCam', false)) 107 | ); 108 | $meetingParams->setLockSettingsDisableMic( 109 | $request->get('lockSettingsDisableMic', config('bigbluebutton.create.lockSettingsDisableMic', false)) 110 | ); 111 | $meetingParams->setLockSettingsDisablePrivateChat( 112 | $request->get('lockSettingsDisablePrivateChat', config('bigbluebutton.create.lockSettingsDisablePrivateChat', false)) 113 | ); 114 | $meetingParams->setLockSettingsDisablePublicChat( 115 | $request->get('lockSettingsDisablePublicChat', config('bigbluebutton.create.lockSettingsDisablePublicChat', false)) 116 | ); 117 | $meetingParams->setLockSettingsDisableNote( 118 | $request->get('lockSettingsDisableNote', config('bigbluebutton.create.lockSettingsDisableNote', false)) 119 | ); 120 | $meetingParams->setLockSettingsLockedLayout( 121 | $request->get('lockSettingsLockedLayout', config('bigbluebutton.create.lockSettingsLockedLayout', false)) 122 | ); 123 | $meetingParams->setLockSettingsLockOnJoin( 124 | $request->get('lockSettingsLockOnJoin', config('bigbluebutton.create.lockSettingsLockOnJoin', false)) 125 | ); 126 | $meetingParams->setLockSettingsLockOnJoinConfigurable( 127 | $request->get('lockSettingsLockOnJoinConfigurable', config('bigbluebutton.create.lockSettingsLockOnJoinConfigurable', false)) 128 | ); 129 | $meetingParams->setMeetingKeepEvents( 130 | $request->get('meetingKeepEvents', config('bigbluebutton.create.meetingKeepEvents', false)) 131 | ); 132 | $meetingParams->setEndWhenNoModerator( 133 | $request->get('endWhenNoModerator', config('bigbluebutton.create.endWhenNoModerator', false)) 134 | ); 135 | $meetingParams->setEndWhenNoModeratorDelayInMinutes( 136 | $request->get('endWhenNoModeratorDelayInMinutes', config('bigbluebutton.create.endWhenNoModeratorDelayInMinutes', 1)) 137 | ); 138 | $meetingParams->setMeetingLayout( 139 | $request->get('meetingLayout', config('bigbluebutton.create.meetingLayout', 'SMART_LAYOUT')) 140 | ); 141 | $meetingParams->setLearningDashboardCleanupDelayInMinutes( 142 | $request->get('learningDashboardCleanupDelayInMinutes', config('bigbluebutton.create.learningDashboardCleanupDelayInMinutes', 2)) 143 | ); 144 | $meetingParams->setAllowModsToEjectCameras( 145 | $request->get('allowModsToEjectCameras', config('bigbluebutton.create.allowModsToEjectCameras', false)) 146 | ); 147 | $meetingParams->setAllowRequestsWithoutSession( 148 | $request->get('allowRequestsWithoutSession', config('bigbluebutton.create.allowRequestsWithoutSession', false)) 149 | ); 150 | $meetingParams->setUserCameraCap( 151 | $request->get('userCameraCap', config('bigbluebutton.create.userCameraCap', 3)) 152 | ); 153 | if (! is_null($request->get('endCallbackUrl', null))) { 154 | $meetingParams->setEndCallbackUrl($request->get('endCallbackUrl', null)); 155 | } 156 | 157 | if (! is_null($request->get('bbb-recording-ready-url', null))) { 158 | $meetingParams->setRecordingReadyCallbackUrl($request->get('bbb-recording-ready-url', null)); 159 | } 160 | 161 | $meetingParams->setFreeJoin($request->get('freeJoin', false)); 162 | 163 | $presentation = (array) $request->get('presentation', null); 164 | foreach ($presentation as $item) { 165 | if (isset($item['fileName']) && ! empty($item['fileName'])) { 166 | if (isset($item['link']) && ! empty($item['link'])) { 167 | $meetingParams->addPresentation(trim($item['link']), null, trim($item['fileName'])); 168 | } elseif (isset($item['content']) && ! empty($item['content'])) { 169 | $meetingParams->addPresentation(trim($item['fileName']), trim($item['content']), null); 170 | } 171 | } 172 | } 173 | 174 | $meta = (array) $request->get('meta', null); 175 | foreach ($meta as $key => $value) { 176 | $meetingParams->addMeta(trim($key), trim($value)); 177 | } 178 | 179 | return $meetingParams; 180 | } 181 | 182 | /** 183 | * @param array $parameters 184 | * 185 | * required fields: 186 | * meetingID 187 | * moderatorPW close meeting must be there moderator password 188 | * @return EndMeetingParameters 189 | */ 190 | public function initCloseMeeting(array $parameters) 191 | { 192 | $request = Fluent($parameters); 193 | 194 | return new EndMeetingParameters($request->meetingID, $request->moderatorPW); 195 | } 196 | 197 | /** 198 | * @param array $parameters 199 | * 200 | * required fields 201 | * 202 | * meetingID 203 | * userName join by name 204 | * password which role want to join 205 | * @return JoinMeetingParameters 206 | */ 207 | public function initJoinMeeting(array $parameters) 208 | { 209 | $request = Fluent($parameters); 210 | $meetingParams = new JoinMeetingParameters($request->meetingID, $request->userName, $request->password); 211 | if (! empty($request->get('role'))) { 212 | $meetingParams->setRole($request->get('role')); 213 | } 214 | $meetingParams->setRedirect($request->get('redirect', config('bigbluebutton.join.redirect', true))); 215 | if (! is_null($request->get('userId'))) { 216 | $meetingParams->setUserID($request->get('userId')); 217 | } 218 | if (! is_null($request->get('userID'))) { 219 | $meetingParams->setUserID($request->get('userID')); 220 | } 221 | if (! empty($request->get('createTime'))) { 222 | $meetingParams->setCreateTime($request->get('createTime')); 223 | } 224 | if (! empty($request->get('defaultLayout'))) { 225 | $meetingParams->setDefaultLayout($request->get('defaultLayout')); 226 | } 227 | if (! empty($request->get('configToken'))) { 228 | $meetingParams->setConfigToken($request->get('configToken')); 229 | } 230 | if (! empty($request->get('webVoiceConf'))) { 231 | $meetingParams->setWebVoiceConf($request->get('webVoiceConf')); 232 | } 233 | if (! empty($request->get('avatarUrl'))) { 234 | $meetingParams->setAvatarURL($request->get('avatarUrl')); 235 | } 236 | if (! empty($request->get('clientUrl'))) { 237 | $meetingParams->setClientURL($request->get('clientUrl')); 238 | } 239 | if (! empty($request->get('guest'))) { 240 | $meetingParams->setGuest($request->get('guest')); 241 | } 242 | if (! empty($request->get('excludeFromDashboard'))) { 243 | $meetingParams->setExcludeFromDashboard($request->get('excludeFromDashboard')); 244 | } 245 | if ($request->customParameters && is_array($request->customParameters)) { 246 | foreach ($request->customParameters as $key => $value) { 247 | $meetingParams->addUserData($key, $value); 248 | } 249 | } 250 | if (! empty($request->get('errorRedirectUrl'))) { 251 | $meetingParams->setErrorRedirectUrl($request->get('errorRedirectUrl')); 252 | } 253 | 254 | return $meetingParams; 255 | } 256 | 257 | /** 258 | * @param $parameters 259 | * 260 | * required fields 261 | * meetingID 262 | * @return IsMeetingRunningParameters 263 | */ 264 | public function initIsMeetingRunning($parameters) 265 | { 266 | $meetingID = ''; 267 | if (is_array($parameters)) { 268 | $meetingID = Fluent($parameters)->get('meetingID'); 269 | } else { 270 | $meetingID = $parameters; 271 | } 272 | 273 | return new IsMeetingRunningParameters($meetingID); 274 | } 275 | 276 | /** 277 | * @param $parameters 278 | * 279 | * required fields 280 | * meetingID 281 | * moderatorPW must be there moderator password 282 | * @return GetMeetingInfoParameters 283 | */ 284 | public function initGetMeetingInfo($parameters) 285 | { 286 | $request = Fluent($parameters); 287 | 288 | return new GetMeetingInfoParameters($request->meetingID, $request->moderatorPW); 289 | } 290 | 291 | private function makeJoinMeetingArray($object, $parameters) 292 | { 293 | $pass['meetingID'] = $object->get('meetingID'); 294 | $pass['password'] = $object->get('moderatorPW'); 295 | if (isset($parameters['userName'])) { 296 | $pass['userName'] = $parameters['userName']; 297 | } 298 | if (isset($parameters['meetingName'])) { 299 | $pass['meetingName'] = $parameters['meetingName']; 300 | } else { 301 | $pass['meetingName'] = $object->get('meetingName'); 302 | } 303 | if (isset($parameters['redirect'])) { 304 | $pass['redirect'] = $parameters['redirect']; 305 | } 306 | 307 | $exceptParameters = ['meetingID', 'moderatorPW', 'userName', 'meetingName', 'redirect']; 308 | if (is_array($parameters)) { 309 | foreach ($parameters as $key => $value) { 310 | if (! empty($key) && is_string($key) && ! empty($value) && ! in_array($key, $exceptParameters)) { 311 | $pass[$key] = $value; 312 | } 313 | } 314 | } 315 | 316 | return $pass; 317 | } 318 | 319 | /** 320 | * @param array $parameters 321 | * 322 | * required fields 323 | * meetingID 324 | * meetingName 325 | * userName 326 | * attendeePW 327 | * moderatorPW 328 | * @return mixed 329 | */ 330 | public function initStart(array $parameters) 331 | { 332 | if ($this->getMeetingInfo($parameters)->isEmpty()) { 333 | $object = $this->create($parameters); 334 | 335 | if (method_exists($object, 'isEmpty') && ! $object->isEmpty()) { 336 | return $this->join($this->makeJoinMeetingArray($object, $parameters)); 337 | } 338 | } else { 339 | if (isset($parameters['moderatorPW'])) { 340 | $parameters['password'] = trim($parameters['moderatorPW']); 341 | } 342 | 343 | return $this->join($parameters); 344 | } 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /src/Services/InitRecordings.php: -------------------------------------------------------------------------------- 1 | setMeetingID(implode(',', (array) $request->get('meetingID'))); 27 | $recordings->setRecordID(implode(',', (array) $request->get('recordID'))); 28 | $recordings->setState($request->get('state', config('bigbluebutton.getRecordings.state'))); 29 | 30 | return $recordings; 31 | } 32 | 33 | /** 34 | * @param mixed $parameters 35 | * 36 | * required fields 37 | * recordID 38 | * @return PublishRecordingsParameters 39 | */ 40 | public function initPublishRecordings($parameters) 41 | { 42 | $request = Fluent($parameters); 43 | 44 | return new PublishRecordingsParameters( 45 | implode(',', (array) $request->get('recordID')), 46 | $request->get('publish', true) 47 | ); 48 | } 49 | 50 | /** 51 | * @param mixed $recording 52 | * 53 | * required fields 54 | * recordID 55 | * @return DeleteRecordingsParameters 56 | */ 57 | public function initDeleteRecordings($recording) 58 | { 59 | $request = Fluent($recording); 60 | 61 | return new DeleteRecordingsParameters(implode(',', (array) $request->get('recordID'))); 62 | } 63 | 64 | /** 65 | * @param mixed $recording 66 | * 67 | * required fields 68 | * recordID 69 | * @return UpdateRecordingsParameters 70 | */ 71 | public function initUpdateRecordings($recording) 72 | { 73 | $request = Fluent($recording); 74 | 75 | return new UpdateRecordingsParameters(implode(',', (array) $request->get('recordID'))); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/helpers.php: -------------------------------------------------------------------------------- 1 | server($serverName); 36 | } 37 | } 38 | 39 | if (! function_exists('XmlToObject')) { 40 | function XmlToObject($xml) 41 | { 42 | return Fluent(XmlToArray($xml)); 43 | } 44 | } 45 | --------------------------------------------------------------------------------