amazon-chime-sdk-rails 1.0.0 → 1.1.1

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +57 -0
  3. data/.gitignore +7 -1
  4. data/CHANGELOG.md +31 -0
  5. data/Dockerfile +15 -0
  6. data/Gemfile +5 -3
  7. data/README.md +132 -1005
  8. data/config/spring.rb +2 -0
  9. data/docs/Develop_Rails_API_Application.md +569 -0
  10. data/docs/Develop_Rails_View_Application.md +441 -0
  11. data/gemfiles/Gemfile.rails-5.0 +1 -1
  12. data/gemfiles/Gemfile.rails-5.1 +0 -1
  13. data/gemfiles/Gemfile.rails-5.2 +0 -1
  14. data/gemfiles/Gemfile.rails-6.0 +0 -1
  15. data/gemfiles/Gemfile.rails-6.1 +24 -0
  16. data/gemfiles/Gemfile.rails-7.0 +25 -0
  17. data/lib/chime_sdk/controller/meetings.rb +3 -3
  18. data/lib/chime_sdk/version.rb +1 -1
  19. data/lib/generators/chime_sdk/js_generator.rb +72 -9
  20. data/lib/generators/templates/controllers/meetings_controller.rb +1 -1
  21. data/spec/generators/js_generator_spec.rb +66 -6
  22. data/spec/rails_app/app/assets/config/manifest.js +1 -0
  23. data/spec/rails_app/app/assets/javascripts/application.js +3 -0
  24. data/spec/rails_app/app/controllers/api/public/meeting_attendees_controller.rb +11 -0
  25. data/spec/rails_app/app/controllers/api/public/meetings_controller.rb +15 -0
  26. data/spec/rails_app/app/controllers/meetings_controller.rb +1 -1
  27. data/spec/rails_app/app/views/layouts/_header.html.erb +1 -5
  28. data/spec/rails_app/app/views/layouts/application.html.erb +1 -2
  29. data/spec/rails_app/app/views/meetings/show.html.erb +22 -2
  30. data/spec/rails_app/config/application.rb +11 -2
  31. data/spec/rails_app/config/initializers/devise_token_auth.rb +1 -1
  32. data/spec/rails_app/config/routes.rb +10 -3
  33. data/spec/rails_app/db/seeds.rb +1 -1
  34. data/spec/requests/meetings_spec.rb +1 -1
  35. data/templates/amazon-chime-sdk-policy.yml +49 -0
  36. metadata +20 -57
  37. data/.travis.yml +0 -47
  38. data/spec/rails_app/app/controllers/spa_controller.rb +0 -6
  39. data/spec/rails_app/app/javascript/App.vue +0 -50
  40. data/spec/rails_app/app/javascript/channels/consumer.js +0 -6
  41. data/spec/rails_app/app/javascript/channels/index.js +0 -5
  42. data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +0 -84
  43. data/spec/rails_app/app/javascript/components/meetings/Index.vue +0 -100
  44. data/spec/rails_app/app/javascript/components/meetings/Meeting.vue +0 -178
  45. data/spec/rails_app/app/javascript/components/rooms/Index.vue +0 -53
  46. data/spec/rails_app/app/javascript/components/rooms/Show.vue +0 -91
  47. data/spec/rails_app/app/javascript/packs/application.js +0 -17
  48. data/spec/rails_app/app/javascript/packs/spa.js +0 -14
  49. data/spec/rails_app/app/javascript/router/index.js +0 -74
  50. data/spec/rails_app/app/javascript/store/index.js +0 -37
  51. data/spec/rails_app/app/views/spa/index.html.erb +0 -1
  52. data/spec/rails_app/babel.config.js +0 -72
  53. data/spec/rails_app/bin/webpack +0 -18
  54. data/spec/rails_app/bin/webpack-dev-server +0 -18
  55. data/spec/rails_app/config/webpack/development.js +0 -5
  56. data/spec/rails_app/config/webpack/environment.js +0 -7
  57. data/spec/rails_app/config/webpack/loaders/vue.js +0 -6
  58. data/spec/rails_app/config/webpack/production.js +0 -5
  59. data/spec/rails_app/config/webpack/test.js +0 -5
  60. data/spec/rails_app/config/webpacker.yml +0 -97
  61. data/spec/rails_app/package.json +0 -23
  62. data/spec/rails_app/postcss.config.js +0 -12
data/config/spring.rb ADDED
@@ -0,0 +1,2 @@
1
+ Spring.application_root = './spec/rails_app'
2
+ Spring.watch 'lib'
@@ -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!