amazon-chime-sdk-rails 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +87 -0
- data/.rspec +2 -0
- data/.travis.yml +47 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +25 -0
- data/LICENSE +21 -0
- data/README.md +1109 -0
- data/Rakefile +20 -0
- data/amazon-chime-sdk-rails.gemspec +29 -0
- data/gemfiles/Gemfile.rails-5.0 +25 -0
- data/gemfiles/Gemfile.rails-5.1 +25 -0
- data/gemfiles/Gemfile.rails-5.2 +25 -0
- data/gemfiles/Gemfile.rails-6.0 +25 -0
- data/lib/amazon-chime-sdk-rails.rb +37 -0
- data/lib/chime_sdk/config.rb +90 -0
- data/lib/chime_sdk/controller/attendees.rb +128 -0
- data/lib/chime_sdk/controller/common.rb +202 -0
- data/lib/chime_sdk/controller/meetings.rb +192 -0
- data/lib/chime_sdk/meeting_coordinator.rb +184 -0
- data/lib/chime_sdk/version.rb +4 -0
- data/lib/generators/chime_sdk/controllers_generator.rb +104 -0
- data/lib/generators/chime_sdk/install_generator.rb +27 -0
- data/lib/generators/chime_sdk/js_generator.rb +67 -0
- data/lib/generators/chime_sdk/views_generator.rb +43 -0
- data/lib/generators/templates/chime_sdk.rb +28 -0
- data/lib/generators/templates/controllers/README +35 -0
- data/lib/generators/templates/controllers/meeting_attendees_controller.rb +106 -0
- data/lib/generators/templates/controllers/meetings_controller.rb +146 -0
- data/lib/generators/templates/views/meetings/index.html.erb +27 -0
- data/lib/generators/templates/views/meetings/show.html.erb +136 -0
- data/spec/factories/rooms.rb +5 -0
- data/spec/factories/users.rb +8 -0
- data/spec/generators/controllers_generator_spec.rb +113 -0
- data/spec/generators/install_generator_spec.rb +24 -0
- data/spec/generators/js_generator_spec.rb +26 -0
- data/spec/generators/views_generator_spec.rb +46 -0
- data/spec/rails_app/Rakefile +15 -0
- data/spec/rails_app/app/assets/config/manifest.js +2 -0
- data/spec/rails_app/app/assets/images/.keep +0 -0
- data/spec/rails_app/app/assets/javascripts/.keep +0 -0
- data/spec/rails_app/app/assets/stylesheets/application.css +15 -0
- data/spec/rails_app/app/assets/stylesheets/scaffolds.scss +65 -0
- data/spec/rails_app/app/controllers/api/meeting_attendees_controller.rb +3 -0
- data/spec/rails_app/app/controllers/api/meetings_controller.rb +3 -0
- data/spec/rails_app/app/controllers/api/rooms_controller.rb +3 -0
- data/spec/rails_app/app/controllers/application_controller.rb +11 -0
- data/spec/rails_app/app/controllers/entries_controller.rb +47 -0
- data/spec/rails_app/app/controllers/meeting_attendees_controller.rb +121 -0
- data/spec/rails_app/app/controllers/meetings_controller.rb +162 -0
- data/spec/rails_app/app/controllers/rooms_controller.rb +76 -0
- data/spec/rails_app/app/controllers/spa_controller.rb +6 -0
- data/spec/rails_app/app/javascript/App.vue +50 -0
- data/spec/rails_app/app/javascript/channels/consumer.js +6 -0
- data/spec/rails_app/app/javascript/channels/index.js +5 -0
- data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +84 -0
- data/spec/rails_app/app/javascript/components/meetings/Index.vue +100 -0
- data/spec/rails_app/app/javascript/components/meetings/Meeting.vue +178 -0
- data/spec/rails_app/app/javascript/components/rooms/Index.vue +53 -0
- data/spec/rails_app/app/javascript/components/rooms/Show.vue +91 -0
- data/spec/rails_app/app/javascript/packs/application.js +17 -0
- data/spec/rails_app/app/javascript/packs/spa.js +14 -0
- data/spec/rails_app/app/javascript/router/index.js +74 -0
- data/spec/rails_app/app/javascript/store/index.js +37 -0
- data/spec/rails_app/app/models/application_record.rb +3 -0
- data/spec/rails_app/app/models/entry.rb +5 -0
- data/spec/rails_app/app/models/room.rb +12 -0
- data/spec/rails_app/app/models/user.rb +6 -0
- data/spec/rails_app/app/views/devise/registrations/new.html.erb +34 -0
- data/spec/rails_app/app/views/layouts/_header.html.erb +20 -0
- data/spec/rails_app/app/views/layouts/application.html.erb +18 -0
- data/spec/rails_app/app/views/meetings/index.html.erb +28 -0
- data/spec/rails_app/app/views/meetings/show.html.erb +136 -0
- data/spec/rails_app/app/views/rooms/_form.html.erb +22 -0
- data/spec/rails_app/app/views/rooms/_room.json.jbuilder +7 -0
- data/spec/rails_app/app/views/rooms/edit.html.erb +6 -0
- data/spec/rails_app/app/views/rooms/index.html.erb +27 -0
- data/spec/rails_app/app/views/rooms/index.json.jbuilder +1 -0
- data/spec/rails_app/app/views/rooms/new.html.erb +5 -0
- data/spec/rails_app/app/views/rooms/show.html.erb +42 -0
- data/spec/rails_app/app/views/rooms/show.json.jbuilder +1 -0
- data/spec/rails_app/app/views/spa/index.html.erb +1 -0
- data/spec/rails_app/babel.config.js +72 -0
- data/spec/rails_app/bin/bundle +114 -0
- data/spec/rails_app/bin/rails +9 -0
- data/spec/rails_app/bin/rake +9 -0
- data/spec/rails_app/bin/setup +36 -0
- data/spec/rails_app/bin/spring +17 -0
- data/spec/rails_app/bin/webpack +18 -0
- data/spec/rails_app/bin/webpack-dev-server +18 -0
- data/spec/rails_app/bin/yarn +11 -0
- data/spec/rails_app/config.ru +5 -0
- data/spec/rails_app/config/application.rb +21 -0
- data/spec/rails_app/config/boot.rb +4 -0
- data/spec/rails_app/config/cable.yml +10 -0
- data/spec/rails_app/config/credentials.yml.enc +1 -0
- data/spec/rails_app/config/database.yml +25 -0
- data/spec/rails_app/config/environment.rb +14 -0
- data/spec/rails_app/config/environments/development.rb +62 -0
- data/spec/rails_app/config/environments/production.rb +112 -0
- data/spec/rails_app/config/environments/test.rb +49 -0
- data/spec/rails_app/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/rails_app/config/initializers/assets.rb +15 -0
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_app/config/initializers/chime_sdk.rb +28 -0
- data/spec/rails_app/config/initializers/content_security_policy.rb +30 -0
- data/spec/rails_app/config/initializers/cookies_serializer.rb +5 -0
- data/spec/rails_app/config/initializers/devise.rb +311 -0
- data/spec/rails_app/config/initializers/devise_token_auth.rb +60 -0
- data/spec/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/rails_app/config/initializers/inflections.rb +16 -0
- data/spec/rails_app/config/initializers/mime_types.rb +4 -0
- data/spec/rails_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/rails_app/config/locales/devise.en.yml +65 -0
- data/spec/rails_app/config/locales/en.yml +33 -0
- data/spec/rails_app/config/puma.rb +38 -0
- data/spec/rails_app/config/routes.rb +24 -0
- data/spec/rails_app/config/secrets.yml +8 -0
- data/spec/rails_app/config/spring.rb +6 -0
- data/spec/rails_app/config/storage.yml +34 -0
- data/spec/rails_app/config/webpack/development.js +5 -0
- data/spec/rails_app/config/webpack/environment.js +7 -0
- data/spec/rails_app/config/webpack/loaders/vue.js +6 -0
- data/spec/rails_app/config/webpack/production.js +5 -0
- data/spec/rails_app/config/webpack/test.js +5 -0
- data/spec/rails_app/config/webpacker.yml +97 -0
- data/spec/rails_app/db/migrate/20200912140231_devise_create_users.rb +45 -0
- data/spec/rails_app/db/migrate/20200912140352_add_tokens_to_users.rb +12 -0
- data/spec/rails_app/db/migrate/20200912140657_create_rooms.rb +9 -0
- data/spec/rails_app/db/migrate/20200912140749_create_entries.rb +10 -0
- data/spec/rails_app/db/schema.rb +49 -0
- data/spec/rails_app/db/seeds.rb +41 -0
- data/spec/rails_app/log/.keep +0 -0
- data/spec/rails_app/package.json +23 -0
- data/spec/rails_app/postcss.config.js +12 -0
- data/spec/rails_app/public/404.html +67 -0
- data/spec/rails_app/public/422.html +67 -0
- data/spec/rails_app/public/500.html +66 -0
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/rails_app/public/robots.txt +1 -0
- data/spec/rails_app/tmp/.keep +0 -0
- data/spec/requests/atendees_spec.rb +182 -0
- data/spec/requests/meetings_spec.rb +433 -0
- data/spec/spec_helper.rb +35 -0
- metadata +400 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 58ba4a5120f7627c132916b953a9220df353788aef966f2a56f8915c3a0a9ef6
|
|
4
|
+
data.tar.gz: 2b59830799578d63ad1d87ec4cf5754be896974a7726ced42be3139adcedfd50
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: b36d2ecafa05d835679ef5e7c8351a7c45f31b996010253b62fca9cc6b7cb0288fd3a0f4cbc5f985c654491afbd7d546acd98d409381d8805ab29e0199047271
|
|
7
|
+
data.tar.gz: e233e6b6f840da4b8b3eb7186a2b279112c39bfc0352a1fb83075a46a90c74acea25abbab2d8d8e0b9ec7a677b4e5335f4326156d8196338806ca6668c2a93f8
|
data/.gitignore
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
*.rbc
|
|
2
|
+
capybara-*.html
|
|
3
|
+
/spec/rails_app/db/*.sqlite3
|
|
4
|
+
/spec/rails_app/db/*.sqlite3-journal
|
|
5
|
+
/spec/rails_app/db/*.sqlite3-[0-9]*
|
|
6
|
+
/spec/rails_app/public/system
|
|
7
|
+
/coverage/
|
|
8
|
+
/tmp/
|
|
9
|
+
/spec/rails_app/spec/tmp
|
|
10
|
+
*.orig
|
|
11
|
+
rerun.txt
|
|
12
|
+
pickle-email-*.html
|
|
13
|
+
/Gemfile.lock
|
|
14
|
+
/gemfiles/Gemfile*.lock
|
|
15
|
+
|
|
16
|
+
# Ignore all logfiles and tempfiles.
|
|
17
|
+
/spec/rails_app/log/*
|
|
18
|
+
/spec/rails_app/tmp/*
|
|
19
|
+
!/spec/rails_app/log/.keep
|
|
20
|
+
!/spec/rails_app/tmp/.keep
|
|
21
|
+
|
|
22
|
+
# TODO Comment out this rule if you are OK with secrets being uploaded to the repo
|
|
23
|
+
/spec/rails_app/config/initializers/secret_token.rb
|
|
24
|
+
/spec/rails_app/config/master.key
|
|
25
|
+
|
|
26
|
+
# Only include if you have production secrets in this file, which is no longer a Rails default
|
|
27
|
+
# config/secrets.yml
|
|
28
|
+
|
|
29
|
+
# dotenv
|
|
30
|
+
# TODO Comment out this rule if environment variables can be committed
|
|
31
|
+
.env
|
|
32
|
+
|
|
33
|
+
## Environment normalization:
|
|
34
|
+
/.bundle
|
|
35
|
+
/vendor/bundle
|
|
36
|
+
/gemfiles/vendor/bundle
|
|
37
|
+
/spec/rails_app/vendor/bundle
|
|
38
|
+
|
|
39
|
+
# these should all be checked in to normalize the environment:
|
|
40
|
+
# Gemfile.lock, .ruby-version, .ruby-gemset
|
|
41
|
+
|
|
42
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
43
|
+
.rvmrc
|
|
44
|
+
|
|
45
|
+
# if using bower-rails ignore default bower_components path bower.json files
|
|
46
|
+
/vendor/assets/bower_components
|
|
47
|
+
*.bowerrc
|
|
48
|
+
bower.json
|
|
49
|
+
|
|
50
|
+
# Ignore pow environment settings
|
|
51
|
+
.powenv
|
|
52
|
+
|
|
53
|
+
# Ignore Byebug command history file.
|
|
54
|
+
.byebug_history
|
|
55
|
+
|
|
56
|
+
# Ignore node_modules
|
|
57
|
+
/node_modules/
|
|
58
|
+
/spec/rails_app/node_modules/
|
|
59
|
+
|
|
60
|
+
# Ignore precompiled javascript packs
|
|
61
|
+
/spec/rails_app/public/packs
|
|
62
|
+
/spec/rails_app/public/packs-test
|
|
63
|
+
/spec/rails_app/public/assets
|
|
64
|
+
|
|
65
|
+
# Ignore yarn files
|
|
66
|
+
/spec/rails_app/yarn.lock
|
|
67
|
+
/spec/rails_app/yarn-error.log
|
|
68
|
+
yarn-debug.log*
|
|
69
|
+
.yarn-integrity
|
|
70
|
+
/package-lock.json
|
|
71
|
+
|
|
72
|
+
# Ignore uploaded files in development
|
|
73
|
+
/spec/rails_app/storage/*
|
|
74
|
+
!/spec/rails_app//storage/.keep
|
|
75
|
+
|
|
76
|
+
## Documentation cache and generated files:
|
|
77
|
+
/.yardoc/
|
|
78
|
+
/_yardoc/
|
|
79
|
+
/doc/
|
|
80
|
+
/rdoc/
|
|
81
|
+
|
|
82
|
+
# Security files for testing
|
|
83
|
+
/spec/rails_app/config/initializers/aws.rb
|
|
84
|
+
|
|
85
|
+
# Compiled Amazon Chime SDK as single JavaScript file
|
|
86
|
+
/spec/rails_app/app/assets/javascripts/amazon-chime-sdk.min.js
|
|
87
|
+
/spec/rails_app/app/assets/javascripts/amazon-chime-sdk.min.js.map
|
data/.rspec
ADDED
data/.travis.yml
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
language: ruby
|
|
2
|
+
|
|
3
|
+
branches:
|
|
4
|
+
except:
|
|
5
|
+
- images
|
|
6
|
+
|
|
7
|
+
rvm:
|
|
8
|
+
# - 2.7.2
|
|
9
|
+
- 2.6.6
|
|
10
|
+
|
|
11
|
+
gemfile:
|
|
12
|
+
- gemfiles/Gemfile.rails-5.0
|
|
13
|
+
- gemfiles/Gemfile.rails-5.1
|
|
14
|
+
- gemfiles/Gemfile.rails-5.2
|
|
15
|
+
- gemfiles/Gemfile.rails-6.0
|
|
16
|
+
|
|
17
|
+
matrix:
|
|
18
|
+
include:
|
|
19
|
+
- rvm: ruby-head
|
|
20
|
+
gemfile: Gemfile
|
|
21
|
+
allow_failures:
|
|
22
|
+
- rvm: ruby-head
|
|
23
|
+
fast_finish: true
|
|
24
|
+
|
|
25
|
+
sudo: false
|
|
26
|
+
|
|
27
|
+
cache: bundler
|
|
28
|
+
|
|
29
|
+
before_install:
|
|
30
|
+
- gem install bundler
|
|
31
|
+
- nvm install node
|
|
32
|
+
|
|
33
|
+
install:
|
|
34
|
+
- bundle install
|
|
35
|
+
|
|
36
|
+
before_script:
|
|
37
|
+
- cd spec/rails_app
|
|
38
|
+
- yarn --check-files
|
|
39
|
+
- bundle exec rails webpacker:compile
|
|
40
|
+
- bundle exec rails g chime_sdk:js
|
|
41
|
+
- cd -
|
|
42
|
+
|
|
43
|
+
script:
|
|
44
|
+
- bundle exec rspec
|
|
45
|
+
|
|
46
|
+
notifications:
|
|
47
|
+
email: true
|
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gemspec
|
|
4
|
+
|
|
5
|
+
# Bundle Rails
|
|
6
|
+
gem 'rails', '~> 6.0.0'
|
|
7
|
+
|
|
8
|
+
gem 'sqlite3'
|
|
9
|
+
gem 'puma'
|
|
10
|
+
gem 'sass-rails'
|
|
11
|
+
gem 'webpacker'
|
|
12
|
+
gem 'turbolinks'
|
|
13
|
+
gem 'jbuilder'
|
|
14
|
+
|
|
15
|
+
group :development do
|
|
16
|
+
gem 'web-console'
|
|
17
|
+
gem 'listen'
|
|
18
|
+
gem 'spring'
|
|
19
|
+
gem 'spring-watcher-listen'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
group :test do
|
|
23
|
+
# gem 'coveralls', require: false
|
|
24
|
+
gem 'coveralls_reborn', require: false
|
|
25
|
+
end
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Shota Yamazaki
|
|
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.
|
data/README.md
ADDED
|
@@ -0,0 +1,1109 @@
|
|
|
1
|
+
# amazon-chime-sdk-rails
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/simukappu/amazon-chime-sdk-rails)
|
|
4
|
+
[](https://coveralls.io/github/simukappu/amazon-chime-sdk-rails?branch=master)
|
|
5
|
+
[](https://depfu.com/repos/simukappu/amazon-chime-sdk-rails)
|
|
6
|
+
[](http://inch-ci.org/github/simukappu/amazon-chime-sdk-rails)
|
|
7
|
+
[](https://rubygems.org/gems/amazon-chime-sdk-rails)
|
|
8
|
+
[](https://rubygems.org/gems/amazon-chime-sdk-rails)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
*amazon-chime-sdk-rails* brings server-side implementation of [Amazon Chime SDK](https://aws.amazon.com/chime/chime-sdk) to your [Ruby on Rails](https://rubyonrails.org) application. [Amazon Chime SDK](https://aws.amazon.com/chime/chime-sdk) provides client-side implementation to build real-time communications for your application, and *amazon-chime-sdk-rails* enables you to easily add server-side implementation to your Rails application.
|
|
12
|
+
|
|
13
|
+
*amazon-chime-sdk-rails* supports both of [Rails API Application](https://guides.rubyonrails.org/api_app.html) and [Rails Application with Action View](https://guides.rubyonrails.org/action_view_overview.html). The gem provides following functions:
|
|
14
|
+
* Meeting Coordinator - Wrapper client module of [AWS SDK for Ruby](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/Chime/Client.html), which simulates [AWS SDK for JavaScript](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Chime.html) to communicate with Amazon Chime SDK client implementation by JSON format.
|
|
15
|
+
* Controller Templates - Mixin module implementation for meetings and attendees controllers.
|
|
16
|
+
* Rails Generators
|
|
17
|
+
* Controller Generator - Generator to create customizable meetings and attendees controllers in your Rails application.
|
|
18
|
+
* View Generator - Generator to create customizable meetings views for your Rails application with Action View.
|
|
19
|
+
* Single Javascript Generator - Generator to [bundle Amazon Chime SDK into single .js file](https://github.com/aws/amazon-chime-sdk-js/tree/master/demos/singlejs) and put it into [Asset Pipeline](https://guides.rubyonrails.org/asset_pipeline.html) for your Rails application with Action View.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Getting Started
|
|
23
|
+
|
|
24
|
+
### Installation
|
|
25
|
+
|
|
26
|
+
Add *amazon-chime-sdk-rails* to your app’s Gemfile:
|
|
27
|
+
|
|
28
|
+
```ruby:Gemfile
|
|
29
|
+
gem 'amazon-chime-sdk-rails'
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Then, in your project directory:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
$ bundle install
|
|
36
|
+
$ rails g chime_sdk:install
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The install generator will generate an initializer which describes all configuration options of *amazon-chime-sdk-rails*.
|
|
40
|
+
|
|
41
|
+
### Set up AWS credentials
|
|
42
|
+
|
|
43
|
+
You need to set up AWS credentials or IAM role for *amazon-chime-sdk-rails* in your Rails app. See [Configuring the AWS SDK for Ruby](https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html) for more details.
|
|
44
|
+
|
|
45
|
+
*amazon-chime-sdk-rails* requires following IAM permissions:
|
|
46
|
+
|
|
47
|
+
* [chime:TagResource](https://docs.aws.amazon.com/chime/latest/APIReference/API_TagResource.html)
|
|
48
|
+
* [chime:UntagResource](https://docs.aws.amazon.com/chime/latest/APIReference/API_UntagResource.html)
|
|
49
|
+
* [chime:CreateMeeting](https://docs.aws.amazon.com/chime/latest/APIReference/API_CreateMeeting.html)
|
|
50
|
+
* [chime:GetMeeting](https://docs.aws.amazon.com/chime/latest/APIReference/API_GetMeeting.html)
|
|
51
|
+
* [chime:ListMeetings](https://docs.aws.amazon.com/chime/latest/APIReference/API_ListMeetings.html) (if necessary)
|
|
52
|
+
* [chime:DeleteMeeting](https://docs.aws.amazon.com/chime/latest/APIReference/API_DeleteMeeting.html) (if necessary)
|
|
53
|
+
* [chime:CreateAttendee](https://docs.aws.amazon.com/chime/latest/APIReference/API_CreateAttendee.html)
|
|
54
|
+
* [chime:GetAttendee](https://docs.aws.amazon.com/chime/latest/APIReference/API_GetAttendee.html)
|
|
55
|
+
* [chime:ListAttendees](https://docs.aws.amazon.com/chime/latest/APIReference/API_ListAttendees.html) (if necessary)
|
|
56
|
+
* [chime:DeleteAttendee](https://docs.aws.amazon.com/chime/latest/APIReference/API_DeleteAttendee.html) (if necessary)
|
|
57
|
+
|
|
58
|
+
See [Actions defined by Amazon Chime](https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazonchime.html#amazonchime-actions-as-permissions) for more details.
|
|
59
|
+
|
|
60
|
+
### A: Develop your Rails API Application
|
|
61
|
+
|
|
62
|
+
Let's start to building simple Rails API application providing real-time communications in a private room.
|
|
63
|
+
For example, create Rails API application using [Devise Token Auth](https://github.com/lynndylanhurley/devise_token_auth) for user authentication.
|
|
64
|
+
|
|
65
|
+
#### Prepare Rails API application
|
|
66
|
+
|
|
67
|
+
At first, create new Rails application:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
$ rails new chime_api_app --api
|
|
71
|
+
$ cd chime_api_app
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Add gems to your Gemfile:
|
|
75
|
+
|
|
76
|
+
```ruby:Gemfile
|
|
77
|
+
# Gemfile
|
|
78
|
+
|
|
79
|
+
gem 'devise_token_auth'
|
|
80
|
+
gem 'amazon-chime-sdk-rails'
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Then, install *devise_token_auth*:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
$ bundle install
|
|
87
|
+
$ rails g devise:install
|
|
88
|
+
$ rails g devise_token_auth:install User auth
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Update your `application_controller.rb` like this:
|
|
92
|
+
|
|
93
|
+
```ruby:app/controllers/application_controller.rb
|
|
94
|
+
# app/controllers/application_controller.rb
|
|
95
|
+
|
|
96
|
+
class ApplicationController < ActionController::API
|
|
97
|
+
include ActionController::Helpers
|
|
98
|
+
include DeviseTokenAuth::Concerns::SetUserByToken
|
|
99
|
+
before_action :configure_permitted_parameters, if: :devise_controller?
|
|
100
|
+
|
|
101
|
+
protected
|
|
102
|
+
def configure_permitted_parameters
|
|
103
|
+
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Update your `user.rb` to remove unnecessary options like this:
|
|
109
|
+
|
|
110
|
+
```ruby:app/models/user.rb
|
|
111
|
+
# app/models/user.rb
|
|
112
|
+
|
|
113
|
+
class User < ActiveRecord::Base
|
|
114
|
+
devise :database_authenticatable, :registerable
|
|
115
|
+
include DeviseTokenAuth::Concerns::User
|
|
116
|
+
end
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Update *devise_token_auth* configuration in `devise_token_auth.rb` to keep authorization headers:
|
|
120
|
+
|
|
121
|
+
```ruby:config/initializers/devise_token_auth.rb
|
|
122
|
+
# config/initializers/devise_token_auth.rb
|
|
123
|
+
|
|
124
|
+
DeviseTokenAuth.setup do |config|
|
|
125
|
+
# Uncomment and update
|
|
126
|
+
config.change_headers_on_each_request = false
|
|
127
|
+
end
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### Create private room functions
|
|
131
|
+
|
|
132
|
+
Create models and controllers by generator:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
$ rails g model room name:string
|
|
136
|
+
$ rails g scaffold_controller api/rooms name:string --model-name=room
|
|
137
|
+
$ rails g model entry room:references user:references
|
|
138
|
+
$ rails g scaffold_controller api/entries room:references user:references --model-name=entry
|
|
139
|
+
$ rake db:migrate
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Update your `room.rb` like this:
|
|
143
|
+
|
|
144
|
+
```ruby:app/models/room.rb
|
|
145
|
+
# app/models/room.rb
|
|
146
|
+
|
|
147
|
+
class Room < ApplicationRecord
|
|
148
|
+
has_many :entries, dependent: :destroy
|
|
149
|
+
has_many :members, through: :entries, source: :user
|
|
150
|
+
|
|
151
|
+
def member?(user)
|
|
152
|
+
members.include?(user)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def as_json(options = {})
|
|
156
|
+
super options.merge(:methods => [:members])
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Add uniqueness validation to your `entry.rb` like this:
|
|
162
|
+
|
|
163
|
+
```ruby:app/models/entry.rb
|
|
164
|
+
# app/models/entry.rb
|
|
165
|
+
|
|
166
|
+
class Entry < ApplicationRecord
|
|
167
|
+
belongs_to :room
|
|
168
|
+
belongs_to :user
|
|
169
|
+
# Add uniqueness validation
|
|
170
|
+
validates :user, uniqueness: { scope: :room }
|
|
171
|
+
end
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Remove location header from your `rooms_controller.rb` and `entries_controller.rb` like this:
|
|
175
|
+
|
|
176
|
+
```ruby:app/controllers/api/rooms_controller.rb
|
|
177
|
+
# app/controllers/api/rooms_controller.rb
|
|
178
|
+
|
|
179
|
+
# POST /rooms
|
|
180
|
+
def create
|
|
181
|
+
@room = Room.new(room_params)
|
|
182
|
+
|
|
183
|
+
if @room.save
|
|
184
|
+
render json: @room, status: :created # Remove location header
|
|
185
|
+
else
|
|
186
|
+
render json: @room.errors, status: :unprocessable_entity
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```ruby:app/controllers/api/entries_controller.rb
|
|
192
|
+
# app/controllers/api/entries_controller.rb
|
|
193
|
+
|
|
194
|
+
# POST /entries
|
|
195
|
+
def create
|
|
196
|
+
@entry = Entry.new(entry_params)
|
|
197
|
+
|
|
198
|
+
if @entry.save
|
|
199
|
+
render json: @entry, status: :created # Remove location header
|
|
200
|
+
else
|
|
201
|
+
render json: @entry.errors, status: :unprocessable_entity
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### Develop meeting functions with amazon-chime-sdk-rails
|
|
207
|
+
|
|
208
|
+
Install *amazon-chime-sdk-rails* and generates your controllers:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
$ rails g chime_sdk:install
|
|
212
|
+
$ rails g chime_sdk:controllers -r room -n api
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Add and uncomment several functions in generated `meetings_controller.rb` and `meeting_attendees_controller.rb` for your app configurations:
|
|
216
|
+
|
|
217
|
+
```ruby:app/controllers/api/meetings_controller.rb
|
|
218
|
+
# app/controllers/api/meetings_controller.rb
|
|
219
|
+
|
|
220
|
+
class Api::MeetingsController < ApplicationController
|
|
221
|
+
before_action :authenticate_api_user!
|
|
222
|
+
include DeviseTokenAuth::Concerns::SetUserByToken
|
|
223
|
+
before_action :set_room
|
|
224
|
+
before_action :check_membership
|
|
225
|
+
|
|
226
|
+
include ChimeSdk::Controller::Meetings::Mixin
|
|
227
|
+
|
|
228
|
+
private
|
|
229
|
+
# Add
|
|
230
|
+
def set_room
|
|
231
|
+
@room = Room.find(params[:room_id])
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Add
|
|
235
|
+
def check_membership
|
|
236
|
+
unless @room.member?(current_api_user)
|
|
237
|
+
message = 'Unauthorized: you are not a member of this private room.'
|
|
238
|
+
render json: { room: @room, notice: message }, status: :forbidden
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Uncomment
|
|
243
|
+
def meeting_request_id
|
|
244
|
+
"PrivateRoom-#{@room.id}"
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Uncomment and update
|
|
248
|
+
def attendee_request_id
|
|
249
|
+
"User-#{current_api_user.id}"
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Uncomment
|
|
253
|
+
def application_meeting_metadata(meeting)
|
|
254
|
+
{
|
|
255
|
+
"MeetingType": "PrivateRoom",
|
|
256
|
+
"Room": @room
|
|
257
|
+
}
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# Uncomment
|
|
261
|
+
def application_attendee_metadata(attendee)
|
|
262
|
+
user_id = attendee[:Attendee][:ExternalUserId].split('-')[3]
|
|
263
|
+
{
|
|
264
|
+
"AttendeeType": "User",
|
|
265
|
+
"User": User.find_by_id(user_id)
|
|
266
|
+
}
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
```ruby:app/controllers/api/meeting_attendees_controller.rb
|
|
272
|
+
# app/controllers/api/meeting_attendees_controller.rb
|
|
273
|
+
|
|
274
|
+
class Api::MeetingAttendeesController < ApplicationController
|
|
275
|
+
before_action :authenticate_api_user!
|
|
276
|
+
include DeviseTokenAuth::Concerns::SetUserByToken
|
|
277
|
+
before_action :set_room
|
|
278
|
+
before_action :check_membership
|
|
279
|
+
|
|
280
|
+
include ChimeSdk::Controller::Attendees::Mixin
|
|
281
|
+
|
|
282
|
+
private
|
|
283
|
+
# Add
|
|
284
|
+
def set_room
|
|
285
|
+
@room = Room.find(params[:room_id])
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Add
|
|
289
|
+
def check_membership
|
|
290
|
+
unless @room.member?(current_api_user)
|
|
291
|
+
message = 'Unauthorized: you are not a member of this private room.'
|
|
292
|
+
render json: { room: @room, notice: message }, status: :forbidden
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
# Uncomment and update
|
|
297
|
+
def attendee_request_id
|
|
298
|
+
"User-#{current_api_user.id}"
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
# Uncomment
|
|
302
|
+
def application_attendee_metadata(attendee)
|
|
303
|
+
user_id = attendee[:Attendee][:ExternalUserId].split('-')[3]
|
|
304
|
+
{
|
|
305
|
+
"AttendeeType": "User",
|
|
306
|
+
"User": User.find_by_id(user_id)
|
|
307
|
+
}
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Then, update your `routes.rb` like this:
|
|
313
|
+
|
|
314
|
+
```ruby:config/routes.rb
|
|
315
|
+
# config/routes.rb
|
|
316
|
+
|
|
317
|
+
Rails.application.routes.draw do
|
|
318
|
+
namespace :api do
|
|
319
|
+
scope :"v1" do
|
|
320
|
+
mount_devise_token_auth_for 'User', at: 'auth'
|
|
321
|
+
resources :rooms do
|
|
322
|
+
resources :entries, only: [:create, :destroy]
|
|
323
|
+
resources :meetings, defaults: { format: :json }, only: [:index, :show, :create, :destroy] do
|
|
324
|
+
resources :meeting_attendees, as: :attendees, path: :attendees, only: [:index, :show, :create, :destroy]
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Note that you need to set up AWS credentials or IAM role for *amazon-chime-sdk-rails*. See [Set up AWS credentials](#set-up-aws-credentials) for more details.
|
|
333
|
+
|
|
334
|
+
Finally, start rails server:
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
$ rails server
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Now ready to take off!
|
|
341
|
+
|
|
342
|
+
#### Get meeting configurations through Rails API
|
|
343
|
+
|
|
344
|
+
Created Rails API works like this:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
# Sign up users
|
|
348
|
+
|
|
349
|
+
$ curl localhost:3000/api/v1/auth -X POST -H "content-type:application/json" -d '{"email":"ichiro@example.com", "password":"password", "password_confirmation":"password", "name":"ichiro"}'
|
|
350
|
+
|
|
351
|
+
{"status":"success","data":{"id":1,"provider":"email","uid":"ichiro@example.com","allow_password_change":false,"name":"ichiro","nickname":null,"image":null,"email":"ichiro@example.com","created_at":"2020-10-16T11:14:48.731Z","updated_at":"2020-10-16T11:14:48.827Z"}}
|
|
352
|
+
|
|
353
|
+
$ curl localhost:3000/api/v1/auth -X POST -H "content-type:application/json" -d '{"email":"stephen@example.com", "password":"password", "password_confirmation":"password", "name":"stephen"}'
|
|
354
|
+
|
|
355
|
+
{"status":"success","data":{"id":2,"provider":"email","uid":"stephen@example.com","allow_password_change":false,"name":"stephen","nickname":null,"image":null,"email":"stephen@example.com","created_at":"2020-10-16T11:15:33.226Z","updated_at":"2020-10-16T11:15:33.314Z"}}
|
|
356
|
+
|
|
357
|
+
# Create private room
|
|
358
|
+
|
|
359
|
+
$ curl localhost:3000/api/v1/rooms -X POST -H "content-type:application/json" -d '{"room":{"name":"PrivateRoom-1"}}'
|
|
360
|
+
|
|
361
|
+
{"id":1,"name":"PrivateRoom-1","created_at":"2020-10-16T11:15:56.223Z","updated_at":"2020-10-16T11:15:56.223Z","members":[]}
|
|
362
|
+
|
|
363
|
+
# You cannot create meeting yet because the user is not signed in
|
|
364
|
+
|
|
365
|
+
$ curl localhost:3000/api/v1/rooms/3/meetings -X POST -H "content-type:application/json"
|
|
366
|
+
|
|
367
|
+
{"errors":["You need to sign in or sign up before continuing."]}
|
|
368
|
+
|
|
369
|
+
# Sign in as ichiro
|
|
370
|
+
|
|
371
|
+
$ curl localhost:3000/api/v1/auth/sign_in -X POST -H "content-type:application/json" -D auth_headers.txt -d '{"email":"ichiro@example.com", "password":"password"}'
|
|
372
|
+
|
|
373
|
+
{"data":{"id":1,"email":"ichiro@example.com","provider":"email","uid":"ichiro@example.com","allow_password_change":false,"name":"ichiro","nickname":null,"image":null}}
|
|
374
|
+
|
|
375
|
+
$ _ACCESS_TOKEN=$(cat auth_headers.txt | grep access-token | rev | cut -c 2- | rev)
|
|
376
|
+
$ _CLIENT=$(cat auth_headers.txt | grep client | rev | cut -c 2- | rev)
|
|
377
|
+
$ _UID=$(cat auth_headers.txt | grep uid | rev | cut -c 2- | rev)
|
|
378
|
+
|
|
379
|
+
# You cannot create meeting yet because the user is not a member of the private room
|
|
380
|
+
|
|
381
|
+
$ curl localhost:3000/api/v1/rooms/1/meetings -X POST -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}"
|
|
382
|
+
|
|
383
|
+
{"room":{"id":1,"name":"PrivateRoom-1","created_at":"2020-10-16T11:15:56.223Z","updated_at":"2020-10-16T11:15:56.223Z","members":[]},"notice":"Unauthorized: you are not a member of this private room."}
|
|
384
|
+
|
|
385
|
+
# Add users to the private room
|
|
386
|
+
|
|
387
|
+
$ curl localhost:3000/api/v1/rooms/1/entries -X POST -H "content-type:application/json" -d '{"entry":{"room_id":1,"user_id":1}}'
|
|
388
|
+
|
|
389
|
+
{"id":1,"room_id":1,"user_id":1,"created_at":"2020-10-16T11:18:22.839Z","updated_at":"2020-10-16T11:18:22.839Z"}
|
|
390
|
+
|
|
391
|
+
$ curl localhost:3000/api/v1/rooms/1/entries -X POST -H "content-type:application/json" -d '{"entry":{"room_id":1,"user_id":2}}'
|
|
392
|
+
|
|
393
|
+
{"id":2,"room_id":1,"user_id":2,"created_at":"2020-10-16T11:18:41.116Z","updated_at":"2020-10-16T11:18:41.116Z"}
|
|
394
|
+
|
|
395
|
+
# Now you can create meeting as a member of the private room
|
|
396
|
+
|
|
397
|
+
$ curl localhost:3000/api/v1/rooms/1/meetings -X POST -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}" | jq .
|
|
398
|
+
|
|
399
|
+
{
|
|
400
|
+
"Meeting": {
|
|
401
|
+
"MeetingId": "2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
402
|
+
"ExternalMeetingId": "ChimeSdkRailsApp-development-PrivateRoom-1",
|
|
403
|
+
"MediaPlacement": {
|
|
404
|
+
"AudioHostUrl": "d3175d855e633b72aedb275a0dd6504f.k.m2.ue1.app.chime.aws:3478",
|
|
405
|
+
"AudioFallbackUrl": "wss://haxrp.m2.ue1.app.chime.aws:443/calls/2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
406
|
+
"ScreenDataUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/v2/screen/2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
407
|
+
"ScreenSharingUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/v2/screen/2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
408
|
+
"ScreenViewingUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/ws/connect?passcode=null&viewer_uuid=null&X-BitHub-Call-Id=2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
409
|
+
"SignalingUrl": "wss://signal.m2.ue1.app.chime.aws/control/2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
410
|
+
"TurnControlUrl": "https://ccp.cp.ue1.app.chime.aws/v2/turn_sessions"
|
|
411
|
+
},
|
|
412
|
+
"MediaRegion": "us-east-1",
|
|
413
|
+
"ApplicationMetadata": {
|
|
414
|
+
"MeetingType": "PrivateRoom",
|
|
415
|
+
"Room": {
|
|
416
|
+
"id": 1,
|
|
417
|
+
"name": "PrivateRoom-1",
|
|
418
|
+
"created_at": "2020-10-16T11:15:56.223Z",
|
|
419
|
+
"updated_at": "2020-10-16T11:15:56.223Z",
|
|
420
|
+
"members": [
|
|
421
|
+
{
|
|
422
|
+
"id": 1,
|
|
423
|
+
"provider": "email",
|
|
424
|
+
"uid": "ichiro@example.com",
|
|
425
|
+
"allow_password_change": false,
|
|
426
|
+
"name": "ichiro",
|
|
427
|
+
"nickname": null,
|
|
428
|
+
"image": null,
|
|
429
|
+
"email": "ichiro@example.com",
|
|
430
|
+
"created_at": "2020-10-16T11:14:48.731Z",
|
|
431
|
+
"updated_at": "2020-10-16T11:16:56.927Z"
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
"id": 2,
|
|
435
|
+
"provider": "email",
|
|
436
|
+
"uid": "stephen@example.com",
|
|
437
|
+
"allow_password_change": false,
|
|
438
|
+
"name": "stephen",
|
|
439
|
+
"nickname": null,
|
|
440
|
+
"image": null,
|
|
441
|
+
"email": "stephen@example.com",
|
|
442
|
+
"created_at": "2020-10-16T11:15:33.226Z",
|
|
443
|
+
"updated_at": "2020-10-16T11:15:33.314Z"
|
|
444
|
+
}
|
|
445
|
+
]
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
"Attendee": {
|
|
450
|
+
"ExternalUserId": "ChimeSdkRailsApp-development-User-1",
|
|
451
|
+
"AttendeeId": "b581c46d-661f-92bb-d80e-f4b157d95fe9",
|
|
452
|
+
"JoinToken": "YjU4MWM0NmQtNjYxZi05MmJiLWQ4MGUtZjRiMTU3ZDk1ZmU5OjgyZmM2NTMxLTIwMjctNGMxMS04OTE0LTQwZjkxNmJmNjM3MQ",
|
|
453
|
+
"ApplicationMetadata": {
|
|
454
|
+
"AttendeeType": "User",
|
|
455
|
+
"User": {
|
|
456
|
+
"id": 1,
|
|
457
|
+
"provider": "email",
|
|
458
|
+
"uid": "ichiro@example.com",
|
|
459
|
+
"allow_password_change": false,
|
|
460
|
+
"name": "ichiro",
|
|
461
|
+
"nickname": null,
|
|
462
|
+
"image": null,
|
|
463
|
+
"email": "ichiro@example.com",
|
|
464
|
+
"created_at": "2020-10-16T11:14:48.731Z",
|
|
465
|
+
"updated_at": "2020-10-16T11:16:56.927Z"
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
# Get attendee data from created meeting ID
|
|
472
|
+
|
|
473
|
+
$ MEETING_ID=$(curl localhost:3000/api/v1/rooms/1/meetings -X POST -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}" | jq -r .Meeting.MeetingId)
|
|
474
|
+
|
|
475
|
+
$ curl localhost:3000/api/v1/rooms/1/meetings/${MEETING_ID}/attendees -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}" | jq .
|
|
476
|
+
|
|
477
|
+
{
|
|
478
|
+
"attendees": [
|
|
479
|
+
{
|
|
480
|
+
"Attendee": {
|
|
481
|
+
"ExternalUserId": "ChimeSdkRailsApp-development-User-1",
|
|
482
|
+
"AttendeeId": "b581c46d-661f-92bb-d80e-f4b157d95fe9",
|
|
483
|
+
"JoinToken": "YjU4MWM0NmQtNjYxZi05MmJiLWQ4MGUtZjRiMTU3ZDk1ZmU5OjgyZmM2NTMxLTIwMjctNGMxMS04OTE0LTQwZjkxNmJmNjM3MQ",
|
|
484
|
+
"ApplicationMetadata": {
|
|
485
|
+
"AttendeeType": "User",
|
|
486
|
+
"User": {
|
|
487
|
+
"id": 1,
|
|
488
|
+
"provider": "email",
|
|
489
|
+
"uid": "ichiro@example.com",
|
|
490
|
+
"allow_password_change": false,
|
|
491
|
+
"name": "ichiro",
|
|
492
|
+
"nickname": null,
|
|
493
|
+
"image": null,
|
|
494
|
+
"email": "ichiro@example.com",
|
|
495
|
+
"created_at": "2020-10-16T11:14:48.731Z",
|
|
496
|
+
"updated_at": "2020-10-16T11:16:56.927Z"
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
]
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
$ ATTENDEE_ID=$(curl localhost:3000/api/v1/rooms/1/meetings/${MEETING_ID}/attendees -X GET -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}" | jq -r .attendees[0].Attendee.AttendeeId)
|
|
505
|
+
|
|
506
|
+
$ curl localhost:3000/api/v1/rooms/1/meetings/${MEETING_ID}/attendees/${ATTENDEE_ID} -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}" | jq .
|
|
507
|
+
|
|
508
|
+
{
|
|
509
|
+
"Attendee": {
|
|
510
|
+
"ExternalUserId": "ChimeSdkRailsApp-development-User-1",
|
|
511
|
+
"AttendeeId": "b581c46d-661f-92bb-d80e-f4b157d95fe9",
|
|
512
|
+
"JoinToken": "YjU4MWM0NmQtNjYxZi05MmJiLWQ4MGUtZjRiMTU3ZDk1ZmU5OjgyZmM2NTMxLTIwMjctNGMxMS04OTE0LTQwZjkxNmJmNjM3MQ",
|
|
513
|
+
"ApplicationMetadata": {
|
|
514
|
+
"AttendeeType": "User",
|
|
515
|
+
"User": {
|
|
516
|
+
"id": 1,
|
|
517
|
+
"provider": "email",
|
|
518
|
+
"uid": "ichiro@example.com",
|
|
519
|
+
"allow_password_change": false,
|
|
520
|
+
"name": "ichiro",
|
|
521
|
+
"nickname": null,
|
|
522
|
+
"image": null,
|
|
523
|
+
"email": "ichiro@example.com",
|
|
524
|
+
"created_at": "2020-10-16T11:14:48.731Z",
|
|
525
|
+
"updated_at": "2020-10-16T11:16:56.927Z"
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
# Sign in as stephen
|
|
532
|
+
|
|
533
|
+
$ curl localhost:3000/api/v1/auth/sign_in -X POST -H "content-type:application/json" -D auth_headers.txt -d '{"email":"stephen@example.com", "password":"password"}'
|
|
534
|
+
|
|
535
|
+
{"data":{"id":2,"email":"stephen@example.com","provider":"email","uid":"stephen@example.com","allow_password_change":false,"name":"stephen","nickname":null,"image":null}}
|
|
536
|
+
|
|
537
|
+
$ _ACCESS_TOKEN=$(cat auth_headers.txt | grep access-token | rev | cut -c 2- | rev)
|
|
538
|
+
$ _CLIENT=$(cat auth_headers.txt | grep client | rev | cut -c 2- | rev)
|
|
539
|
+
$ _UID=$(cat auth_headers.txt | grep uid | rev | cut -c 2- | rev)
|
|
540
|
+
|
|
541
|
+
# Confirm attending same meeting in the private room as different attendee
|
|
542
|
+
|
|
543
|
+
$ curl localhost:3000/api/v1/rooms/1/meetings -X POST -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}" | jq .
|
|
544
|
+
|
|
545
|
+
{
|
|
546
|
+
"Meeting": {
|
|
547
|
+
"MeetingId": "2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
548
|
+
"ExternalMeetingId": "ChimeSdkRailsApp-development-PrivateRoom-1",
|
|
549
|
+
"MediaPlacement": {
|
|
550
|
+
"AudioHostUrl": "d3175d855e633b72aedb275a0dd6504f.k.m2.ue1.app.chime.aws:3478",
|
|
551
|
+
"AudioFallbackUrl": "wss://haxrp.m2.ue1.app.chime.aws:443/calls/2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
552
|
+
"ScreenDataUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/v2/screen/2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
553
|
+
"ScreenSharingUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/v2/screen/2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
554
|
+
"ScreenViewingUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/ws/connect?passcode=null&viewer_uuid=null&X-BitHub-Call-Id=2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
555
|
+
"SignalingUrl": "wss://signal.m2.ue1.app.chime.aws/control/2f550432-579c-4058-bbb9-be8a01d3beea",
|
|
556
|
+
"TurnControlUrl": "https://ccp.cp.ue1.app.chime.aws/v2/turn_sessions"
|
|
557
|
+
},
|
|
558
|
+
"MediaRegion": "us-east-1",
|
|
559
|
+
"ApplicationMetadata": {
|
|
560
|
+
"MeetingType": "PrivateRoom",
|
|
561
|
+
"Room": {
|
|
562
|
+
"id": 1,
|
|
563
|
+
"name": "PrivateRoom-1",
|
|
564
|
+
"created_at": "2020-10-16T11:15:56.223Z",
|
|
565
|
+
"updated_at": "2020-10-16T11:15:56.223Z",
|
|
566
|
+
"members": [
|
|
567
|
+
{
|
|
568
|
+
"id": 1,
|
|
569
|
+
"provider": "email",
|
|
570
|
+
"uid": "ichiro@example.com",
|
|
571
|
+
"allow_password_change": false,
|
|
572
|
+
"name": "ichiro",
|
|
573
|
+
"nickname": null,
|
|
574
|
+
"image": null,
|
|
575
|
+
"email": "ichiro@example.com",
|
|
576
|
+
"created_at": "2020-10-16T11:14:48.731Z",
|
|
577
|
+
"updated_at": "2020-10-16T11:16:56.927Z"
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
"id": 2,
|
|
581
|
+
"provider": "email",
|
|
582
|
+
"uid": "stephen@example.com",
|
|
583
|
+
"allow_password_change": false,
|
|
584
|
+
"name": "stephen",
|
|
585
|
+
"nickname": null,
|
|
586
|
+
"image": null,
|
|
587
|
+
"email": "stephen@example.com",
|
|
588
|
+
"created_at": "2020-10-16T11:15:33.226Z",
|
|
589
|
+
"updated_at": "2020-10-16T11:21:46.011Z"
|
|
590
|
+
}
|
|
591
|
+
]
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
"Attendee": {
|
|
596
|
+
"ExternalUserId": "ChimeSdkRailsApp-development-User-2",
|
|
597
|
+
"AttendeeId": "986886fc-dcbc-1d44-4708-917ab23117de",
|
|
598
|
+
"JoinToken": "OTg2ODg2ZmMtZGNiYy0xZDQ0LTQ3MDgtOTE3YWIyMzExN2RlOjNjNjAzM2E5LWFlNGUtNGVmZi1iNjZjLWMwY2M1YjU3OTE4OA",
|
|
599
|
+
"ApplicationMetadata": {
|
|
600
|
+
"AttendeeType": "User",
|
|
601
|
+
"User": {
|
|
602
|
+
"id": 2,
|
|
603
|
+
"provider": "email",
|
|
604
|
+
"uid": "stephen@example.com",
|
|
605
|
+
"allow_password_change": false,
|
|
606
|
+
"name": "stephen",
|
|
607
|
+
"nickname": null,
|
|
608
|
+
"image": null,
|
|
609
|
+
"email": "stephen@example.com",
|
|
610
|
+
"created_at": "2020-10-16T11:15:33.226Z",
|
|
611
|
+
"updated_at": "2020-10-16T11:21:46.011Z"
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
$ MEETING_ID_2=$(curl localhost:3000/api/v1/rooms/1/meetings -X POST -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}" | jq -r .Meeting.MeetingId)
|
|
618
|
+
|
|
619
|
+
$ echo ${MEETING_ID}
|
|
620
|
+
|
|
621
|
+
2f550432-579c-4058-bbb9-be8a01d3beea
|
|
622
|
+
|
|
623
|
+
$ echo ${MEETING_ID_2}
|
|
624
|
+
|
|
625
|
+
2f550432-579c-4058-bbb9-be8a01d3beea
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
Now you can start online meeting using [Amazon Chime SDK](https://aws.amazon.com/chime/chime-sdk) client-side implementation with this responded *Meeting* and *Attendee* data.
|
|
629
|
+
|
|
630
|
+
You can see [sample single page application](/spec/rails_app/app/javascript/) using [Vue.js](https://vuejs.org) and [Amazon Chime SDK for JavaScript](https://github.com/aws/amazon-chime-sdk-js) as a part of [example Rails application](#examples).
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
### B: Develop your Rails Application with Action View
|
|
634
|
+
|
|
635
|
+
Let's start to building simple Rails application with Action View providing real-time communications in a private room.
|
|
636
|
+
For example, create Rails application using [Devise](https://github.com/heartcombo/devise) for user authentication.
|
|
637
|
+
|
|
638
|
+
#### Prepare Rails application
|
|
639
|
+
|
|
640
|
+
At first, create new Rails application:
|
|
641
|
+
|
|
642
|
+
```bash
|
|
643
|
+
$ rails new chime_view_app
|
|
644
|
+
$ cd chime_view_app
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
Add gems to your Gemfile:
|
|
648
|
+
|
|
649
|
+
```ruby:Gemfile
|
|
650
|
+
# Gemfile
|
|
651
|
+
|
|
652
|
+
gem 'devise'
|
|
653
|
+
gem 'amazon-chime-sdk-rails'
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
Then, install *devise*:
|
|
657
|
+
|
|
658
|
+
```bash
|
|
659
|
+
$ bundle install
|
|
660
|
+
$ rails g devise:install
|
|
661
|
+
$ rails g devise User
|
|
662
|
+
$ rails g migration add_name_to_users name:string
|
|
663
|
+
$ rails g devise:views User
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
Update your `application_controller.rb` like this:
|
|
667
|
+
|
|
668
|
+
```ruby:app/controllers/application_controller.rb
|
|
669
|
+
# app/controllers/application_controller.rb
|
|
670
|
+
|
|
671
|
+
class ApplicationController < ActionController::Base
|
|
672
|
+
before_action :configure_permitted_parameters, if: :devise_controller?
|
|
673
|
+
|
|
674
|
+
protected
|
|
675
|
+
def configure_permitted_parameters
|
|
676
|
+
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
|
|
677
|
+
end
|
|
678
|
+
end
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
Add user name form to your `app/views/users/registrations/new.html.erb` view template like this:
|
|
682
|
+
|
|
683
|
+
```erb:app/views/users/registrations/new.html.erb
|
|
684
|
+
# app/views/users/registrations/new.html.erb
|
|
685
|
+
|
|
686
|
+
<div class="field">
|
|
687
|
+
<%= f.label :name %><br />
|
|
688
|
+
<%= f.text_field :name, autocomplete: "name" %>
|
|
689
|
+
</div>
|
|
690
|
+
|
|
691
|
+
<div class="field">
|
|
692
|
+
<%= f.label :email %><br />
|
|
693
|
+
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
|
|
694
|
+
</div>
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
Update *devise* configuration in `devise.rb` to use scoped views:
|
|
698
|
+
|
|
699
|
+
```ruby:config/initializers/devise.rb
|
|
700
|
+
# config/initializers/devise.rb
|
|
701
|
+
|
|
702
|
+
Devise.setup do |config|
|
|
703
|
+
# Uncomment and update
|
|
704
|
+
config.scoped_views = true
|
|
705
|
+
end
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
Add login header to your application. Create new `app/views/layouts/_header.html.erb` and update your `app/views/layouts/application.html.erb` like this:
|
|
709
|
+
|
|
710
|
+
```erb:app/views/layouts/_header.html.erb
|
|
711
|
+
# app/views/layouts/_header.html.erb
|
|
712
|
+
|
|
713
|
+
<header>
|
|
714
|
+
<div>
|
|
715
|
+
<div>
|
|
716
|
+
<strong>Rails Application for Amazon Chime SDK Meeting (Rails App with Action View)</strong>
|
|
717
|
+
</div>
|
|
718
|
+
<div>
|
|
719
|
+
<% if user_signed_in? %>
|
|
720
|
+
<%= current_user.name %>
|
|
721
|
+
<%= link_to 'Logout', destroy_user_session_path, method: :delete %>
|
|
722
|
+
<% else %>
|
|
723
|
+
<%= link_to "Sign up", new_user_registration_path %>
|
|
724
|
+
<%= link_to 'Login', new_user_session_path %>
|
|
725
|
+
<% end %>
|
|
726
|
+
</div>
|
|
727
|
+
</div>
|
|
728
|
+
</header>
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
```erb:app/views/layouts/application.html.erb
|
|
732
|
+
# app/views/layouts/application.html.erb
|
|
733
|
+
|
|
734
|
+
<!DOCTYPE html>
|
|
735
|
+
<html>
|
|
736
|
+
<head>
|
|
737
|
+
<title>Rails Application for Amazon Chime SDK Meeting</title>
|
|
738
|
+
<%= csrf_meta_tags %>
|
|
739
|
+
<%= csp_meta_tag %>
|
|
740
|
+
|
|
741
|
+
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
|
742
|
+
<%= yield(:javascript_pack_tag) %>
|
|
743
|
+
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
|
744
|
+
</head>
|
|
745
|
+
|
|
746
|
+
<body>
|
|
747
|
+
<div id="app">
|
|
748
|
+
<%= render 'layouts/header' %>
|
|
749
|
+
<%= yield %>
|
|
750
|
+
<div>
|
|
751
|
+
</body>
|
|
752
|
+
</html>
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
#### Create private room functions
|
|
756
|
+
|
|
757
|
+
Create MVC by generator:
|
|
758
|
+
|
|
759
|
+
```bash
|
|
760
|
+
$ rails g scaffold room name:string
|
|
761
|
+
$ rails g scaffold entry room:references user:references
|
|
762
|
+
$ rake db:migrate
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
Update your `room.rb` like this:
|
|
766
|
+
|
|
767
|
+
```ruby:app/models/room.rb
|
|
768
|
+
# app/models/room.rb
|
|
769
|
+
|
|
770
|
+
class Room < ApplicationRecord
|
|
771
|
+
has_many :entries, dependent: :destroy
|
|
772
|
+
has_many :members, through: :entries, source: :user
|
|
773
|
+
|
|
774
|
+
def member?(user)
|
|
775
|
+
members.include?(user)
|
|
776
|
+
end
|
|
777
|
+
end
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
Add uniqueness validation to your `entry.rb` like this:
|
|
781
|
+
|
|
782
|
+
```ruby:app/models/entry.rb
|
|
783
|
+
# app/models/entry.rb
|
|
784
|
+
|
|
785
|
+
class Entry < ApplicationRecord
|
|
786
|
+
belongs_to :room
|
|
787
|
+
belongs_to :user
|
|
788
|
+
# Add uniqueness validation
|
|
789
|
+
validates :user, uniqueness: { scope: :room }
|
|
790
|
+
end
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
Update *create* and *destroy* method in your `entries_controller.rb` like this:
|
|
794
|
+
|
|
795
|
+
```ruby:app/controllers/entries_controller.rb
|
|
796
|
+
# app/controllers/entries_controller.rb
|
|
797
|
+
|
|
798
|
+
class EntriesController < ApplicationController
|
|
799
|
+
before_action :authenticate_user!
|
|
800
|
+
before_action :set_room
|
|
801
|
+
before_action :set_entry, only: [:destroy]
|
|
802
|
+
|
|
803
|
+
# POST /entries
|
|
804
|
+
# POST /entries.json
|
|
805
|
+
def create
|
|
806
|
+
@entry = Entry.new(entry_params)
|
|
807
|
+
|
|
808
|
+
respond_to do |format|
|
|
809
|
+
if @entry.save
|
|
810
|
+
format.html { redirect_to @room, notice: 'Member was successfully added.' }
|
|
811
|
+
format.json { render :show, status: :created, location: @room }
|
|
812
|
+
else
|
|
813
|
+
format.html { redirect_to @room, notice: @entry.errors }
|
|
814
|
+
format.json { render json: @entry.errors, status: :unprocessable_entity }
|
|
815
|
+
end
|
|
816
|
+
end
|
|
817
|
+
end
|
|
818
|
+
|
|
819
|
+
# DELETE /entries/1
|
|
820
|
+
# DELETE /entries/1.json
|
|
821
|
+
def destroy
|
|
822
|
+
@entry.destroy
|
|
823
|
+
respond_to do |format|
|
|
824
|
+
format.html { redirect_to @room, notice: 'Member was successfully removed.' }
|
|
825
|
+
format.json { head :no_content }
|
|
826
|
+
end
|
|
827
|
+
end
|
|
828
|
+
|
|
829
|
+
private
|
|
830
|
+
# Use callbacks to share common setup or constraints between actions.
|
|
831
|
+
def set_room
|
|
832
|
+
@room = Room.find(params[:room_id])
|
|
833
|
+
end
|
|
834
|
+
|
|
835
|
+
# Use callbacks to share common setup or constraints between actions.
|
|
836
|
+
def set_entry
|
|
837
|
+
@entry = Entry.find(params[:id])
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
# Only allow a list of trusted parameters through.
|
|
841
|
+
def entry_params
|
|
842
|
+
params.require(:entry).permit(:room_id, :user_id)
|
|
843
|
+
end
|
|
844
|
+
end
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
#### Develop meeting functions with amazon-chime-sdk-rails
|
|
848
|
+
|
|
849
|
+
Install *amazon-chime-sdk-rails* and generates your controllers:
|
|
850
|
+
|
|
851
|
+
```bash
|
|
852
|
+
$ rails g chime_sdk:install
|
|
853
|
+
$ rails g chime_sdk:controllers -r room
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
Add and uncomment several functions in generated `meetings_controller.rb` and `meeting_attendees_controller.rb` for your app configurations:
|
|
857
|
+
|
|
858
|
+
```ruby:app/controllers/api/meetings_controller.rb
|
|
859
|
+
# app/controllers/api/meetings_controller.rb
|
|
860
|
+
|
|
861
|
+
class MeetingsController < ApplicationController
|
|
862
|
+
before_action :authenticate_user!
|
|
863
|
+
before_action :set_room
|
|
864
|
+
before_action :check_membership
|
|
865
|
+
|
|
866
|
+
include ChimeSdk::Controller::Meetings::Mixin
|
|
867
|
+
|
|
868
|
+
private
|
|
869
|
+
# Add
|
|
870
|
+
def set_room
|
|
871
|
+
@room = Room.find(params[:room_id])
|
|
872
|
+
end
|
|
873
|
+
|
|
874
|
+
# Add
|
|
875
|
+
def check_membership
|
|
876
|
+
unless @room.member?(current_user)
|
|
877
|
+
message = 'Unauthorized: you are not a member of this private room.'
|
|
878
|
+
redirect_to @room, notice: message
|
|
879
|
+
end
|
|
880
|
+
end
|
|
881
|
+
|
|
882
|
+
# Uncomment
|
|
883
|
+
def meeting_request_id
|
|
884
|
+
"PrivateRoom-#{@room.id}"
|
|
885
|
+
end
|
|
886
|
+
|
|
887
|
+
# Uncomment
|
|
888
|
+
def attendee_request_id
|
|
889
|
+
"User-#{current_user.id}"
|
|
890
|
+
end
|
|
891
|
+
|
|
892
|
+
# Uncomment
|
|
893
|
+
def application_meeting_metadata(meeting)
|
|
894
|
+
{
|
|
895
|
+
"MeetingType": "PrivateRoom",
|
|
896
|
+
"Room": @room
|
|
897
|
+
}
|
|
898
|
+
end
|
|
899
|
+
|
|
900
|
+
# Uncomment
|
|
901
|
+
def application_attendee_metadata(attendee)
|
|
902
|
+
user_id = attendee[:Attendee][:ExternalUserId].split('-')[3]
|
|
903
|
+
{
|
|
904
|
+
"AttendeeType": "User",
|
|
905
|
+
"User": User.find_by_id(user_id)
|
|
906
|
+
}
|
|
907
|
+
end
|
|
908
|
+
|
|
909
|
+
# Uncomment
|
|
910
|
+
def application_attendee_metadata(attendee)
|
|
911
|
+
user_id = attendee[:Attendee][:ExternalUserId].split('-')[3]
|
|
912
|
+
{
|
|
913
|
+
"AttendeeType": "User",
|
|
914
|
+
"User": User.find_by_id(user_id)
|
|
915
|
+
}
|
|
916
|
+
end
|
|
917
|
+
end
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
```ruby:app/controllers/api/meeting_attendees_controller.rb
|
|
921
|
+
# app/controllers/api/meeting_attendees_controller.rb
|
|
922
|
+
|
|
923
|
+
class MeetingAttendeesController < ApplicationController
|
|
924
|
+
before_action :authenticate_user!
|
|
925
|
+
before_action :set_room
|
|
926
|
+
before_action :check_membership
|
|
927
|
+
|
|
928
|
+
include ChimeSdk::Controller::Attendees::Mixin
|
|
929
|
+
|
|
930
|
+
private
|
|
931
|
+
# Add
|
|
932
|
+
def set_room
|
|
933
|
+
@room = Room.find(params[:room_id])
|
|
934
|
+
end
|
|
935
|
+
|
|
936
|
+
# Add
|
|
937
|
+
def check_membership
|
|
938
|
+
unless @room.member?(current_user)
|
|
939
|
+
message = 'Unauthorized: you are not a member of this private room.'
|
|
940
|
+
redirect_to @room, notice: message
|
|
941
|
+
end
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
# Uncomment
|
|
945
|
+
def attendee_request_id
|
|
946
|
+
"User-#{current_user.id}"
|
|
947
|
+
end
|
|
948
|
+
|
|
949
|
+
# Uncomment
|
|
950
|
+
def application_attendee_metadata(attendee)
|
|
951
|
+
user_id = attendee[:Attendee][:ExternalUserId].split('-')[3]
|
|
952
|
+
{
|
|
953
|
+
"AttendeeType": "User",
|
|
954
|
+
"User": User.find_by_id(user_id)
|
|
955
|
+
}
|
|
956
|
+
end
|
|
957
|
+
end
|
|
958
|
+
```
|
|
959
|
+
|
|
960
|
+
Generates meeting views by *amazon-chime-sdk-rails* generator:
|
|
961
|
+
|
|
962
|
+
```bash
|
|
963
|
+
$ rails g chime_sdk:views
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
Simply customize your meeting view generated *app/views/meetings/show.html.erb*:
|
|
967
|
+
|
|
968
|
+
```javascript
|
|
969
|
+
// app/views/meetings/show.html.erb
|
|
970
|
+
|
|
971
|
+
function showApplicationUserName(attendee) {
|
|
972
|
+
// Comment
|
|
973
|
+
// return attendee.Attendee.AttendeeId;
|
|
974
|
+
// Uncomment
|
|
975
|
+
return `${attendee.Attendee.ApplicationMetadata.User.name} (${attendee.Attendee.AttendeeId})`;
|
|
976
|
+
}
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
Bundle Amazon Chime SDK into single amazon-chime-sdk.min.js file and copy it to *app/assets/javascripts* by *amazon-chime-sdk-rails* generator:
|
|
980
|
+
|
|
981
|
+
```bash
|
|
982
|
+
$ rails g chime_sdk:js
|
|
983
|
+
```
|
|
984
|
+
|
|
985
|
+
Add *amazon-chime-sdk.min.js* to your Asset Pipeline:
|
|
986
|
+
|
|
987
|
+
```ruby:config/initializers/assets.rb
|
|
988
|
+
# config/initializers/assets.rb
|
|
989
|
+
|
|
990
|
+
Rails.application.config.assets.precompile += %w( amazon-chime-sdk.min.js )
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
Then, add member management and meeting link to your room view:
|
|
994
|
+
|
|
995
|
+
```erb:app/views/rooms/show.html.erb
|
|
996
|
+
# app/views/rooms/show.html.erb
|
|
997
|
+
|
|
998
|
+
<p id="notice"><%= notice %></p>
|
|
999
|
+
|
|
1000
|
+
<p>
|
|
1001
|
+
<strong>Name:</strong>
|
|
1002
|
+
<%= @room.name %>
|
|
1003
|
+
</p>
|
|
1004
|
+
|
|
1005
|
+
<p>
|
|
1006
|
+
<strong>Private Meeting:</strong>
|
|
1007
|
+
<p><%= link_to 'Show Meetings', room_meetings_path(@room) %></p>
|
|
1008
|
+
<p><%= link_to 'Join the Meeting', room_meetings_path(@room), method: :post %></p>
|
|
1009
|
+
</p>
|
|
1010
|
+
|
|
1011
|
+
<p>
|
|
1012
|
+
<strong>Members:</strong>
|
|
1013
|
+
<table>
|
|
1014
|
+
<tbody>
|
|
1015
|
+
<% @room.entries.each do |entry| %>
|
|
1016
|
+
<tr>
|
|
1017
|
+
<td><%= entry.user.name %></td>
|
|
1018
|
+
<td><%= link_to 'Remove', [@room, entry], method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
|
1019
|
+
</tr>
|
|
1020
|
+
<% end %>
|
|
1021
|
+
</tbody>
|
|
1022
|
+
</table>
|
|
1023
|
+
</p>
|
|
1024
|
+
|
|
1025
|
+
<p>
|
|
1026
|
+
<strong>Add members:</strong>
|
|
1027
|
+
<%= form_for [@room, Entry.new] do |f| %>
|
|
1028
|
+
<%= f.hidden_field :room_id, value: @room.id %>
|
|
1029
|
+
<%= f.collection_select :user_id, User.all, :id, :name %>
|
|
1030
|
+
<%= f.submit "Add" %>
|
|
1031
|
+
<% end %>
|
|
1032
|
+
</p>
|
|
1033
|
+
|
|
1034
|
+
<%= link_to 'Edit', edit_room_path(@room) %> |
|
|
1035
|
+
<%= link_to 'Back', rooms_path %>
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
Update your `routes.rb` like this:
|
|
1039
|
+
|
|
1040
|
+
```ruby:config/routes.rb
|
|
1041
|
+
# config/routes.rb
|
|
1042
|
+
|
|
1043
|
+
Rails.application.routes.draw do
|
|
1044
|
+
root "rooms#index"
|
|
1045
|
+
devise_for :users
|
|
1046
|
+
resources :rooms do
|
|
1047
|
+
resources :entries, only: [:create, :destroy]
|
|
1048
|
+
resources :meetings, only: [:index, :show, :create, :destroy] do
|
|
1049
|
+
resources :meeting_attendees, as: :attendees, path: :attendees, only: [:index, :show]
|
|
1050
|
+
end
|
|
1051
|
+
end
|
|
1052
|
+
end
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
Note that you need to set up AWS credentials or IAM role for *amazon-chime-sdk-rails*. See [Set up AWS credentials](#set-up-aws-credentials) for more details.
|
|
1056
|
+
|
|
1057
|
+
Finally, start rails server:
|
|
1058
|
+
|
|
1059
|
+
```bash
|
|
1060
|
+
$ rails server
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
Now ready to take off!
|
|
1064
|
+
|
|
1065
|
+
#### Start meeting with your Rails application
|
|
1066
|
+
|
|
1067
|
+
Access *http://localhost:3000/* through your web browser.
|
|
1068
|
+
|
|
1069
|
+
Sign up users from *Sign up* header. For example, sign up *ichiro* as *ichiro@example.com* and *stephen* as *stephen@example.com*.
|
|
1070
|
+
|
|
1071
|
+
Create new room and add *ichiro* and *stephen* as a room member.
|
|
1072
|
+
|
|
1073
|
+
Now you can join the meeting from *"Join the Meeting"* link in your room view. Your rails application includes simple online meeting implementation using [Amazon Chime SDK](https://aws.amazon.com/chime/chime-sdk) as a Rails view.
|
|
1074
|
+
|
|
1075
|
+
##### The meeting has been created
|
|
1076
|
+
|
|
1077
|
+
<kbd></kbd>
|
|
1078
|
+
|
|
1079
|
+
##### Ichiro and Stephen have joined the meeting
|
|
1080
|
+
|
|
1081
|
+
<kbd></kbd>
|
|
1082
|
+
|
|
1083
|
+
You should customize your meeting view using [Amazon Chime SDK for JavaScript](https://github.com/aws/amazon-chime-sdk-js). See [sample Rails application](/spec/rails_app/) using [Amazon Chime SDK for JavaScript](https://github.com/aws/amazon-chime-sdk-js) as a part of [example Rails application](#examples).
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
## Documentation
|
|
1087
|
+
|
|
1088
|
+
See [API Reference](http://www.rubydoc.info/github/simukappu/amazon-chime-sdk-rails/index) for more details.
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
## Examples
|
|
1092
|
+
|
|
1093
|
+
See example Rails application in *[/spec/rails_app](/spec/rails_app)*. You can run this example Rails application by the following steps:
|
|
1094
|
+
|
|
1095
|
+
```bash
|
|
1096
|
+
$ git clone https://github.com/simukappu/amazon-chime-sdk-rails.git
|
|
1097
|
+
$ cd amazon-chime-sdk-rails
|
|
1098
|
+
$ bundle install
|
|
1099
|
+
$ cd spec/rails_app
|
|
1100
|
+
$ bin/rake db:migrate
|
|
1101
|
+
$ bin/rake db:seed
|
|
1102
|
+
$ bin/rails g chime_sdk:js
|
|
1103
|
+
$ bin/rails server
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
## License
|
|
1108
|
+
|
|
1109
|
+
*amazon-chime-sdk-rails* project rocks and uses [MIT License](LICENSE).
|