amazon-chime-sdk-rails 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +69 -0
- data/.gitignore +7 -1
- data/CHANGELOG.md +19 -0
- data/Dockerfile +15 -0
- data/Gemfile +5 -3
- data/README.md +132 -1005
- data/docs/Develop_Rails_API_Application.md +569 -0
- data/docs/Develop_Rails_View_Application.md +441 -0
- data/gemfiles/Gemfile.rails-5.0 +1 -1
- data/gemfiles/Gemfile.rails-5.1 +0 -1
- data/gemfiles/Gemfile.rails-5.2 +0 -1
- data/gemfiles/Gemfile.rails-6.0 +0 -1
- data/gemfiles/Gemfile.rails-6.1 +24 -0
- data/gemfiles/Gemfile.rails-7.0 +30 -0
- data/lib/chime_sdk/controller/meetings.rb +4 -3
- data/lib/chime_sdk/version.rb +1 -1
- data/lib/generators/chime_sdk/js_generator.rb +72 -9
- data/lib/generators/templates/controllers/meetings_controller.rb +1 -1
- data/spec/generators/js_generator_spec.rb +66 -6
- data/spec/rails_app/app/assets/config/manifest.js +1 -0
- data/spec/rails_app/app/assets/javascripts/application.js +3 -0
- data/spec/rails_app/app/controllers/api/public/meeting_attendees_controller.rb +11 -0
- data/spec/rails_app/app/controllers/api/public/meetings_controller.rb +15 -0
- data/spec/rails_app/app/controllers/meetings_controller.rb +1 -1
- data/spec/rails_app/app/views/layouts/_header.html.erb +1 -5
- data/spec/rails_app/app/views/layouts/application.html.erb +1 -2
- data/spec/rails_app/app/views/meetings/show.html.erb +22 -2
- data/spec/rails_app/config/application.rb +11 -2
- data/spec/rails_app/config/initializers/devise_token_auth.rb +1 -1
- data/spec/rails_app/config/routes.rb +10 -3
- data/spec/rails_app/db/seeds.rb +1 -1
- data/spec/requests/meetings_spec.rb +1 -1
- data/templates/amazon-chime-sdk-policy.yml +49 -0
- metadata +19 -57
- data/.travis.yml +0 -47
- data/spec/rails_app/app/controllers/spa_controller.rb +0 -6
- data/spec/rails_app/app/javascript/App.vue +0 -50
- data/spec/rails_app/app/javascript/channels/consumer.js +0 -6
- data/spec/rails_app/app/javascript/channels/index.js +0 -5
- data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +0 -84
- data/spec/rails_app/app/javascript/components/meetings/Index.vue +0 -100
- data/spec/rails_app/app/javascript/components/meetings/Meeting.vue +0 -178
- data/spec/rails_app/app/javascript/components/rooms/Index.vue +0 -53
- data/spec/rails_app/app/javascript/components/rooms/Show.vue +0 -91
- data/spec/rails_app/app/javascript/packs/application.js +0 -17
- data/spec/rails_app/app/javascript/packs/spa.js +0 -14
- data/spec/rails_app/app/javascript/router/index.js +0 -74
- data/spec/rails_app/app/javascript/store/index.js +0 -37
- data/spec/rails_app/app/views/spa/index.html.erb +0 -1
- data/spec/rails_app/babel.config.js +0 -72
- data/spec/rails_app/bin/webpack +0 -18
- data/spec/rails_app/bin/webpack-dev-server +0 -18
- data/spec/rails_app/config/webpack/development.js +0 -5
- data/spec/rails_app/config/webpack/environment.js +0 -7
- data/spec/rails_app/config/webpack/loaders/vue.js +0 -6
- data/spec/rails_app/config/webpack/production.js +0 -5
- data/spec/rails_app/config/webpack/test.js +0 -5
- data/spec/rails_app/config/webpacker.yml +0 -97
- data/spec/rails_app/package.json +0 -23
- data/spec/rails_app/postcss.config.js +0 -12
@@ -0,0 +1,569 @@
|
|
1
|
+
## Develop your Rails API Application
|
2
|
+
|
3
|
+
Let's start to build simple Rails API application providing real-time communications in a private room.
|
4
|
+
For example, create Rails API application using [Devise Token Auth](https://github.com/lynndylanhurley/devise_token_auth) for user authentication.
|
5
|
+
|
6
|
+
### Prepare Rails API application
|
7
|
+
|
8
|
+
At first, create new Rails application:
|
9
|
+
|
10
|
+
```bash
|
11
|
+
$ rails new chime_api_app --api
|
12
|
+
$ cd chime_api_app
|
13
|
+
```
|
14
|
+
|
15
|
+
Add gems to your Gemfile:
|
16
|
+
|
17
|
+
```ruby:Gemfile
|
18
|
+
# Gemfile
|
19
|
+
|
20
|
+
gem 'devise_token_auth'
|
21
|
+
gem 'amazon-chime-sdk-rails'
|
22
|
+
```
|
23
|
+
|
24
|
+
Then, install *devise_token_auth*:
|
25
|
+
|
26
|
+
```bash
|
27
|
+
$ bundle install
|
28
|
+
$ rails g devise:install
|
29
|
+
$ rails g devise_token_auth:install User auth
|
30
|
+
```
|
31
|
+
|
32
|
+
Update your `application_controller.rb` like this:
|
33
|
+
|
34
|
+
```ruby:app/controllers/application_controller.rb
|
35
|
+
# app/controllers/application_controller.rb
|
36
|
+
|
37
|
+
class ApplicationController < ActionController::API
|
38
|
+
include ActionController::Helpers
|
39
|
+
include DeviseTokenAuth::Concerns::SetUserByToken
|
40
|
+
before_action :configure_permitted_parameters, if: :devise_controller?
|
41
|
+
|
42
|
+
protected
|
43
|
+
def configure_permitted_parameters
|
44
|
+
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
Update your `user.rb` to remove unnecessary options like this:
|
50
|
+
|
51
|
+
```ruby:app/models/user.rb
|
52
|
+
# app/models/user.rb
|
53
|
+
|
54
|
+
class User < ActiveRecord::Base
|
55
|
+
devise :database_authenticatable, :registerable
|
56
|
+
include DeviseTokenAuth::Concerns::User
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
Update *devise_token_auth* configuration in `devise_token_auth.rb` to keep authorization headers:
|
61
|
+
|
62
|
+
```ruby:config/initializers/devise_token_auth.rb
|
63
|
+
# config/initializers/devise_token_auth.rb
|
64
|
+
|
65
|
+
DeviseTokenAuth.setup do |config|
|
66
|
+
# Uncomment and update
|
67
|
+
config.change_headers_on_each_request = false
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
### Create private room functions
|
72
|
+
|
73
|
+
Create models and controllers by generator:
|
74
|
+
|
75
|
+
```bash
|
76
|
+
$ rails g model room name:string
|
77
|
+
$ rails g scaffold_controller api/rooms name:string --model-name=room
|
78
|
+
$ rails g model entry room:references user:references
|
79
|
+
$ rails g scaffold_controller api/entries room:references user:references --model-name=entry
|
80
|
+
$ rake db:migrate
|
81
|
+
```
|
82
|
+
|
83
|
+
Update your `room.rb` like this:
|
84
|
+
|
85
|
+
```ruby:app/models/room.rb
|
86
|
+
# app/models/room.rb
|
87
|
+
|
88
|
+
class Room < ApplicationRecord
|
89
|
+
has_many :entries, dependent: :destroy
|
90
|
+
has_many :members, through: :entries, source: :user
|
91
|
+
|
92
|
+
def member?(user)
|
93
|
+
members.include?(user)
|
94
|
+
end
|
95
|
+
|
96
|
+
def as_json(options = {})
|
97
|
+
super options.merge(:methods => [:members])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
Add uniqueness validation to your `entry.rb` like this:
|
103
|
+
|
104
|
+
```ruby:app/models/entry.rb
|
105
|
+
# app/models/entry.rb
|
106
|
+
|
107
|
+
class Entry < ApplicationRecord
|
108
|
+
belongs_to :room
|
109
|
+
belongs_to :user
|
110
|
+
# Add uniqueness validation
|
111
|
+
validates :user, uniqueness: { scope: :room }
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
Remove location header from your `rooms_controller.rb` and `entries_controller.rb` like this:
|
116
|
+
|
117
|
+
```ruby:app/controllers/api/rooms_controller.rb
|
118
|
+
# app/controllers/api/rooms_controller.rb
|
119
|
+
|
120
|
+
# POST /rooms
|
121
|
+
def create
|
122
|
+
@room = Room.new(room_params)
|
123
|
+
|
124
|
+
if @room.save
|
125
|
+
render json: @room, status: :created # Remove location header
|
126
|
+
else
|
127
|
+
render json: @room.errors, status: :unprocessable_entity
|
128
|
+
end
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
```ruby:app/controllers/api/entries_controller.rb
|
133
|
+
# app/controllers/api/entries_controller.rb
|
134
|
+
|
135
|
+
# POST /entries
|
136
|
+
def create
|
137
|
+
@entry = Entry.new(entry_params)
|
138
|
+
|
139
|
+
if @entry.save
|
140
|
+
render json: @entry, status: :created # Remove location header
|
141
|
+
else
|
142
|
+
render json: @entry.errors, status: :unprocessable_entity
|
143
|
+
end
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
147
|
+
### Develop meeting functions with amazon-chime-sdk-rails
|
148
|
+
|
149
|
+
Install *amazon-chime-sdk-rails* and generate your controllers by *Controller Generator*:
|
150
|
+
|
151
|
+
```bash
|
152
|
+
$ rails g chime_sdk:install
|
153
|
+
$ rails g chime_sdk:controllers -r room -n api
|
154
|
+
```
|
155
|
+
|
156
|
+
Add and uncomment several functions in generated `meetings_controller.rb` and `meeting_attendees_controller.rb` for your app configurations:
|
157
|
+
|
158
|
+
```ruby:app/controllers/api/meetings_controller.rb
|
159
|
+
# app/controllers/api/meetings_controller.rb
|
160
|
+
|
161
|
+
class Api::MeetingsController < ApplicationController
|
162
|
+
before_action :authenticate_api_user!
|
163
|
+
include DeviseTokenAuth::Concerns::SetUserByToken
|
164
|
+
before_action :set_room
|
165
|
+
before_action :check_membership
|
166
|
+
|
167
|
+
include ChimeSdk::Controller::Meetings::Mixin
|
168
|
+
|
169
|
+
private
|
170
|
+
# Add
|
171
|
+
def set_room
|
172
|
+
@room = Room.find(params[:room_id])
|
173
|
+
end
|
174
|
+
|
175
|
+
# Add
|
176
|
+
def check_membership
|
177
|
+
unless @room.member?(current_api_user)
|
178
|
+
message = 'Unauthorized: you are not a member of this private room.'
|
179
|
+
render json: { room: @room, notice: message }, status: :forbidden
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Uncomment
|
184
|
+
def meeting_request_id
|
185
|
+
"PrivateRoom-#{@room.id}"
|
186
|
+
end
|
187
|
+
|
188
|
+
# Uncomment and update
|
189
|
+
def attendee_request_id
|
190
|
+
"User-#{current_api_user.id}"
|
191
|
+
end
|
192
|
+
|
193
|
+
# Uncomment
|
194
|
+
def application_meeting_metadata(meeting)
|
195
|
+
{
|
196
|
+
"MeetingType": "PrivateRoom",
|
197
|
+
"PrivateRoom": @room
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
# Uncomment
|
202
|
+
def application_attendee_metadata(attendee)
|
203
|
+
user_id = attendee[:Attendee][:ExternalUserId].split('-')[3]
|
204
|
+
{
|
205
|
+
"AttendeeType": "User",
|
206
|
+
"User": User.find_by_id(user_id)
|
207
|
+
}
|
208
|
+
end
|
209
|
+
end
|
210
|
+
```
|
211
|
+
|
212
|
+
```ruby:app/controllers/api/meeting_attendees_controller.rb
|
213
|
+
# app/controllers/api/meeting_attendees_controller.rb
|
214
|
+
|
215
|
+
class Api::MeetingAttendeesController < ApplicationController
|
216
|
+
before_action :authenticate_api_user!
|
217
|
+
include DeviseTokenAuth::Concerns::SetUserByToken
|
218
|
+
before_action :set_room
|
219
|
+
before_action :check_membership
|
220
|
+
|
221
|
+
include ChimeSdk::Controller::Attendees::Mixin
|
222
|
+
|
223
|
+
private
|
224
|
+
# Add
|
225
|
+
def set_room
|
226
|
+
@room = Room.find(params[:room_id])
|
227
|
+
end
|
228
|
+
|
229
|
+
# Add
|
230
|
+
def check_membership
|
231
|
+
unless @room.member?(current_api_user)
|
232
|
+
message = 'Unauthorized: you are not a member of this private room.'
|
233
|
+
render json: { room: @room, notice: message }, status: :forbidden
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# Uncomment and update
|
238
|
+
def attendee_request_id
|
239
|
+
"User-#{current_api_user.id}"
|
240
|
+
end
|
241
|
+
|
242
|
+
# Uncomment
|
243
|
+
def application_attendee_metadata(attendee)
|
244
|
+
user_id = attendee[:Attendee][:ExternalUserId].split('-')[3]
|
245
|
+
{
|
246
|
+
"AttendeeType": "User",
|
247
|
+
"User": User.find_by_id(user_id)
|
248
|
+
}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
```
|
252
|
+
|
253
|
+
Then, update your `routes.rb` like this:
|
254
|
+
|
255
|
+
```ruby:config/routes.rb
|
256
|
+
# config/routes.rb
|
257
|
+
|
258
|
+
Rails.application.routes.draw do
|
259
|
+
namespace :api do
|
260
|
+
scope :"v1" do
|
261
|
+
mount_devise_token_auth_for 'User', at: 'auth'
|
262
|
+
resources :rooms do
|
263
|
+
resources :entries, only: [:create, :destroy]
|
264
|
+
resources :meetings, defaults: { format: :json }, only: [:index, :show, :create, :destroy] do
|
265
|
+
resources :meeting_attendees, as: :attendees, path: :attendees, only: [:index, :show, :create, :destroy]
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
```
|
272
|
+
|
273
|
+
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.
|
274
|
+
|
275
|
+
Finally, start rails server:
|
276
|
+
|
277
|
+
```bash
|
278
|
+
$ rails s
|
279
|
+
```
|
280
|
+
|
281
|
+
Now ready to take off!
|
282
|
+
|
283
|
+
### Get meeting configurations through Rails API
|
284
|
+
|
285
|
+
Created Rails API works like this:
|
286
|
+
|
287
|
+
```bash
|
288
|
+
# Sign up users
|
289
|
+
|
290
|
+
$ 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"}'
|
291
|
+
|
292
|
+
{"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"}}
|
293
|
+
|
294
|
+
$ 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"}'
|
295
|
+
|
296
|
+
{"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"}}
|
297
|
+
|
298
|
+
# Create private room
|
299
|
+
|
300
|
+
$ curl localhost:3000/api/v1/rooms -X POST -H "content-type:application/json" -d '{"room":{"name":"PrivateRoom-1"}}'
|
301
|
+
|
302
|
+
{"id":1,"name":"PrivateRoom-1","created_at":"2020-10-16T11:15:56.223Z","updated_at":"2020-10-16T11:15:56.223Z","members":[]}
|
303
|
+
|
304
|
+
# You cannot create meeting yet because the user is not signed in
|
305
|
+
|
306
|
+
$ curl localhost:3000/api/v1/rooms/3/meetings -X POST -H "content-type:application/json"
|
307
|
+
|
308
|
+
{"errors":["You need to sign in or sign up before continuing."]}
|
309
|
+
|
310
|
+
# Sign in as ichiro
|
311
|
+
|
312
|
+
$ 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"}'
|
313
|
+
|
314
|
+
{"data":{"id":1,"email":"ichiro@example.com","provider":"email","uid":"ichiro@example.com","allow_password_change":false,"name":"ichiro","nickname":null,"image":null}}
|
315
|
+
|
316
|
+
$ _ACCESS_TOKEN=$(cat auth_headers.txt | grep access-token | rev | cut -c 2- | rev)
|
317
|
+
$ _CLIENT=$(cat auth_headers.txt | grep client | rev | cut -c 2- | rev)
|
318
|
+
$ _UID=$(cat auth_headers.txt | grep uid | rev | cut -c 2- | rev)
|
319
|
+
|
320
|
+
# You cannot create meeting yet because the user is not a member of the private room
|
321
|
+
|
322
|
+
$ curl localhost:3000/api/v1/rooms/1/meetings -X POST -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}"
|
323
|
+
|
324
|
+
{"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."}
|
325
|
+
|
326
|
+
# Add users to the private room
|
327
|
+
|
328
|
+
$ curl localhost:3000/api/v1/rooms/1/entries -X POST -H "content-type:application/json" -d '{"entry":{"room_id":1,"user_id":1}}'
|
329
|
+
|
330
|
+
{"id":1,"room_id":1,"user_id":1,"created_at":"2020-10-16T11:18:22.839Z","updated_at":"2020-10-16T11:18:22.839Z"}
|
331
|
+
|
332
|
+
$ curl localhost:3000/api/v1/rooms/1/entries -X POST -H "content-type:application/json" -d '{"entry":{"room_id":1,"user_id":2}}'
|
333
|
+
|
334
|
+
{"id":2,"room_id":1,"user_id":2,"created_at":"2020-10-16T11:18:41.116Z","updated_at":"2020-10-16T11:18:41.116Z"}
|
335
|
+
|
336
|
+
# Now you can create meeting as a member of the private room
|
337
|
+
|
338
|
+
$ curl localhost:3000/api/v1/rooms/1/meetings -X POST -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}" | jq .
|
339
|
+
|
340
|
+
{
|
341
|
+
"Meeting": {
|
342
|
+
"MeetingId": "2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
343
|
+
"ExternalMeetingId": "ChimeSdkRailsApp-development-PrivateRoom-1",
|
344
|
+
"MediaPlacement": {
|
345
|
+
"AudioHostUrl": "d3175d855e633b72aedbXXXXXXXXXXXX.k.m2.ue1.app.chime.aws:3478",
|
346
|
+
"AudioFallbackUrl": "wss://haxrp.m2.ue1.app.chime.aws:443/calls/2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
347
|
+
"ScreenDataUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/v2/screen/2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
348
|
+
"ScreenSharingUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/v2/screen/2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
349
|
+
"ScreenViewingUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/ws/connect?passcode=null&viewer_uuid=null&X-BitHub-Call-Id=2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
350
|
+
"SignalingUrl": "wss://signal.m2.ue1.app.chime.aws/control/2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
351
|
+
"TurnControlUrl": "https://ccp.cp.ue1.app.chime.aws/v2/turn_sessions"
|
352
|
+
},
|
353
|
+
"MediaRegion": "us-east-1",
|
354
|
+
"ApplicationMetadata": {
|
355
|
+
"MeetingType": "PrivateRoom",
|
356
|
+
"Room": {
|
357
|
+
"id": 1,
|
358
|
+
"name": "PrivateRoom-1",
|
359
|
+
"created_at": "2020-10-16T11:15:56.223Z",
|
360
|
+
"updated_at": "2020-10-16T11:15:56.223Z",
|
361
|
+
"members": [
|
362
|
+
{
|
363
|
+
"id": 1,
|
364
|
+
"provider": "email",
|
365
|
+
"uid": "ichiro@example.com",
|
366
|
+
"allow_password_change": false,
|
367
|
+
"name": "ichiro",
|
368
|
+
"nickname": null,
|
369
|
+
"image": null,
|
370
|
+
"email": "ichiro@example.com",
|
371
|
+
"created_at": "2020-10-16T11:14:48.731Z",
|
372
|
+
"updated_at": "2020-10-16T11:16:56.927Z"
|
373
|
+
},
|
374
|
+
{
|
375
|
+
"id": 2,
|
376
|
+
"provider": "email",
|
377
|
+
"uid": "stephen@example.com",
|
378
|
+
"allow_password_change": false,
|
379
|
+
"name": "stephen",
|
380
|
+
"nickname": null,
|
381
|
+
"image": null,
|
382
|
+
"email": "stephen@example.com",
|
383
|
+
"created_at": "2020-10-16T11:15:33.226Z",
|
384
|
+
"updated_at": "2020-10-16T11:15:33.314Z"
|
385
|
+
}
|
386
|
+
]
|
387
|
+
}
|
388
|
+
}
|
389
|
+
},
|
390
|
+
"Attendee": {
|
391
|
+
"ExternalUserId": "ChimeSdkRailsApp-development-User-1",
|
392
|
+
"AttendeeId": "b581c46d-661f-92bb-d80e-XXXXXXXXXXXX",
|
393
|
+
"JoinToken": "YjU4MWM0NmQtNjYxZi05MmJiLWQ4MGUtZjRiMTU3ZDk1ZmU5OjgyZmM2NTMxLTIwMjctNGMxMS04OTE0LTQwZjXXXXXXXXXXXX",
|
394
|
+
"ApplicationMetadata": {
|
395
|
+
"AttendeeType": "User",
|
396
|
+
"User": {
|
397
|
+
"id": 1,
|
398
|
+
"provider": "email",
|
399
|
+
"uid": "ichiro@example.com",
|
400
|
+
"allow_password_change": false,
|
401
|
+
"name": "ichiro",
|
402
|
+
"nickname": null,
|
403
|
+
"image": null,
|
404
|
+
"email": "ichiro@example.com",
|
405
|
+
"created_at": "2020-10-16T11:14:48.731Z",
|
406
|
+
"updated_at": "2020-10-16T11:16:56.927Z"
|
407
|
+
}
|
408
|
+
}
|
409
|
+
}
|
410
|
+
}
|
411
|
+
|
412
|
+
# Get attendee data from created meeting ID
|
413
|
+
|
414
|
+
$ 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)
|
415
|
+
|
416
|
+
$ curl localhost:3000/api/v1/rooms/1/meetings/${MEETING_ID}/attendees -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}" | jq .
|
417
|
+
|
418
|
+
{
|
419
|
+
"attendees": [
|
420
|
+
{
|
421
|
+
"Attendee": {
|
422
|
+
"ExternalUserId": "ChimeSdkRailsApp-development-User-1",
|
423
|
+
"AttendeeId": "b581c46d-661f-92bb-d80e-XXXXXXXXXXXX",
|
424
|
+
"JoinToken": "YjU4MWM0NmQtNjYxZi05MmJiLWQ4MGUtZjRiMTU3ZDk1ZmU5OjgyZmM2NTMxLTIwMjctNGMxMS04OTE0LTQwZjXXXXXXXXXXXX",
|
425
|
+
"ApplicationMetadata": {
|
426
|
+
"AttendeeType": "User",
|
427
|
+
"User": {
|
428
|
+
"id": 1,
|
429
|
+
"provider": "email",
|
430
|
+
"uid": "ichiro@example.com",
|
431
|
+
"allow_password_change": false,
|
432
|
+
"name": "ichiro",
|
433
|
+
"nickname": null,
|
434
|
+
"image": null,
|
435
|
+
"email": "ichiro@example.com",
|
436
|
+
"created_at": "2020-10-16T11:14:48.731Z",
|
437
|
+
"updated_at": "2020-10-16T11:16:56.927Z"
|
438
|
+
}
|
439
|
+
}
|
440
|
+
}
|
441
|
+
}
|
442
|
+
]
|
443
|
+
}
|
444
|
+
|
445
|
+
$ 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)
|
446
|
+
|
447
|
+
$ 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 .
|
448
|
+
|
449
|
+
{
|
450
|
+
"Attendee": {
|
451
|
+
"ExternalUserId": "ChimeSdkRailsApp-development-User-1",
|
452
|
+
"AttendeeId": "b581c46d-661f-92bb-d80e-XXXXXXXXXXXX",
|
453
|
+
"JoinToken": "YjU4MWM0NmQtNjYxZi05MmJiLWQ4MGUtZjRiMTU3ZDk1ZmU5OjgyZmM2NTMxLTIwMjctNGMxMS04OTE0LTQwZjXXXXXXXXXXXX",
|
454
|
+
"ApplicationMetadata": {
|
455
|
+
"AttendeeType": "User",
|
456
|
+
"User": {
|
457
|
+
"id": 1,
|
458
|
+
"provider": "email",
|
459
|
+
"uid": "ichiro@example.com",
|
460
|
+
"allow_password_change": false,
|
461
|
+
"name": "ichiro",
|
462
|
+
"nickname": null,
|
463
|
+
"image": null,
|
464
|
+
"email": "ichiro@example.com",
|
465
|
+
"created_at": "2020-10-16T11:14:48.731Z",
|
466
|
+
"updated_at": "2020-10-16T11:16:56.927Z"
|
467
|
+
}
|
468
|
+
}
|
469
|
+
}
|
470
|
+
}
|
471
|
+
|
472
|
+
# Sign in as stephen
|
473
|
+
|
474
|
+
$ 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"}'
|
475
|
+
|
476
|
+
{"data":{"id":2,"email":"stephen@example.com","provider":"email","uid":"stephen@example.com","allow_password_change":false,"name":"stephen","nickname":null,"image":null}}
|
477
|
+
|
478
|
+
$ _ACCESS_TOKEN=$(cat auth_headers.txt | grep access-token | rev | cut -c 2- | rev)
|
479
|
+
$ _CLIENT=$(cat auth_headers.txt | grep client | rev | cut -c 2- | rev)
|
480
|
+
$ _UID=$(cat auth_headers.txt | grep uid | rev | cut -c 2- | rev)
|
481
|
+
|
482
|
+
# Confirm attending same meeting in the private room as different attendee
|
483
|
+
|
484
|
+
$ curl localhost:3000/api/v1/rooms/1/meetings -X POST -H "content-type:application/json" -H "${_ACCESS_TOKEN}" -H "${_CLIENT}" -H "${_UID}" | jq .
|
485
|
+
|
486
|
+
{
|
487
|
+
"Meeting": {
|
488
|
+
"MeetingId": "2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
489
|
+
"ExternalMeetingId": "ChimeSdkRailsApp-development-PrivateRoom-1",
|
490
|
+
"MediaPlacement": {
|
491
|
+
"AudioHostUrl": "d3175d855e633b72aedbXXXXXXXXXXXX.k.m2.ue1.app.chime.aws:3478",
|
492
|
+
"AudioFallbackUrl": "wss://haxrp.m2.ue1.app.chime.aws:443/calls/2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
493
|
+
"ScreenDataUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/v2/screen/2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
494
|
+
"ScreenSharingUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/v2/screen/2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
495
|
+
"ScreenViewingUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/ws/connect?passcode=null&viewer_uuid=null&X-BitHub-Call-Id=2f550432-579c-4058-XXXXXXXXXXXX",
|
496
|
+
"SignalingUrl": "wss://signal.m2.ue1.app.chime.aws/control/2f550432-579c-4058-bbb9-XXXXXXXXXXXX",
|
497
|
+
"TurnControlUrl": "https://ccp.cp.ue1.app.chime.aws/v2/turn_sessions"
|
498
|
+
},
|
499
|
+
"MediaRegion": "us-east-1",
|
500
|
+
"ApplicationMetadata": {
|
501
|
+
"MeetingType": "PrivateRoom",
|
502
|
+
"Room": {
|
503
|
+
"id": 1,
|
504
|
+
"name": "PrivateRoom-1",
|
505
|
+
"created_at": "2020-10-16T11:15:56.223Z",
|
506
|
+
"updated_at": "2020-10-16T11:15:56.223Z",
|
507
|
+
"members": [
|
508
|
+
{
|
509
|
+
"id": 1,
|
510
|
+
"provider": "email",
|
511
|
+
"uid": "ichiro@example.com",
|
512
|
+
"allow_password_change": false,
|
513
|
+
"name": "ichiro",
|
514
|
+
"nickname": null,
|
515
|
+
"image": null,
|
516
|
+
"email": "ichiro@example.com",
|
517
|
+
"created_at": "2020-10-16T11:14:48.731Z",
|
518
|
+
"updated_at": "2020-10-16T11:16:56.927Z"
|
519
|
+
},
|
520
|
+
{
|
521
|
+
"id": 2,
|
522
|
+
"provider": "email",
|
523
|
+
"uid": "stephen@example.com",
|
524
|
+
"allow_password_change": false,
|
525
|
+
"name": "stephen",
|
526
|
+
"nickname": null,
|
527
|
+
"image": null,
|
528
|
+
"email": "stephen@example.com",
|
529
|
+
"created_at": "2020-10-16T11:15:33.226Z",
|
530
|
+
"updated_at": "2020-10-16T11:21:46.011Z"
|
531
|
+
}
|
532
|
+
]
|
533
|
+
}
|
534
|
+
}
|
535
|
+
},
|
536
|
+
"Attendee": {
|
537
|
+
"ExternalUserId": "ChimeSdkRailsApp-development-User-2",
|
538
|
+
"AttendeeId": "986886fc-dcbc-1d44-4708-XXXXXXXXXXXX",
|
539
|
+
"JoinToken": "OTg2ODg2ZmMtZGNiYy0xZDQ0LTQ3MDgtOTE3YWIyMzExN2RlOjNjNjAzM2E5LWFlNGUtNGVmZi1iNjZjLWMwY2XXXXXXXXXXXX",
|
540
|
+
"ApplicationMetadata": {
|
541
|
+
"AttendeeType": "User",
|
542
|
+
"User": {
|
543
|
+
"id": 2,
|
544
|
+
"provider": "email",
|
545
|
+
"uid": "stephen@example.com",
|
546
|
+
"allow_password_change": false,
|
547
|
+
"name": "stephen",
|
548
|
+
"nickname": null,
|
549
|
+
"image": null,
|
550
|
+
"email": "stephen@example.com",
|
551
|
+
"created_at": "2020-10-16T11:15:33.226Z",
|
552
|
+
"updated_at": "2020-10-16T11:21:46.011Z"
|
553
|
+
}
|
554
|
+
}
|
555
|
+
}
|
556
|
+
}
|
557
|
+
|
558
|
+
$ 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)
|
559
|
+
|
560
|
+
$ echo ${MEETING_ID}
|
561
|
+
|
562
|
+
2f550432-579c-4058-bbb9-XXXXXXXXXXXX
|
563
|
+
|
564
|
+
$ echo ${MEETING_ID_2}
|
565
|
+
|
566
|
+
2f550432-579c-4058-bbb9-XXXXXXXXXXXX
|
567
|
+
```
|
568
|
+
|
569
|
+
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. You can see [customized React Meeting Demo](https://github.com/simukappu/amazon-chime-sdk/tree/main/apps/meeting) as a sample single page application using [React](https://reactjs.org/) and [Amazon Chime SDK for JavaScript](https://github.com/aws/amazon-chime-sdk-js). Enjoy your application development!
|