agora_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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 04a40ffed9d5e20f48386decfc354bc5fe3883a50ab12931a91770cce0f7caeb
4
+ data.tar.gz: 27875a1500f997aff4d662c2291037eee9f2a7502563d43ee9580959635b91d0
5
+ SHA512:
6
+ metadata.gz: '077592d3284b50e15f8487cd3ddb310494c0e09cb67eb95f19153dffac3a41378d34c0eb98ad5ac9e9e7c372c5a58892113c51b4c1c993174c7d7c949ad2fa13'
7
+ data.tar.gz: c588ebe7535c4a88ff6493c4efaa29ded72a11de2e65b15672bc6e5047863d4c7500cf0dbecd82f4b2d0168085462cab867cb6b819bfb6634753ad1aa7a81ee4
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # AgoraRails
2
+
3
+ AgoraRails is a Ruby gem that provides an interface for Agora.io APIs, specifically designed for Ruby on Rails. It offers functionality for generating dynamic tokens and managing cloud recording.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+ ```ruby
9
+ gem 'agora_rails'
10
+ ```
11
+
12
+ And then execute:
13
+ ```
14
+ $ bundle install
15
+ ```
16
+
17
+ ## Configuration
18
+
19
+ Create an initializer file (e.g., `config/initializers/agora_rails.rb`) and add your Agora.io credentials:
20
+
21
+ ```ruby
22
+ AgoraRails.configure do |config|
23
+ config.app_id = 'your_app_id'
24
+ config.app_certificate = 'your_app_certificate'
25
+ config.customer_id = 'your_customer_id'
26
+ config.customer_secret = 'your_customer_secret'
27
+
28
+ config.bucket = 'your_bucket'
29
+ config.access_key = 'your_access_key'
30
+ config.secret_key = 'your_secret_key'
31
+ config.file_prefix = 'your_file_prefix'
32
+ end
33
+ ```
34
+
35
+ The `file_prefix` is optional and is used to store the recording files in a specific folder in your bucket. For example, if you set the file_prefix to `["agora", "calls", "v3"]`, the recording files will be stored in a folder `agora/calls/v3` in your bucket.
36
+
37
+
38
+ ## Usage
39
+
40
+ ### Token Generation
41
+
42
+ The token generator is taken from the [Agora Tools repo](https://github.com/AgoraIO/Tools) and uses DynamicKey2.
43
+ DynamicKey2 requires `uid` to be an integer (i.e. not a string).
44
+
45
+ Generate a token for a specific channel and user:
46
+
47
+ ```ruby
48
+ channel_name = 'my_channel'
49
+ uid = 1234
50
+
51
+ recorder = AgoraRails::CloudRecording.new
52
+ token = recorder.generate_token(channel_name, uid)
53
+ ```
54
+ You can validate the token at https://api-agora.solutions/
55
+
56
+
57
+ ### Cloud Recording
58
+
59
+ Start cloud recording for a channel:
60
+
61
+ ```ruby
62
+ channel_name = 'my_channel'
63
+ uid = 1234
64
+ recorder = AgoraRails::CloudRecording.new
65
+ recorder.start(channel_name, uid)
66
+ ```
67
+
68
+ Stop cloud recording for a channel:
69
+
70
+ If you have the CloudRecording object, you can use it to stop the recording:
71
+
72
+ ```ruby
73
+ recorder.stop
74
+ ```
75
+
76
+ If you don't have the CloudRecording object, you can use the following method to stop the recording:
77
+
78
+ ```ruby
79
+ recorder = AgoraRails::CloudRecording.new
80
+ recorder.stop(channel_name, sid, uid, mode)
81
+
82
+ ```
83
+
84
+
85
+ ## Development
86
+
87
+ Contributions are welcome! Please open an issue or submit a pull request.
88
+
89
+ #### Speech-to-Text (STT)
90
+
91
+ STT support is currently being worked on.
@@ -0,0 +1,131 @@
1
+ require 'dynamic_key2'
2
+ require 'httparty'
3
+
4
+ module AgoraRails
5
+ class CloudRecording
6
+ include HTTParty
7
+ base_uri 'https://api.agora.io/v1/apps'
8
+
9
+ debug_output $stdout # uncomment this for debugging i.e. output to stdout
10
+
11
+ attr_accessor :app_id, :app_certificate, :customer_key, :customer_secret, :auth, :resource_id, :uid, :bucket, :access_key, :secret_key, :sid, :channel_name, :mode
12
+
13
+ def initialize
14
+ self.app_id = AgoraRails.configuration.app_id
15
+ self.app_certificate = AgoraRails.configuration.app_certificate
16
+ self.customer_key = AgoraRails.configuration.customer_key
17
+ self.customer_secret = AgoraRails.configuration.customer_secret
18
+ self.auth = { username: customer_key, password: customer_secret }
19
+ self.uid = "#{rand(2_000_000_000..3_000_000_000)}"
20
+ self.mode = 'mix'
21
+ end
22
+
23
+ def acquire_resource(channel_name, uid = nil)
24
+ self.channel_name = channel_name
25
+ self.uid = uid if uid
26
+ response = self.class.post("/#{app_id}/cloud_recording/acquire",
27
+ basic_auth: auth,
28
+ headers: { 'Content-Type' => 'application/json' },
29
+ body: {
30
+ cname: channel_name,
31
+ uid: self.uid.to_s,
32
+ clientRequest: { resourceExpiredHour: 24 }
33
+ }.to_json
34
+ )
35
+ self.resource_id = handle_response(response)['resourceId']
36
+ end
37
+
38
+ def start(channel_name, uid = nil, mode = nil, recording_config = nil)
39
+ raise "Invalid Channel Name" if channel_name.nil?
40
+ self.channel_name = channel_name
41
+ self.uid = uid if uid
42
+ self.mode = mode if mode
43
+ acquire_resource(channel_name)
44
+ recording_config ||= default_recording_config(channel_name, self.uid)
45
+
46
+ response = self.class.post("/#{app_id}/cloud_recording/resourceid/#{resource_id}/mode/#{self.mode}/start",
47
+ basic_auth: auth,
48
+ headers: { 'Content-Type' => 'application/json' },
49
+ body: recording_config.to_json
50
+ )
51
+ self.sid = handle_response(response)['sid']
52
+ end
53
+
54
+ def stop(channel_name = nil, sid = nil, uid = nil, mode = nil)
55
+ raise "Invalid Channel Name" if channel_name.nil? && self.channel_name.nil?
56
+ raise "Invalid SID" if sid.nil? && self.sid.nil?
57
+ self.channel_name = channel_name if channel_name
58
+ self.sid = sid if sid
59
+ self.uid = uid if uid
60
+ self.mode = mode if mode
61
+
62
+ acquire_resource(self.channel_name) if self.resource_id.nil? # FIXME: should pass resource_id in because it is possible that the resource ID is expired or acquired for another channel
63
+
64
+ response = self.class.post("/#{app_id}/cloud_recording/resourceid/#{self.resource_id}/sid/#{self.sid}/mode/#{self.mode}/stop",
65
+ basic_auth: auth,
66
+ headers: { 'Content-Type' => 'application/json' },
67
+ body: {
68
+ cname: self.channel_name,
69
+ uid: self.uid.to_s,
70
+ clientRequest: {}
71
+ }.to_json
72
+ )
73
+ handle_response(response)
74
+ end
75
+
76
+ def query(channel_name = nil)
77
+ self.channel_name = channel_name if channel_name
78
+ response = self.class.get("/#{app_id}/cloud_recording/resourceid/#{self.resource_id}/sid/#{self.sid}/mode/#{mode}/query",
79
+ basic_auth: auth,
80
+ headers: { 'Content-Type' => 'application/json' },
81
+ )
82
+ handle_response(response)
83
+ end
84
+
85
+
86
+ def generate_token(channel_name = nil, uid = nil)
87
+ self.channel_name = channel_name if channel_name
88
+ self.uid = uid if uid
89
+
90
+ token_expiration_in_seconds = 3600 # 1 hour
91
+ privilege_expiration_in_seconds = 3600 # 1 hour
92
+ ::AgoraDynamicKey2::RtcTokenBuilder.build_token_with_uid(
93
+ app_id, app_certificate, self.channel_name, self.uid,
94
+ ::AgoraDynamicKey2::RtcTokenBuilder::ROLE_PUBLISHER, token_expiration_in_seconds, privilege_expiration_in_seconds
95
+ )
96
+ end
97
+
98
+ private
99
+
100
+ def handle_response(response)
101
+ if response.success?
102
+ JSON.parse(response.body)
103
+ else
104
+ raise AgoraRails::Error, "API request failed: #{response.code} - #{response.body}"
105
+ end
106
+ end
107
+
108
+ def default_recording_config(channel_name, uid)
109
+ {
110
+ cname: channel_name,
111
+ uid: uid.to_s,
112
+ clientRequest: {
113
+ token: generate_token,
114
+ recordingConfig: {
115
+ maxIdleTime: 30,
116
+ streamTypes: 0, # 0: audio only, 1: audio and video, 2: video only
117
+ channelType: 0, # 0: communication (audio call / video call), 1: live-broadcast (video live streaming)
118
+ },
119
+ storageConfig: {
120
+ vendor: 1, # 1: AWS, 2: Azure, 3: GCP, 4: Aliyun, 5: Tencent, 6: Qiniu, 7: AWS_S3, 8: Azure_Blob, 9: GCP_Storage, 10: Aliyun_OSS, 11: Tencent_COS, 12: Qiniu_Kodo
121
+ region: 0, # 0: us-east-1, 1: us-east-2
122
+ bucket: AgoraRails.configuration.bucket,
123
+ accessKey: AgoraRails.configuration.access_key,
124
+ secretKey: AgoraRails.configuration.secret_key,
125
+ fileNamePrefix: AgoraRails.configuration.file_prefix,
126
+ },
127
+ },
128
+ }
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,16 @@
1
+ module AgoraRails
2
+ class Configuration
3
+ attr_accessor :app_id, :app_certificate, :customer_key, :customer_secret, :bucket, :access_key, :secret_key, :file_prefix
4
+
5
+ def initialize
6
+ @app_id = nil
7
+ @app_certificate = nil
8
+ @customer_key = nil
9
+ @customer_secret = nil
10
+ @bucket = nil
11
+ @access_key = nil
12
+ @secret_key = nil
13
+ @file_prefix = nil
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,46 @@
1
+ require 'httparty'
2
+
3
+ module AgoraRails
4
+ class STT
5
+ include HTTParty
6
+ base_uri 'https://api.agora.io/v1/projects'
7
+
8
+ def initialize
9
+ @app_id = AgoraRails.configuration.app_id
10
+ @customer_key = AgoraRails.configuration.customer_key
11
+ @customer_secret = AgoraRails.configuration.customer_secret
12
+ @auth = { username: @customer_key, password: @customer_secret }
13
+ end
14
+
15
+ def start_task(channel_name, uid, config)
16
+ response = self.class.post("/#{@app_id}/rtsc/speech-to-text/tasks",
17
+ basic_auth: @auth,
18
+ headers: { 'Content-Type' => 'application/json' },
19
+ body: {
20
+ channel_name: channel_name,
21
+ uid: uid.to_s,
22
+ config: config
23
+ }.to_json
24
+ )
25
+ handle_response(response)
26
+ end
27
+
28
+ def stop_task(task_id)
29
+ response = self.class.delete("/#{@app_id}/rtsc/speech-to-text/tasks/#{task_id}",
30
+ basic_auth: @auth,
31
+ headers: { 'Content-Type' => 'application/json' }
32
+ )
33
+ handle_response(response)
34
+ end
35
+
36
+ private
37
+
38
+ def handle_response(response)
39
+ if response.success?
40
+ JSON.parse(response.body)
41
+ else
42
+ raise AgoraRails::Error, "API request failed: #{response.code} - #{response.body}"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ require_relative "agora_rails/configuration"
2
+ require_relative "agora_rails/cloud_recording"
3
+ require_relative "agora_rails/stt"
4
+
5
+ module AgoraRails
6
+ class Error < StandardError; end
7
+
8
+ class << self
9
+ attr_accessor :configuration
10
+ end
11
+
12
+ def self.configure
13
+ self.configuration ||= Configuration.new
14
+ yield(configuration)
15
+ end
16
+ end
@@ -0,0 +1,220 @@
1
+ require 'openssl'
2
+ require 'zlib'
3
+ require 'base64'
4
+
5
+ module AgoraDynamicKey2
6
+ class Service
7
+ attr_accessor :type, :privileges
8
+
9
+ def initialize(type)
10
+ @type = type
11
+ @privileges = {}
12
+ end
13
+
14
+ def add_privilege(privilege, expire)
15
+ @privileges[privilege] = expire
16
+ end
17
+
18
+ def fetch_uid(uid)
19
+ return '' if uid.eql?(0)
20
+
21
+ uid.to_s
22
+ end
23
+
24
+ def pack
25
+ Util.pack_uint16(@type) + Util.pack_map_uint32(@privileges)
26
+ end
27
+
28
+ def unpack(data)
29
+ @privileges, data = Util.unpack_map_uint32(data)
30
+ end
31
+ end
32
+
33
+ class ServiceRtc < Service
34
+ attr_accessor :channel_name, :uid
35
+
36
+ SERVICE_TYPE = 1
37
+ PRIVILEGE_JOIN_CHANNEL = 1
38
+ PRIVILEGE_PUBLISH_AUDIO_STREAM = 2
39
+ PRIVILEGE_PUBLISH_VIDEO_STREAM = 3
40
+ PRIVILEGE_PUBLISH_DATA_STREAM = 4
41
+
42
+ def initialize(channel_name = '', uid = '')
43
+ super(SERVICE_TYPE)
44
+ @channel_name = channel_name
45
+ @uid = fetch_uid(uid)
46
+ end
47
+
48
+ def pack
49
+ super() + Util.pack_string(@channel_name) + Util.pack_string(@uid)
50
+ end
51
+
52
+ def unpack(data)
53
+ _, data = super(data)
54
+ @channel_name, data = Util.unpack_string(data)
55
+ @uid, data = Util.unpack_string(data)
56
+ end
57
+ end
58
+
59
+ class ServiceRtm < Service
60
+ attr_accessor :user_id
61
+
62
+ SERVICE_TYPE = 2
63
+ PRIVILEGE_JOIN_LOGIN = 1
64
+
65
+ def initialize(user_id = '')
66
+ super(SERVICE_TYPE)
67
+ @user_id = user_id
68
+ end
69
+
70
+ def pack
71
+ super() + Util.pack_string(@user_id)
72
+ end
73
+
74
+ def unpack(data)
75
+ _, data = super(data)
76
+ @user_id, data = Util.unpack_string(data)
77
+ end
78
+ end
79
+
80
+ class ServiceFpa < Service
81
+ SERVICE_TYPE = 4
82
+ PRIVILEGE_LOGIN = 1
83
+
84
+ def initialize
85
+ super(SERVICE_TYPE)
86
+ end
87
+
88
+ def pack
89
+ super()
90
+ end
91
+
92
+ def unpack(data)
93
+ _, data = super(data)
94
+ end
95
+ end
96
+
97
+ class ServiceChat < Service
98
+ attr_accessor :uid
99
+
100
+ SERVICE_TYPE = 5
101
+ PRIVILEGE_USER = 1
102
+ PRIVILEGE_APP = 2
103
+
104
+ def initialize(uid = '')
105
+ super(SERVICE_TYPE)
106
+ @uid = fetch_uid(uid)
107
+ end
108
+
109
+ def pack
110
+ super() + Util.pack_string(@uid)
111
+ end
112
+
113
+ def unpack(data)
114
+ _, data = super(data)
115
+ @uid, data = Util.unpack_string(data)
116
+ end
117
+ end
118
+
119
+ class ServiceApaas < Service
120
+ attr_accessor :room_uuid, :user_uuid, :role
121
+
122
+ SERVICE_TYPE = 7
123
+ PRIVILEGE_ROOM_USER = 1
124
+ PRIVILEGE_USER = 2
125
+ PRIVILEGE_APP = 3
126
+
127
+ def initialize(room_uuid = '', user_uuid = '', role = -1)
128
+ super(SERVICE_TYPE)
129
+ @room_uuid = room_uuid
130
+ @user_uuid = user_uuid
131
+ @role = role
132
+ end
133
+
134
+ def pack
135
+ super() + Util.pack_string(@room_uuid) + Util.pack_string(@user_uuid) + Util.pack_int16(@role)
136
+ end
137
+
138
+ def unpack(data)
139
+ _, data = super(data)
140
+ @room_uuid, data = Util.unpack_string(data)
141
+ @user_uuid, data = Util.unpack_string(data)
142
+ @role, data = Util.unpack_int16(data)
143
+ end
144
+ end
145
+
146
+ class AccessToken
147
+ attr_accessor :app_cert, :app_id, :expire, :issue_ts, :salt, :services
148
+
149
+ VERSION = '007'.freeze
150
+ VERSION_LENGTH = 3
151
+ SERVICES = { ServiceRtc::SERVICE_TYPE => ServiceRtc,
152
+ ServiceRtm::SERVICE_TYPE => ServiceRtm,
153
+ ServiceFpa::SERVICE_TYPE => ServiceFpa,
154
+ ServiceChat::SERVICE_TYPE => ServiceChat,
155
+ ServiceApaas::SERVICE_TYPE => ServiceApaas }.freeze
156
+
157
+ def initialize(app_id = '', app_cert = '', expire = 900)
158
+ @app_id = app_id
159
+ @app_cert = app_cert
160
+ @expire = expire
161
+ @issue_ts = Time.now.to_i
162
+ @salt = rand(1...99_999_999)
163
+ @services = {}
164
+ end
165
+
166
+ def add_service(service)
167
+ @services[service.type] = service
168
+ end
169
+
170
+ def build
171
+ return '' if !uuid?(@app_id) || !uuid?(@app_cert)
172
+
173
+ signing = fetch_sign
174
+ data = Util.pack_string(@app_id) + Util.pack_uint32(@issue_ts) + Util.pack_uint32(@expire) \
175
+ + Util.pack_uint32(@salt) + Util.pack_uint16(@services.size)
176
+
177
+ @services.each do |_, service|
178
+ data += service.pack
179
+ end
180
+
181
+ signature = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), signing, data)
182
+ fetch_version + Base64.strict_encode64(Zlib::Deflate.deflate(Util.pack_string(signature) + data))
183
+ end
184
+
185
+ def fetch_sign
186
+ sign = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), Util.pack_uint32(@issue_ts), @app_cert)
187
+ OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), Util.pack_uint32(@salt), sign)
188
+ end
189
+
190
+ def fetch_version
191
+ VERSION
192
+ end
193
+
194
+ def uuid?(str)
195
+ return false if str.length != 32
196
+
197
+ true
198
+ end
199
+
200
+ def parse(token)
201
+ return false if token[0..VERSION_LENGTH - 1] != fetch_version
202
+
203
+ data = Zlib::Inflate.inflate(Base64.strict_decode64(token[VERSION_LENGTH..-1]))
204
+ signature, data = Util.unpack_string(data)
205
+ @app_id, data = Util.unpack_string(data)
206
+ @issue_ts, data = Util.unpack_uint32(data)
207
+ @expire, data = Util.unpack_uint32(data)
208
+ @salt, data = Util.unpack_uint32(data)
209
+ service_num, data = Util.unpack_uint16(data)
210
+
211
+ (1..service_num).each do
212
+ service_type, data = Util.unpack_uint16(data)
213
+ service = SERVICES[service_type].new
214
+ _, data = service.unpack(data)
215
+ @services[service_type] = service
216
+ end
217
+ true
218
+ end
219
+ end
220
+ end
@@ -0,0 +1,73 @@
1
+ module AgoraDynamicKey2
2
+ class ApaasTokenBuilder
3
+ # Build room user token.
4
+ #
5
+ # app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing
6
+ # from your kit. See Get an App ID.
7
+ # app_certificate: Certificate of the application that you registered in the Agora Dashboard.
8
+ # See Get an App Certificate.
9
+ # room_uuid: The room's id, must be unique.
10
+ # user_uuid: The user's id, must be unique.
11
+ # role: The user's role.
12
+ # expire: represented by the number of seconds elapsed since now. If, for example, you want to access the
13
+ # Agora Service within 10 minutes after the token is generated, set expire as 600(seconds).
14
+ # return: The room user token.
15
+ def self.build_room_user_token(app_id, app_certificate, room_uuid, user_uuid, role, expire)
16
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, expire)
17
+
18
+ chat_user_id = Digest::MD5.hexdigest user_uuid
19
+ service_apaas = AgoraDynamicKey2::ServiceApaas.new(room_uuid, user_uuid, role)
20
+ service_apaas.add_privilege(AgoraDynamicKey2::ServiceApaas::PRIVILEGE_ROOM_USER, expire)
21
+ access_token.add_service(service_apaas)
22
+
23
+ service_rtm = AgoraDynamicKey2::ServiceRtm.new(user_uuid)
24
+ service_rtm.add_privilege(AgoraDynamicKey2::ServiceRtm::PRIVILEGE_JOIN_LOGIN, expire)
25
+ access_token.add_service(service_rtm)
26
+
27
+ service_chat = AgoraDynamicKey2::ServiceChat.new(chat_user_id)
28
+ service_chat.add_privilege(AgoraDynamicKey2::ServiceChat::PRIVILEGE_USER, expire)
29
+ access_token.add_service(service_chat)
30
+
31
+ access_token.build
32
+ end
33
+
34
+ # Build user token.
35
+ #
36
+ # app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing
37
+ # from your kit. See Get an App ID.
38
+ # app_certificate: Certificate of the application that you registered in the Agora Dashboard.
39
+ # See Get an App Certificate.
40
+ # user_uuid: The user's id, must be unique.
41
+ # expire: represented by the number of seconds elapsed since now. If, for example, you want to access the
42
+ # Agora Service within 10 minutes after the token is generated, set expire as 600(seconds).
43
+ # return: The user token.
44
+ def self.build_user_token(app_id, app_certificate, user_uuid, expire)
45
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, expire)
46
+
47
+ service_apaas = AgoraDynamicKey2::ServiceApaas.new('', user_uuid)
48
+ service_apaas.add_privilege(AgoraDynamicKey2::ServiceApaas::PRIVILEGE_USER, expire)
49
+ access_token.add_service(service_apaas)
50
+
51
+ access_token.build
52
+ end
53
+
54
+ # Build app token.
55
+ #
56
+ # app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing
57
+ # from your kit. See Get an App ID.
58
+ # app_certificate: Certificate of the application that you registered in the Agora Dashboard.
59
+ # See Get an App Certificate.
60
+ # expire: represented by the number of seconds elapsed since now. If, for example, you want to access the
61
+ # Agora Service within 10 minutes after the token is generated, set expire as 600(seconds).
62
+ # return: The app token.
63
+ def self.build_app_token(app_id, app_certificate, expire)
64
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, expire)
65
+
66
+ service_apaas = AgoraDynamicKey2::ServiceApaas.new
67
+ service_apaas.add_privilege(AgoraDynamicKey2::ServiceApaas::PRIVILEGE_APP, expire)
68
+ access_token.add_service(service_apaas)
69
+
70
+ access_token.build
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,42 @@
1
+ module AgoraDynamicKey2
2
+ class ChatTokenBuilder
3
+ # Build the Chat user token.
4
+ #
5
+ # @param app_id: The App ID issued to you by Agora. Apply for a new App ID from
6
+ # Agora Dashboard if it is missing from your kit. See Get an App ID.
7
+ # @param app_certificate: Certificate of the application that you registered in
8
+ # the Agora Dashboard. See Get an App Certificate.
9
+ # @param user_id: The user's account, max length is 64 Bytes.
10
+ # @param expire: represented by the number of seconds elapsed since now. If, for example, you want to access the
11
+ # Agora Service within 10 minutes after the token is generated, set expire as 600(seconds).
12
+ # @return The Chat User token.
13
+ def self.build_user_token(app_id, app_certificate, user_id, expire)
14
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, expire)
15
+
16
+ service_chat = AgoraDynamicKey2::ServiceChat.new(user_id)
17
+ service_chat.add_privilege(AgoraDynamicKey2::ServiceChat::PRIVILEGE_USER, expire)
18
+ access_token.add_service(service_chat)
19
+
20
+ access_token.build
21
+ end
22
+
23
+ # Build the Chat App token.
24
+ #
25
+ # @param app_id: The App ID issued to you by Agora. Apply for a new App ID from
26
+ # Agora Dashboard if it is missing from your kit. See Get an App ID.
27
+ # @param app_certificate: Certificate of the application that you registered in
28
+ # the Agora Dashboard. See Get an App Certificate.
29
+ # @param expire: represented by the number of seconds elapsed since now. If, for example, you want to access the
30
+ # Agora Service within 10 minutes after the token is generated, set expire as 600(seconds).
31
+ # @return The Chat App token.
32
+ def self.build_app_token(app_id, app_certificate, expire)
33
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, expire)
34
+
35
+ service_chat = AgoraDynamicKey2::ServiceChat.new
36
+ service_chat.add_privilege(AgoraDynamicKey2::ServiceChat::PRIVILEGE_APP, expire)
37
+ access_token.add_service(service_chat)
38
+
39
+ access_token.build
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,73 @@
1
+ module AgoraDynamicKey2
2
+ class EducationTokenBuilder
3
+ # Build room user token.
4
+ #
5
+ # app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing
6
+ # from your kit. See Get an App ID.
7
+ # app_certificate: Certificate of the application that you registered in the Agora Dashboard.
8
+ # See Get an App Certificate.
9
+ # room_uuid: The room's id, must be unique.
10
+ # user_uuid: The user's id, must be unique.
11
+ # role: The user's role.
12
+ # expire: represented by the number of seconds elapsed since now. If, for example, you want to access the
13
+ # Agora Service within 10 minutes after the token is generated, set expire as 600(seconds).
14
+ # return: The room user token.
15
+ def self.build_room_user_token(app_id, app_certificate, room_uuid, user_uuid, role, expire)
16
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, expire)
17
+
18
+ chat_user_id = Digest::MD5.hexdigest user_uuid
19
+ service_apaas = AgoraDynamicKey2::ServiceApaas.new(room_uuid, user_uuid, role)
20
+ service_apaas.add_privilege(AgoraDynamicKey2::ServiceApaas::PRIVILEGE_ROOM_USER, expire)
21
+ access_token.add_service(service_apaas)
22
+
23
+ service_rtm = AgoraDynamicKey2::ServiceRtm.new(user_uuid)
24
+ service_rtm.add_privilege(AgoraDynamicKey2::ServiceRtm::PRIVILEGE_JOIN_LOGIN, expire)
25
+ access_token.add_service(service_rtm)
26
+
27
+ service_chat = AgoraDynamicKey2::ServiceChat.new(chat_user_id)
28
+ service_chat.add_privilege(AgoraDynamicKey2::ServiceChat::PRIVILEGE_USER, expire)
29
+ access_token.add_service(service_chat)
30
+
31
+ access_token.build
32
+ end
33
+
34
+ # Build user token.
35
+ #
36
+ # app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing
37
+ # from your kit. See Get an App ID.
38
+ # app_certificate: Certificate of the application that you registered in the Agora Dashboard.
39
+ # See Get an App Certificate.
40
+ # user_uuid: The user's id, must be unique.
41
+ # expire: represented by the number of seconds elapsed since now. If, for example, you want to access the
42
+ # Agora Service within 10 minutes after the token is generated, set expire as 600(seconds).
43
+ # return: The user token.
44
+ def self.build_user_token(app_id, app_certificate, user_uuid, expire)
45
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, expire)
46
+
47
+ service_apaas = AgoraDynamicKey2::ServiceApaas.new('', user_uuid)
48
+ service_apaas.add_privilege(AgoraDynamicKey2::ServiceApaas::PRIVILEGE_USER, expire)
49
+ access_token.add_service(service_apaas)
50
+
51
+ access_token.build
52
+ end
53
+
54
+ # Build app token.
55
+ #
56
+ # app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing
57
+ # from your kit. See Get an App ID.
58
+ # app_certificate: Certificate of the application that you registered in the Agora Dashboard.
59
+ # See Get an App Certificate.
60
+ # expire: represented by the number of seconds elapsed since now. If, for example, you want to access the
61
+ # Agora Service within 10 minutes after the token is generated, set expire as 600(seconds).
62
+ # return: The app token.
63
+ def self.build_app_token(app_id, app_certificate, expire)
64
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, expire)
65
+
66
+ service_apaas = AgoraDynamicKey2::ServiceApaas.new
67
+ service_apaas.add_privilege(AgoraDynamicKey2::ServiceApaas::PRIVILEGE_APP, expire)
68
+ access_token.add_service(service_apaas)
69
+
70
+ access_token.build
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,20 @@
1
+ module AgoraDynamicKey2
2
+ class FpaTokenBuilder
3
+ # Build the FPA token.
4
+ #
5
+ # @param app_id The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing
6
+ # from your kit. See Get an App ID.
7
+ # @param app_certificate Certificate of the application that you registered in the Agora Dashboard.
8
+ # See Get an App Certificate.
9
+ # @return The FPA token.
10
+ def self.build_token(app_id, app_certificate)
11
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, 24 * 3600)
12
+
13
+ service_fpa = AgoraDynamicKey2::ServiceFpa.new
14
+ service_fpa.add_privilege(AgoraDynamicKey2::ServiceFpa::PRIVILEGE_LOGIN, 0)
15
+ access_token.add_service(service_fpa)
16
+
17
+ access_token.build
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,215 @@
1
+ module AgoraDynamicKey2
2
+ class RtcTokenBuilder
3
+ # RECOMMENDED. Use this role for a voice/video call or a live broadcast, if
4
+ # your scenario does not require authentication for
5
+ # [Co-host](https://docs.agora.io/en/video-calling/get-started/authentication-workflow?#co-host-token-authentication).
6
+ ROLE_PUBLISHER = 1
7
+
8
+ # Only use this role if your scenario require authentication for
9
+ # [Co-host](https://docs.agora.io/en/video-calling/get-started/authentication-workflow?#co-host-token-authentication).
10
+ # @note In order for this role to take effect, please contact our support team
11
+ # to enable authentication for Hosting-in for you. Otherwise, Role_Subscriber
12
+ # still has the same privileges as Role_Publisher.
13
+ ROLE_SUBSCRIBER = 2
14
+
15
+ # Build the RTC token with uid.
16
+ #
17
+ # app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing
18
+ # from your kit. See Get an App ID.
19
+ # app_certificate: Certificate of the application that you registered in the Agora Dashboard.
20
+ # See Get an App Certificate.
21
+ # channel_name: Unique channel name for the AgoraRTC session in the string format.
22
+ # uid: User ID. A 32-bit unsigned integer with a value ranging from 1 to (2^32-1).
23
+ # uid must be unique.
24
+ # role: ROLE_PUBLISHER: A broadcaster/host in a live-broadcast profile.
25
+ # ROLE_SUBSCRIBER: An audience(default) in a live-broadcast profile.
26
+ # token_expire: represented by the number of seconds elapsed since now. If, for example,
27
+ # you want to access the Agora Service within 10 minutes after the token is generated,
28
+ # set token_expire as 600(seconds).
29
+ # privilege_expire: represented by the number of seconds elapsed since now. If, for example,
30
+ # you want to enable your privilege for 10 minutes, set privilege_expire as 600(seconds).
31
+ # return: The RTC token.
32
+ def self.build_token_with_uid(app_id, app_certificate, channel_name, uid, role, token_expire, privilege_expire = 0)
33
+ build_token_with_user_account(app_id, app_certificate, channel_name, uid, role, token_expire, privilege_expire)
34
+ end
35
+
36
+ # Build the RTC token with account.
37
+ #
38
+ # app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing
39
+ # from your kit. See Get an App ID.
40
+ # app_certificate: Certificate of the application that you registered in the Agora Dashboard.
41
+ # See Get an App Certificate.
42
+ # channel_name: Unique channel name for the AgoraRTC session in the string format.
43
+ # uid: User ID. A 32-bit unsigned integer with a value ranging from 1 to (2^32-1).
44
+ # uid must be unique.
45
+ # role: ROLE_PUBLISHER: A broadcaster/host in a live-broadcast profile.
46
+ # ROLE_SUBSCRIBER: An audience(default) in a live-broadcast profile.
47
+ # token_expire: represented by the number of seconds elapsed since now. If, for example,
48
+ # you want to access the Agora Service within 10 minutes after the token is generated,
49
+ # set token_expire as 600(seconds).
50
+ # privilege_expire: represented by the number of seconds elapsed since now. If, for example,
51
+ # you want to enable your privilege for 10 minutes, set privilege_expire as 600(seconds).
52
+ # return: The RTC token.
53
+ def self.build_token_with_user_account(app_id, app_certificate, channel_name, account, role, token_expire, privilege_expire = 0)
54
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, token_expire)
55
+ service_rtc = AgoraDynamicKey2::ServiceRtc.new(channel_name, account)
56
+
57
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_JOIN_CHANNEL, privilege_expire)
58
+ if role == ROLE_PUBLISHER
59
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_PUBLISH_AUDIO_STREAM, privilege_expire)
60
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_PUBLISH_VIDEO_STREAM, privilege_expire)
61
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_PUBLISH_DATA_STREAM, privilege_expire)
62
+ end
63
+ access_token.add_service(service_rtc)
64
+ access_token.build
65
+ end
66
+
67
+ # Generates an RTC token with the specified privilege.
68
+ #
69
+ # This method supports generating a token with the following privileges:
70
+ # - Joining an RTC channel.
71
+ # - Publishing audio in an RTC channel.
72
+ # - Publishing video in an RTC channel.
73
+ # - Publishing data streams in an RTC channel.
74
+ #
75
+ # The privileges for publishing audio, video, and data streams in an RTC channel apply only if you have
76
+ # enabled co-host authentication.
77
+ #
78
+ # A user can have multiple privileges. Each privilege is valid for a maximum of 24 hours.
79
+ # The SDK triggers the onTokenPrivilegeWillExpire and onRequestToken callbacks when the token is about to expire
80
+ # or has expired. The callbacks do not report the specific privilege affected, and you need to maintain
81
+ # the respective timestamp for each privilege in your app logic. After receiving the callback, you need
82
+ # to generate a new token, and then call renewToken to pass the new token to the SDK, or call joinChannel to re-join
83
+ # the channel.
84
+ #
85
+ # @note
86
+ # Agora recommends setting a reasonable timestamp for each privilege according to your scenario.
87
+ # Suppose the expiration timestamp for joining the channel is set earlier than that for publishing audio.
88
+ # When the token for joining the channel expires, the user is immediately kicked off the RTC channel
89
+ # and cannot publish any audio stream, even though the timestamp for publishing audio has not expired.
90
+ #
91
+ # @param app_id The App ID of your Agora project.
92
+ # @param app_certificate The App Certificate of your Agora project.
93
+ # @param channel_name The unique channel name for the Agora RTC session in string format. The string length must be less than 64 bytes. The channel name may contain the following characters:
94
+ # - All lowercase English letters: a to z.
95
+ # - All uppercase English letters: A to Z.
96
+ # - All numeric characters: 0 to 9.
97
+ # - The space character.
98
+ # - "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
99
+ # @param uid The user ID. A 32-bit unsigned integer with a value range from 1 to (2^32 - 1). It must be unique. Set uid as 0, if you do not want to authenticate the user ID, that is, any uid from the app client can join the channel.
100
+ # @param token_expire represented by the number of seconds elapsed since now. If, for example, you want to access the
101
+ # Agora Service within 10 minutes after the token is generated, set token_expire as 600(seconds).
102
+ # @param join_channel_privilege_expire represented by the number of seconds elapsed since now.
103
+ # If, for example, you want to join channel and expect stay in the channel for 10 minutes, set join_channel_privilege_expire as 600(seconds).
104
+ # @param pub_audio_privilege_expire represented by the number of seconds elapsed since now.
105
+ # If, for example, you want to enable publish audio privilege for 10 minutes, set pub_audio_privilege_expire as 600(seconds).
106
+ # @param pub_video_privilege_expire represented by the number of seconds elapsed since now.
107
+ # If, for example, you want to enable publish video privilege for 10 minutes, set pub_video_privilege_expire as 600(seconds).
108
+ # @param pub_data_stream_privilege_expire represented by the number of seconds elapsed since now.
109
+ # If, for example, you want to enable publish data stream privilege for 10 minutes, set pub_data_stream_privilege_expire as 600(seconds).
110
+ # @return The RTC Token
111
+ def self.build_token_with_uid_and_privilege(app_id, app_certificate, channel_name, uid, token_expire,
112
+ join_channel_privilege_expire, pub_audio_privilege_expire,
113
+ pub_video_privilege_expire, pub_data_stream_privilege_expire)
114
+ build_token_with_user_account_and_privilege(
115
+ app_id, app_certificate, channel_name, uid, token_expire, join_channel_privilege_expire,
116
+ pub_audio_privilege_expire, pub_video_privilege_expire, pub_data_stream_privilege_expire
117
+ )
118
+ end
119
+
120
+ # Generates an RTC token with the specified privilege.
121
+ #
122
+ # This method supports generating a token with the following privileges:
123
+ # - Joining an RTC channel.
124
+ # - Publishing audio in an RTC channel.
125
+ # - Publishing video in an RTC channel.
126
+ # - Publishing data streams in an RTC channel.
127
+ #
128
+ # The privileges for publishing audio, video, and data streams in an RTC channel apply only if you have
129
+ # enabled co-host authentication.
130
+ #
131
+ # A user can have multiple privileges. Each privilege is valid for a maximum of 24 hours.
132
+ # The SDK triggers the onTokenPrivilegeWillExpire and onRequestToken callbacks when the token is about to expire
133
+ # or has expired. The callbacks do not report the specific privilege affected, and you need to maintain
134
+ # the respective timestamp for each privilege in your app logic. After receiving the callback, you need
135
+ # to generate a new token, and then call renewToken to pass the new token to the SDK, or call joinChannel to re-join
136
+ # the channel.
137
+ #
138
+ # @note
139
+ # Agora recommends setting a reasonable timestamp for each privilege according to your scenario.
140
+ # Suppose the expiration timestamp for joining the channel is set earlier than that for publishing audio.
141
+ # When the token for joining the channel expires, the user is immediately kicked off the RTC channel
142
+ # and cannot publish any audio stream, even though the timestamp for publishing audio has not expired.
143
+ #
144
+ # @param app_id The App ID of your Agora project.
145
+ # @param app_certificate The App Certificate of your Agora project.
146
+ # @param channel_name The unique channel name for the Agora RTC session in string format. The string length must be less than 64 bytes. The channel name may contain the following characters:
147
+ # - All lowercase English letters: a to z.
148
+ # - All uppercase English letters: A to Z.
149
+ # - All numeric characters: 0 to 9.
150
+ # - The space character.
151
+ # - "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
152
+ # @param account The user account.
153
+ # @param token_expire represented by the number of seconds elapsed since now. If, for example, you want to access the
154
+ # Agora Service within 10 minutes after the token is generated, set token_expire as 600(seconds).
155
+ # @param join_channel_privilege_expire represented by the number of seconds elapsed since now.
156
+ # If, for example, you want to join channel and expect stay in the channel for 10 minutes, set join_channel_privilege_expire as 600(seconds).
157
+ # @param pub_audio_privilege_expire represented by the number of seconds elapsed since now.
158
+ # If, for example, you want to enable publish audio privilege for 10 minutes, set pub_audio_privilege_expire as 600(seconds).
159
+ # @param pub_video_privilege_expire represented by the number of seconds elapsed since now.
160
+ # If, for example, you want to enable publish video privilege for 10 minutes, set pub_video_privilege_expire as 600(seconds).
161
+ # @param pub_data_stream_privilege_expire represented by the number of seconds elapsed since now.
162
+ # If, for example, you want to enable publish data stream privilege for 10 minutes, set pub_data_stream_privilege_expire as 600(seconds).
163
+ # @return The RTC Token
164
+ def self.build_token_with_user_account_and_privilege(app_id, app_certificate, channel_name, account, token_expire,
165
+ join_channel_privilege_expire, pub_audio_privilege_expire,
166
+ pub_video_privilege_expire, pub_data_stream_privilege_expire)
167
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, token_expire)
168
+ service_rtc = AgoraDynamicKey2::ServiceRtc.new(channel_name, account)
169
+
170
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_JOIN_CHANNEL, join_channel_privilege_expire)
171
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_PUBLISH_AUDIO_STREAM, pub_audio_privilege_expire)
172
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_PUBLISH_VIDEO_STREAM, pub_video_privilege_expire)
173
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_PUBLISH_DATA_STREAM, pub_data_stream_privilege_expire)
174
+ access_token.add_service(service_rtc)
175
+ access_token.build
176
+ end
177
+
178
+ # Build the RTC and RTM token with account.
179
+ #
180
+ # app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing
181
+ # from your kit. See Get an App ID.
182
+ # app_certificate: Certificate of the application that you registered in the Agora Dashboard.
183
+ # See Get an App Certificate.
184
+ # channel_name: Unique channel name for the AgoraRTC session in the string format.
185
+ # uid: User ID. A 32-bit unsigned integer with a value ranging from 1 to (2^32-1).
186
+ # uid must be unique.
187
+ # role: ROLE_PUBLISHER: A broadcaster/host in a live-broadcast profile.
188
+ # ROLE_SUBSCRIBER: An audience(default) in a live-broadcast profile.
189
+ # token_expire: represented by the number of seconds elapsed since now. If, for example,
190
+ # you want to access the Agora Service within 10 minutes after the token is generated,
191
+ # set token_expire as 600(seconds).
192
+ # privilege_expire: represented by the number of seconds elapsed since now. If, for example,
193
+ # you want to enable your privilege for 10 minutes, set privilege_expire as 600(seconds).
194
+ # return: The RTC and RTM token.
195
+ def self.build_token_with_rtm(app_id, app_certificate, channel_name, account, role, token_expire, privilege_expire = 0)
196
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, token_expire)
197
+ service_rtc = AgoraDynamicKey2::ServiceRtc.new(channel_name, account)
198
+
199
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_JOIN_CHANNEL, privilege_expire)
200
+ if role == ROLE_PUBLISHER
201
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_PUBLISH_AUDIO_STREAM, privilege_expire)
202
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_PUBLISH_VIDEO_STREAM, privilege_expire)
203
+ service_rtc.add_privilege(AgoraDynamicKey2::ServiceRtc::PRIVILEGE_PUBLISH_DATA_STREAM, privilege_expire)
204
+ end
205
+ access_token.add_service(service_rtc)
206
+
207
+ service_rtm = AgoraDynamicKey2::ServiceRtm.new(account)
208
+
209
+ service_rtm.add_privilege(AgoraDynamicKey2::ServiceRtm::PRIVILEGE_JOIN_LOGIN, token_expire)
210
+ access_token.add_service(service_rtm)
211
+
212
+ access_token.build
213
+ end
214
+ end
215
+ end
@@ -0,0 +1,23 @@
1
+ module AgoraDynamicKey2
2
+ class RtmTokenBuilder
3
+ # Build the RTM token.
4
+ #
5
+ # @param app_id: The App ID issued to you by Agora. Apply for a new App ID from
6
+ # Agora Dashboard if it is missing from your kit. See Get an App ID.
7
+ # @param app_certificate: Certificate of the application that you registered in
8
+ # the Agora Dashboard. See Get an App Certificate.
9
+ # @param user_id: The user's account, max length is 64 Bytes.
10
+ # @param expire: represented by the number of seconds elapsed since now. If, for example, you want to access the
11
+ # Agora Service within 10 minutes after the token is generated, set expire as 600(seconds).
12
+ # @return The RTM token.
13
+ def self.build_token(app_id, app_certificate, user_id, expire)
14
+ access_token = AgoraDynamicKey2::AccessToken.new(app_id, app_certificate, expire)
15
+ service_rtm = AgoraDynamicKey2::ServiceRtm.new(user_id)
16
+
17
+ service_rtm.add_privilege(AgoraDynamicKey2::ServiceRtm::PRIVILEGE_JOIN_LOGIN, expire)
18
+ access_token.add_service(service_rtm)
19
+ access_token.build
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,61 @@
1
+ require 'base64'
2
+
3
+ module AgoraDynamicKey2
4
+ class Util
5
+ def self.pack_int16(int)
6
+ [int].pack('s')
7
+ end
8
+
9
+ def self.unpack_int16(data)
10
+ [data[0..2].unpack1('s'), data[2..-1]]
11
+ end
12
+
13
+ def self.pack_uint16(int)
14
+ [int].pack('v')
15
+ end
16
+
17
+ def self.unpack_uint16(data)
18
+ [data[0..2].unpack1('v'), data[2..-1]]
19
+ end
20
+
21
+ def self.pack_uint32(int)
22
+ [int].pack('V')
23
+ end
24
+
25
+ def self.unpack_uint32(data)
26
+ [data[0..4].unpack1('V'), data[4..-1]]
27
+ end
28
+
29
+ def self.pack_string(str)
30
+ pack_uint16(str.bytesize) + str
31
+ end
32
+
33
+ def self.unpack_string(data)
34
+ len, data = unpack_uint16(data)
35
+ if len.zero?
36
+ return ['', data[len..-1]]
37
+ end
38
+ [data[0..len - 1], data[len..-1]]
39
+ end
40
+
41
+ def self.pack_map_uint32(map)
42
+ kv = ''
43
+ Hash[map.sort].each do |k, v|
44
+ kv += pack_uint16(k) + pack_uint32(v)
45
+ end
46
+ (pack_uint16(map.size) + kv).force_encoding('utf-8')
47
+ end
48
+
49
+ def self.unpack_map_uint32(data)
50
+ len, data = unpack_uint16(data)
51
+ map = {}
52
+ (1..len).each do
53
+ k, data = unpack_uint16(data)
54
+ v, data = unpack_uint32(data)
55
+ map[k] = v
56
+ end
57
+ [map, data]
58
+ end
59
+ end
60
+ end
61
+
@@ -0,0 +1,14 @@
1
+ # code taken from https://github.com/AgoraIO/Tools
2
+
3
+ require_relative 'dynamic_key2/access_token'
4
+ require_relative 'dynamic_key2/apaas_token_builder'
5
+ require_relative 'dynamic_key2/chat_token_builder'
6
+ require_relative 'dynamic_key2/education_token_builder'
7
+ require_relative 'dynamic_key2/fpa_token_builder'
8
+ require_relative 'dynamic_key2/rtc_token_builder'
9
+ require_relative 'dynamic_key2/rtm_token_builder'
10
+ require_relative 'dynamic_key2/util'
11
+
12
+ module AgoraDynamicKey2
13
+ VERSION = '0.2.0'.freeze
14
+ end
@@ -0,0 +1,13 @@
1
+ require 'rails/generators/base'
2
+
3
+ module AgoraRails
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ def create_initializer_file
9
+ template "agora_rails.rb", "config/initializers/agora_rails.rb"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ AgoraRails.configure do |config|
2
+ config.app_id = "YOUR_APP_ID"
3
+ config.app_certificate = "YOUR_APP_CERTIFICATE"
4
+ config.customer_key = "YOUR_CUSTOMER_KEY"
5
+ config.customer_secret = "YOUR_CUSTOMER_SECRET"
6
+
7
+ # the following are optional
8
+ config.bucket = "YOUR_BUCKET"
9
+ config.access_key = "YOUR_ACCESS_KEY"
10
+ config.secret_key = "YOUR_SECRET_KEY"
11
+ config.file_prefix = "YOUR_FILE_PREFIX"
12
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: agora_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Mohammad Forouzani
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-11-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httparty
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: openssl
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Provides functionality for Agora.io token generation and cloud recording
84
+ email:
85
+ - mo@usechance.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - README.md
91
+ - lib/agora_rails.rb
92
+ - lib/agora_rails/cloud_recording.rb
93
+ - lib/agora_rails/configuration.rb
94
+ - lib/agora_rails/stt.rb
95
+ - lib/dynamic_key2.rb
96
+ - lib/dynamic_key2/access_token.rb
97
+ - lib/dynamic_key2/apaas_token_builder.rb
98
+ - lib/dynamic_key2/chat_token_builder.rb
99
+ - lib/dynamic_key2/education_token_builder.rb
100
+ - lib/dynamic_key2/fpa_token_builder.rb
101
+ - lib/dynamic_key2/rtc_token_builder.rb
102
+ - lib/dynamic_key2/rtm_token_builder.rb
103
+ - lib/dynamic_key2/util.rb
104
+ - lib/generators/agora_rails/install_generator.rb
105
+ - lib/generators/agora_rails/templates/agora_rails.rb
106
+ homepage: https://github.com/mamady/agora_rails
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubygems_version: 3.5.3
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: Ruby interface for Agora.io APIs
129
+ test_files: []