tiktok-open-sdk 0.4.0 → 0.5.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 +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +3 -1
- data/README.md +56 -1
- data/lib/tiktok/open/sdk/config.rb +5 -0
- data/lib/tiktok/open/sdk/helpers/validators/post_info_validator.rb +178 -0
- data/lib/tiktok/open/sdk/helpers/validators/post_publish_validator.rb +57 -0
- data/lib/tiktok/open/sdk/helpers/validators/source_info_validator.rb +186 -0
- data/lib/tiktok/open/sdk/http_client.rb +4 -3
- data/lib/tiktok/open/sdk/open_api/post/publish.rb +15 -0
- data/lib/tiktok/open/sdk/version.rb +1 -1
- data/lib/tiktok/open/sdk.rb +26 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ea350ded46bc468a3b86a72f539c12a36ecc960b1e2476ac7e59c2c52424d8f1
|
|
4
|
+
data.tar.gz: 07fa578800d4d03d9431c39b043008d2185ed62ed2f93c8c20feea8bb331736d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61e3742ea46ddeb02a8a168d3485c7ecc7632698c6c533364e392b67058f6a5d7e325e0e546eebe9eee915070e309981dc8707aca7ff67097dfadd74610977d0
|
|
7
|
+
data.tar.gz: f19aa49f93036f0b02f0d5613d76b7bd86e7a00457a3642569c3f266ac895720a4106e7df27fec6f215581ccfd6fcedb71ac68638c83fdddcfc0dca8b56d5052
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,9 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
-
## [
|
|
7
|
+
## [0.5.0] - 2026-02-14
|
|
8
|
+
### Added
|
|
9
|
+
- **Post API: video_init** - Initialize a video publish to obtain an upload URL (file upload) or to start a pull-from-URL flow. Accepts `access_token` and `params` (post_info, source_info). Optional config: `video_init_url`.
|
|
8
10
|
|
|
9
11
|
## [0.4.0] - 2025-10-06
|
|
10
12
|
### Added
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TikTok Open SDK
|
|
2
2
|
|
|
3
|
-
[](https://rubygems.org/gems/tiktok-open-sdk)
|
|
4
4
|
[](https://www.ruby-lang.org/en/downloads/)
|
|
5
5
|
[](LICENSE.txt)
|
|
6
6
|
[](https://github.com/pochkuntaras/tiktok-open-sdk/actions/workflows/main.yml)
|
|
@@ -59,6 +59,7 @@ Tiktok::Open::Sdk.configure do |config|
|
|
|
59
59
|
config.user_auth.revoke_token_url = 'https://open.tiktokapis.com/v2/oauth/revoke/'
|
|
60
60
|
config.user_info_url = 'https://open.tiktokapis.com/v2/user/info/'
|
|
61
61
|
config.creator_info_query_url = 'https://open.tiktokapis.com/v2/post/publish/creator_info/query/'
|
|
62
|
+
config.video_init_url = 'https://open.tiktokapis.com/v2/post/publish/video/init/'
|
|
62
63
|
|
|
63
64
|
# Optional: Enable OmniAuth strategy auto-loading
|
|
64
65
|
config.load_omniauth = true
|
|
@@ -188,6 +189,40 @@ else
|
|
|
188
189
|
end
|
|
189
190
|
```
|
|
190
191
|
|
|
192
|
+
#### Video Init
|
|
193
|
+
|
|
194
|
+
Initialize a video publish to obtain an upload URL (for file upload) or to start a pull-from-URL flow:
|
|
195
|
+
|
|
196
|
+
```ruby
|
|
197
|
+
params = {
|
|
198
|
+
post_info: {
|
|
199
|
+
title: 'My video #tiktok',
|
|
200
|
+
privacy_level: 'SELF_ONLY',
|
|
201
|
+
disable_duet: false,
|
|
202
|
+
disable_comment: false,
|
|
203
|
+
disable_stitch: false,
|
|
204
|
+
video_cover_timestamp_ms: 1000
|
|
205
|
+
},
|
|
206
|
+
source_info: {
|
|
207
|
+
source: 'FILE_UPLOAD',
|
|
208
|
+
video_type: 'video/mp4',
|
|
209
|
+
video_size: 7_340_032,
|
|
210
|
+
chunk_size: 7_340_032,
|
|
211
|
+
total_chunk_count: 1
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
response = Tiktok::Open::Sdk.post.video_init(access_token: access_token, params: params)
|
|
216
|
+
|
|
217
|
+
if response[:success]
|
|
218
|
+
publish_id = response[:response][:data][:publish_id]
|
|
219
|
+
upload_url = response[:response][:data][:upload_url]
|
|
220
|
+
# Use upload_url to upload video chunks (FILE_UPLOAD) or proceed with PULL_FROM_URL flow
|
|
221
|
+
else
|
|
222
|
+
puts "Error: #{response[:response][:error][:message]}"
|
|
223
|
+
end
|
|
224
|
+
```
|
|
225
|
+
|
|
191
226
|
### Using the User API
|
|
192
227
|
|
|
193
228
|
The SDK provides a convenient way to access user information:
|
|
@@ -428,6 +463,8 @@ Tiktok::Open::Sdk.configure do |config|
|
|
|
428
463
|
config.user_auth.scopes = %w[user.info.basic] # Optional
|
|
429
464
|
config.user_auth.redirect_uri = 'https://...' # Optional
|
|
430
465
|
config.user_info_url = 'https://open.tiktokapis.com/v2/user/info/' # Optional
|
|
466
|
+
config.creator_info_query_url = 'https://open.tiktokapis.com/v2/post/publish/creator_info/query/' # Optional
|
|
467
|
+
config.video_init_url = 'https://open.tiktokapis.com/v2/post/publish/video/init/' # Optional
|
|
431
468
|
end
|
|
432
469
|
```
|
|
433
470
|
|
|
@@ -543,6 +580,24 @@ Queries creator information from the TikTok Open API for video publishing.
|
|
|
543
580
|
- `max_video_post_duration_sec` - Maximum video duration in seconds
|
|
544
581
|
- `privacy_level_options` - Available privacy level options
|
|
545
582
|
|
|
583
|
+
#### `video_init(access_token:, params: {})`
|
|
584
|
+
|
|
585
|
+
Initializes a video publish and returns a publish ID and upload URL (for file upload) or starts a pull-from-URL flow.
|
|
586
|
+
|
|
587
|
+
**Parameters:**
|
|
588
|
+
- `access_token` (String, required) - OAuth2 access token for authentication
|
|
589
|
+
- `params` (Hash, required) - Request body with `post_info` and `source_info`
|
|
590
|
+
- `post_info` - Post metadata (title, privacy_level, disable_duet, disable_comment, disable_stitch, video_cover_timestamp_ms, etc.)
|
|
591
|
+
- `source_info` - Video source (e.g. `source: 'FILE_UPLOAD'` with video_size, chunk_size, total_chunk_count, video_type; or `source: 'PULL_FROM_URL'` with video_url)
|
|
592
|
+
|
|
593
|
+
**Returns:** Hash with `:success`, `:code`, and `:response` keys
|
|
594
|
+
|
|
595
|
+
**Response Data (on success):**
|
|
596
|
+
- `data.publish_id` - Publish session ID
|
|
597
|
+
- `data.upload_url` - URL for uploading video chunks (when using FILE_UPLOAD)
|
|
598
|
+
|
|
599
|
+
**Raises:** `Tiktok::Open::Sdk::RequestValidationError` if access token is invalid or params fail validation
|
|
600
|
+
|
|
546
601
|
### HTTP Client
|
|
547
602
|
|
|
548
603
|
#### `request(method, url, params: {}, headers: {}, body: nil)`
|
|
@@ -33,6 +33,10 @@ module Tiktok
|
|
|
33
33
|
# @return [String] TikTok Query Creator Info endpoint URL.
|
|
34
34
|
attr_accessor :creator_info_query_url
|
|
35
35
|
|
|
36
|
+
# @!attribute [rw] video_init_url
|
|
37
|
+
# @return [String] TikTok Video Init endpoint URL.
|
|
38
|
+
attr_accessor :video_init_url
|
|
39
|
+
|
|
36
40
|
# @!attribute [rw] user_auth
|
|
37
41
|
# @return [UserAuth] User authentication configuration.
|
|
38
42
|
attr_accessor :user_auth
|
|
@@ -45,6 +49,7 @@ module Tiktok
|
|
|
45
49
|
def initialize
|
|
46
50
|
@user_info_url = "#{OPEN_API_BASE_URL}/v2/user/info/"
|
|
47
51
|
@creator_info_query_url = "#{OPEN_API_BASE_URL}/v2/post/publish/creator_info/query/"
|
|
52
|
+
@video_init_url = "#{OPEN_API_BASE_URL}/v2/post/publish/video/init/"
|
|
48
53
|
@user_auth = UserAuth.new
|
|
49
54
|
@load_omniauth = false
|
|
50
55
|
end
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tiktok
|
|
4
|
+
module Open
|
|
5
|
+
module Sdk
|
|
6
|
+
module Helpers
|
|
7
|
+
module Validators
|
|
8
|
+
# Validates post information for TikTok video publishing.
|
|
9
|
+
#
|
|
10
|
+
# This module provides validation methods for post-related parameters including
|
|
11
|
+
# privacy level, title, boolean flags, and video cover timestamp.
|
|
12
|
+
#
|
|
13
|
+
# @example Including the validator in a class
|
|
14
|
+
# class VideoPublisher
|
|
15
|
+
# include Tiktok::Open::Sdk::Helpers::Validators::PostInfoValidator
|
|
16
|
+
#
|
|
17
|
+
# def publish(post_info)
|
|
18
|
+
# validate_post_info!(post_info)
|
|
19
|
+
# # proceed with publishing
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# @example Validating post information
|
|
24
|
+
# post_info = {
|
|
25
|
+
# privacy_level: 'PUBLIC_TO_EVERYONE',
|
|
26
|
+
# title: 'My awesome video',
|
|
27
|
+
# disable_duet: false,
|
|
28
|
+
# brand_content_toggle: true
|
|
29
|
+
# }
|
|
30
|
+
# validate_post_info!(post_info)
|
|
31
|
+
module PostInfoValidator
|
|
32
|
+
# Valid privacy level options for TikTok videos
|
|
33
|
+
PRIVACY_LEVEL_OPTIONS = %w[
|
|
34
|
+
PUBLIC_TO_EVERYONE
|
|
35
|
+
MUTUAL_FOLLOW_FRIENDS
|
|
36
|
+
FOLLOWER_OF_CREATOR
|
|
37
|
+
SELF_ONLY
|
|
38
|
+
].freeze
|
|
39
|
+
|
|
40
|
+
# Maximum allowed length for video title
|
|
41
|
+
MAX_TITLE_LENGTH = 2200
|
|
42
|
+
|
|
43
|
+
# Validates post information and raises an error if invalid.
|
|
44
|
+
#
|
|
45
|
+
# @param post_info [Hash, nil] The post information to validate
|
|
46
|
+
# @option post_info [String] :privacy_level Required. Must be one of PRIVACY_LEVEL_OPTIONS
|
|
47
|
+
# @option post_info [String] :title Optional. Maximum 2200 characters
|
|
48
|
+
# @option post_info [Boolean] :disable_duet Optional. Boolean flag
|
|
49
|
+
# @option post_info [Boolean] :disable_stitch Optional. Boolean flag
|
|
50
|
+
# @option post_info [Boolean] :disable_comment Optional. Boolean flag
|
|
51
|
+
# @option post_info [Boolean] :brand_content_toggle Optional. Boolean flag
|
|
52
|
+
# @option post_info [Boolean] :brand_organic_toggle Optional. Boolean flag
|
|
53
|
+
# @option post_info [Boolean] :is_aigc Optional. Boolean flag
|
|
54
|
+
# @option post_info [Integer] :video_cover_timestamp_ms Optional. Non-negative integer
|
|
55
|
+
#
|
|
56
|
+
# @return [void]
|
|
57
|
+
# @raise [Tiktok::Open::Sdk::RequestValidationError] If validation fails
|
|
58
|
+
#
|
|
59
|
+
# @example Valid post information
|
|
60
|
+
# validate_post_info!(privacy_level: 'PUBLIC_TO_EVERYONE')
|
|
61
|
+
#
|
|
62
|
+
# @example Invalid privacy level
|
|
63
|
+
# validate_post_info!(privacy_level: 'INVALID')
|
|
64
|
+
# # => raises RequestValidationError with privacy_level error
|
|
65
|
+
def validate_post_info!(post_info)
|
|
66
|
+
errors = {}
|
|
67
|
+
|
|
68
|
+
validate_post_info(post_info, errors)
|
|
69
|
+
|
|
70
|
+
raise_validation_errors!(errors)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
# Raises validation errors if any exist.
|
|
76
|
+
#
|
|
77
|
+
# @param errors [Hash] The accumulated validation errors
|
|
78
|
+
# @return [void]
|
|
79
|
+
# @raise [Tiktok::Open::Sdk::RequestValidationError] If errors is not empty
|
|
80
|
+
def raise_validation_errors!(errors)
|
|
81
|
+
raise ::Tiktok::Open::Sdk::RequestValidationError, errors unless errors.empty?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Validates post information and accumulates errors.
|
|
85
|
+
#
|
|
86
|
+
# @param post_info [Hash, nil] The post information to validate
|
|
87
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
88
|
+
# @return [void]
|
|
89
|
+
def validate_post_info(post_info, errors)
|
|
90
|
+
return if post_info.nil?
|
|
91
|
+
return add_error errors, :post_info, 'must be a Hash' unless post_info.is_a?(Hash)
|
|
92
|
+
|
|
93
|
+
privacy_level = post_info[:privacy_level]
|
|
94
|
+
title = post_info[:title]
|
|
95
|
+
timestamp = post_info[:video_cover_timestamp_ms]
|
|
96
|
+
|
|
97
|
+
validate_privacy_level! privacy_level, errors
|
|
98
|
+
validate_title! title, errors
|
|
99
|
+
validate_boolean_fields! post_info, errors
|
|
100
|
+
validate_video_cover_timestamp! timestamp, errors
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Validates that privacy level is one of the allowed options.
|
|
104
|
+
#
|
|
105
|
+
# @param privacy_level [String, nil] The privacy level to validate
|
|
106
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
107
|
+
# @return [void]
|
|
108
|
+
def validate_privacy_level!(privacy_level, errors)
|
|
109
|
+
return if PRIVACY_LEVEL_OPTIONS.include?(privacy_level)
|
|
110
|
+
|
|
111
|
+
add_error errors, :privacy_level, "must be one of: #{PRIVACY_LEVEL_OPTIONS.join(", ")}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Validates video title length and type.
|
|
115
|
+
#
|
|
116
|
+
# @param title [String, nil] The title to validate
|
|
117
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
118
|
+
# @return [void]
|
|
119
|
+
def validate_title!(title, errors)
|
|
120
|
+
return if title.nil?
|
|
121
|
+
return add_error errors, :title, 'must be a String' unless title.is_a?(String)
|
|
122
|
+
return unless title.length > MAX_TITLE_LENGTH
|
|
123
|
+
|
|
124
|
+
add_error errors, :title, "must be less than #{MAX_TITLE_LENGTH} characters"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Validates that boolean fields contain boolean values.
|
|
128
|
+
#
|
|
129
|
+
# @param post_info [Hash] The post information containing boolean fields
|
|
130
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
131
|
+
# @return [void]
|
|
132
|
+
def validate_boolean_fields!(post_info, errors)
|
|
133
|
+
boolean_fields = %i[
|
|
134
|
+
disable_duet
|
|
135
|
+
disable_stitch
|
|
136
|
+
disable_comment
|
|
137
|
+
brand_content_toggle
|
|
138
|
+
brand_organic_toggle
|
|
139
|
+
is_aigc
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
boolean_fields.each do |field|
|
|
143
|
+
next unless post_info.key?(field)
|
|
144
|
+
|
|
145
|
+
value = post_info[field]
|
|
146
|
+
next if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
|
147
|
+
|
|
148
|
+
add_error errors, field, 'must be a boolean (true or false)'
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Validates video cover timestamp is a non-negative integer.
|
|
153
|
+
#
|
|
154
|
+
# @param timestamp [Integer, nil] The timestamp to validate
|
|
155
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
156
|
+
# @return [void]
|
|
157
|
+
def validate_video_cover_timestamp!(timestamp, errors)
|
|
158
|
+
return if timestamp.nil? || (timestamp.is_a?(Integer) && timestamp >= 0)
|
|
159
|
+
|
|
160
|
+
add_error errors, :video_cover_timestamp_ms, 'must be a non-negative integer'
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Adds an error message to the errors hash.
|
|
164
|
+
#
|
|
165
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
166
|
+
# @param field_name [Symbol] The field name that has an error
|
|
167
|
+
# @param message [String] The error message
|
|
168
|
+
# @return [Hash] The errors hash
|
|
169
|
+
def add_error(errors, field_name, message)
|
|
170
|
+
errors[field_name] ||= [] << message
|
|
171
|
+
errors
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'post_info_validator'
|
|
4
|
+
require_relative 'source_info_validator'
|
|
5
|
+
|
|
6
|
+
module Tiktok
|
|
7
|
+
module Open
|
|
8
|
+
module Sdk
|
|
9
|
+
module Helpers
|
|
10
|
+
module Validators
|
|
11
|
+
# Provides validation for video publishing initialization parameters.
|
|
12
|
+
#
|
|
13
|
+
# This module combines and applies the `PostInfoValidator` and `SourceInfoValidator` logic
|
|
14
|
+
# for validating `post_info` and `source_info` input hashes typically required for
|
|
15
|
+
# TikTok Open SDK video publishing workflows.
|
|
16
|
+
#
|
|
17
|
+
# @example Including and using PostPublishValidator
|
|
18
|
+
# class Publisher
|
|
19
|
+
# include Tiktok::Open::Sdk::Helpers::Validators::PostPublishValidator
|
|
20
|
+
#
|
|
21
|
+
# def publish_video(params)
|
|
22
|
+
# validate_video_init_info!(params)
|
|
23
|
+
# # ...proceed if valid
|
|
24
|
+
# end
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
# @see PostInfoValidator#validate_post_info
|
|
28
|
+
# @see SourceInfoValidator#validate_source_info
|
|
29
|
+
module PostPublishValidator
|
|
30
|
+
include PostInfoValidator
|
|
31
|
+
include SourceInfoValidator
|
|
32
|
+
|
|
33
|
+
# Validates combined video initialization parameters.
|
|
34
|
+
#
|
|
35
|
+
# Both `post_info` and `source_info` sub-hashes are validated using the appropriate
|
|
36
|
+
# validators. If any errors occur, a RequestValidationError (or similar) is raised.
|
|
37
|
+
#
|
|
38
|
+
# @param params [Hash] The full parameter hash.
|
|
39
|
+
# @option params [Hash] :post_info Info for video post, validated by PostInfoValidator
|
|
40
|
+
# @option params [Hash] :source_info Info on video source, validated by SourceInfoValidator
|
|
41
|
+
#
|
|
42
|
+
# @raise [RequestValidationError] Raised if any validation errors found in either section.
|
|
43
|
+
# @return [void]
|
|
44
|
+
def validate_video_init_info!(params)
|
|
45
|
+
errors = { post_info: {}, source_info: {} }
|
|
46
|
+
|
|
47
|
+
validate_post_info params[:post_info], errors[:post_info]
|
|
48
|
+
validate_source_info params[:source_info], errors[:source_info]
|
|
49
|
+
|
|
50
|
+
raise_validation_errors!(errors) unless errors.values.all?(&:empty?)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tiktok
|
|
4
|
+
module Open
|
|
5
|
+
module Sdk
|
|
6
|
+
module Helpers
|
|
7
|
+
module Validators
|
|
8
|
+
# Validates source information for TikTok video publishing.
|
|
9
|
+
#
|
|
10
|
+
# This module provides validation methods for video source parameters including
|
|
11
|
+
# source type (PULL_FROM_URL or FILE_UPLOAD) and their respective required fields.
|
|
12
|
+
#
|
|
13
|
+
# @example Including the validator in a class
|
|
14
|
+
# class VideoPublisher
|
|
15
|
+
# include Tiktok::Open::Sdk::Helpers::Validators::SourceInfoValidator
|
|
16
|
+
#
|
|
17
|
+
# def publish(source_info)
|
|
18
|
+
# validate_source_info!(source_info)
|
|
19
|
+
# # proceed with publishing
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# @example Validating PULL_FROM_URL source
|
|
24
|
+
# source_info = {
|
|
25
|
+
# source: 'PULL_FROM_URL',
|
|
26
|
+
# video_url: 'https://example.com/video.mp4'
|
|
27
|
+
# }
|
|
28
|
+
# validate_source_info!(source_info)
|
|
29
|
+
#
|
|
30
|
+
# @example Validating FILE_UPLOAD source
|
|
31
|
+
# source_info = {
|
|
32
|
+
# source: 'FILE_UPLOAD',
|
|
33
|
+
# video_size: 10_485_760,
|
|
34
|
+
# chunk_size: 1_048_576,
|
|
35
|
+
# total_chunk_count: 10
|
|
36
|
+
# }
|
|
37
|
+
# validate_source_info!(source_info)
|
|
38
|
+
module SourceInfoValidator
|
|
39
|
+
# Valid source options for video uploads
|
|
40
|
+
SOURCE_OPTIONS = %w[
|
|
41
|
+
PULL_FROM_URL
|
|
42
|
+
FILE_UPLOAD
|
|
43
|
+
].freeze
|
|
44
|
+
|
|
45
|
+
# Validates source information and raises an error if invalid.
|
|
46
|
+
#
|
|
47
|
+
# @param source_info [Hash, nil] The source information to validate
|
|
48
|
+
# @option source_info [String] :source Required. Must be 'PULL_FROM_URL' or 'FILE_UPLOAD'
|
|
49
|
+
# @option source_info [String] :video_url Required for PULL_FROM_URL. Non-empty video URL
|
|
50
|
+
# @option source_info [Integer] :video_size Required for FILE_UPLOAD. Positive integer
|
|
51
|
+
# @option source_info [Integer] :chunk_size Optional for FILE_UPLOAD. Positive integer
|
|
52
|
+
# @option source_info [Integer] :total_chunk_count Optional for FILE_UPLOAD. Positive integer
|
|
53
|
+
#
|
|
54
|
+
# @return [void]
|
|
55
|
+
# @raise [Tiktok::Open::Sdk::RequestValidationError] If validation fails
|
|
56
|
+
#
|
|
57
|
+
# @example Valid PULL_FROM_URL source
|
|
58
|
+
# validate_source_info!(source: 'PULL_FROM_URL', video_url: 'https://example.com/video.mp4')
|
|
59
|
+
#
|
|
60
|
+
# @example Valid FILE_UPLOAD source
|
|
61
|
+
# validate_source_info!(source: 'FILE_UPLOAD', video_size: 10_485_760)
|
|
62
|
+
#
|
|
63
|
+
# @example Invalid source type
|
|
64
|
+
# validate_source_info!(source: 'INVALID')
|
|
65
|
+
# # => raises RequestValidationError with source error
|
|
66
|
+
def validate_source_info!(source_info)
|
|
67
|
+
errors = {}
|
|
68
|
+
|
|
69
|
+
validate_source_info(source_info, errors)
|
|
70
|
+
|
|
71
|
+
raise_validation_errors!(errors)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
# Raises validation errors if any exist.
|
|
77
|
+
#
|
|
78
|
+
# @param errors [Hash] The accumulated validation errors
|
|
79
|
+
# @return [void]
|
|
80
|
+
# @raise [Tiktok::Open::Sdk::RequestValidationError] If errors is not empty
|
|
81
|
+
def raise_validation_errors!(errors)
|
|
82
|
+
raise ::Tiktok::Open::Sdk::RequestValidationError, errors unless errors.empty?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Validates source information and accumulates errors.
|
|
86
|
+
#
|
|
87
|
+
# @param source_info [Hash, nil] The source information to validate
|
|
88
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
89
|
+
# @return [void]
|
|
90
|
+
def validate_source_info(source_info, errors)
|
|
91
|
+
if source_info.is_a?(Hash)
|
|
92
|
+
validate_source_specific_fields!(source_info, errors)
|
|
93
|
+
else
|
|
94
|
+
add_error errors, :source_info, 'must be a Hash'
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Validates source-specific required fields based on source type.
|
|
99
|
+
#
|
|
100
|
+
# @param source_info [Hash] The source information containing type-specific fields
|
|
101
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
102
|
+
# @return [void]
|
|
103
|
+
def validate_source_specific_fields!(source_info, errors)
|
|
104
|
+
case source_info[:source]
|
|
105
|
+
when 'PULL_FROM_URL'
|
|
106
|
+
validate_pull_from_url_fields!(source_info, errors)
|
|
107
|
+
when 'FILE_UPLOAD'
|
|
108
|
+
validate_file_upload_fields!(source_info, errors)
|
|
109
|
+
else
|
|
110
|
+
add_error errors, :source, "must be one of: #{SOURCE_OPTIONS.join(", ")}"
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Validates required fields for PULL_FROM_URL source type.
|
|
115
|
+
#
|
|
116
|
+
# @param source_info [Hash] The source information
|
|
117
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
118
|
+
# @return [void]
|
|
119
|
+
def validate_pull_from_url_fields!(source_info, errors)
|
|
120
|
+
video_url = source_info[:video_url]
|
|
121
|
+
|
|
122
|
+
return if video_url.is_a?(String) && !video_url.empty?
|
|
123
|
+
|
|
124
|
+
add_error errors, :video_url, 'is required and must be a non-empty string for PULL_FROM_URL'
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Validates required fields for FILE_UPLOAD source type.
|
|
128
|
+
#
|
|
129
|
+
# @param source_info [Hash] The source information
|
|
130
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
131
|
+
# @return [void]
|
|
132
|
+
def validate_file_upload_fields!(source_info, errors)
|
|
133
|
+
validate_video_size! source_info[:video_size], errors
|
|
134
|
+
validate_chunk_size! source_info[:chunk_size], errors
|
|
135
|
+
validate_total_chunk_count! source_info[:total_chunk_count], errors
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Validates video size for FILE_UPLOAD source.
|
|
139
|
+
#
|
|
140
|
+
# @param video_size [Integer, nil] The video size in bytes
|
|
141
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
142
|
+
# @return [void]
|
|
143
|
+
def validate_video_size!(video_size, errors)
|
|
144
|
+
return if video_size.is_a?(Integer) && video_size.positive?
|
|
145
|
+
|
|
146
|
+
add_error errors, :video_size, 'is required and must be a positive integer for FILE_UPLOAD'
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Validates chunk size for FILE_UPLOAD source.
|
|
150
|
+
#
|
|
151
|
+
# @param value [Integer, nil] The chunk size in bytes
|
|
152
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
153
|
+
# @return [void]
|
|
154
|
+
def validate_chunk_size!(value, errors)
|
|
155
|
+
return if value.nil? || (value.is_a?(Integer) && value.positive?)
|
|
156
|
+
|
|
157
|
+
add_error errors, :chunk_size, 'must be a positive integer if provided'
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Validates total chunk count for FILE_UPLOAD source.
|
|
161
|
+
#
|
|
162
|
+
# @param value [Integer, nil] The total number of chunks
|
|
163
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
164
|
+
# @return [void]
|
|
165
|
+
def validate_total_chunk_count!(value, errors)
|
|
166
|
+
return if value.nil? || (value.is_a?(Integer) && value.positive?)
|
|
167
|
+
|
|
168
|
+
add_error errors, :total_chunk_count, 'must be a positive integer if provided'
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Adds an error message to the errors hash.
|
|
172
|
+
#
|
|
173
|
+
# @param errors [Hash] The hash to accumulate errors into
|
|
174
|
+
# @param field_name [Symbol] The field name that has an error
|
|
175
|
+
# @param message [String] The error message
|
|
176
|
+
# @return [Hash] The errors hash
|
|
177
|
+
def add_error(errors, field_name, message)
|
|
178
|
+
errors[field_name] ||= [] << message
|
|
179
|
+
errors
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -102,10 +102,11 @@ module Tiktok
|
|
|
102
102
|
# @param body [Hash, nil] The request body.
|
|
103
103
|
# @return [Net::HTTPRequest] The HTTP request object.
|
|
104
104
|
def build_http_request(method, uri, headers, body)
|
|
105
|
-
klass
|
|
106
|
-
request
|
|
105
|
+
klass = Net::HTTP.const_get(method.capitalize)
|
|
106
|
+
request = klass.new(uri, headers)
|
|
107
|
+
content_type = headers[:'Content-Type'] || headers['Content-Type']
|
|
107
108
|
|
|
108
|
-
body ? assign_body!(request, body,
|
|
109
|
+
body ? assign_body!(request, body, content_type) : request
|
|
109
110
|
end
|
|
110
111
|
end
|
|
111
112
|
end
|
|
@@ -12,6 +12,7 @@ module Tiktok
|
|
|
12
12
|
|
|
13
13
|
include ::Tiktok::Open::Sdk::Helpers::ResponseHelper
|
|
14
14
|
include ::Tiktok::Open::Sdk::Helpers::Validators::TokenValidator
|
|
15
|
+
include ::Tiktok::Open::Sdk::Helpers::Validators::PostPublishValidator
|
|
15
16
|
|
|
16
17
|
# Queries creator information from the TikTok Open API.
|
|
17
18
|
#
|
|
@@ -31,6 +32,20 @@ module Tiktok
|
|
|
31
32
|
}
|
|
32
33
|
)
|
|
33
34
|
end
|
|
35
|
+
|
|
36
|
+
def video_init(access_token:, params: {})
|
|
37
|
+
validate_token!(access_token)
|
|
38
|
+
validate_video_init_info!(params)
|
|
39
|
+
|
|
40
|
+
render_response Tiktok::Open::Sdk::HttpClient.post(
|
|
41
|
+
Tiktok::Open::Sdk.config.video_init_url,
|
|
42
|
+
headers: {
|
|
43
|
+
Authorization: "Bearer #{access_token}",
|
|
44
|
+
'Content-Type': 'application/json; charset=UTF-8'
|
|
45
|
+
},
|
|
46
|
+
body: params
|
|
47
|
+
)
|
|
48
|
+
end
|
|
34
49
|
end
|
|
35
50
|
end
|
|
36
51
|
end
|
data/lib/tiktok/open/sdk.rb
CHANGED
|
@@ -4,6 +4,7 @@ require_relative 'sdk/helpers/string_utils_helper'
|
|
|
4
4
|
require_relative 'sdk/helpers/response_helper'
|
|
5
5
|
require_relative 'sdk/helpers/auth_helper'
|
|
6
6
|
require_relative 'sdk/helpers/validators/token_validator'
|
|
7
|
+
require_relative 'sdk/helpers/validators/post_publish_validator'
|
|
7
8
|
require_relative 'sdk/open_api/auth/user'
|
|
8
9
|
require_relative 'sdk/open_api/auth/client'
|
|
9
10
|
require_relative 'sdk/open_api/post/publish'
|
|
@@ -22,7 +23,31 @@ module Tiktok
|
|
|
22
23
|
# raise Tiktok::Open::Sdk::Error, "Something went wrong"
|
|
23
24
|
class Error < StandardError; end
|
|
24
25
|
|
|
25
|
-
class
|
|
26
|
+
# Error class for request validation failures
|
|
27
|
+
#
|
|
28
|
+
# This error is raised when request validation fails, providing access to
|
|
29
|
+
# detailed validation error information.
|
|
30
|
+
#
|
|
31
|
+
# @attr_reader messages [Hash, nil] validation errors hash or nil if no specific errors
|
|
32
|
+
#
|
|
33
|
+
# @example
|
|
34
|
+
# raise RequestValidationError.new({ field: ['error message'] })
|
|
35
|
+
# raise RequestValidationError.new('General validation error')
|
|
36
|
+
class RequestValidationError < Error
|
|
37
|
+
attr_reader :messages
|
|
38
|
+
|
|
39
|
+
def initialize(messages = nil)
|
|
40
|
+
if messages.is_a?(Hash)
|
|
41
|
+
@messages = messages
|
|
42
|
+
|
|
43
|
+
super('Validation failed')
|
|
44
|
+
else
|
|
45
|
+
@messages = nil
|
|
46
|
+
|
|
47
|
+
super
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
26
51
|
|
|
27
52
|
class << self
|
|
28
53
|
# SDK configuration object
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tiktok-open-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Taras Pochkun
|
|
@@ -32,6 +32,9 @@ files:
|
|
|
32
32
|
- lib/tiktok/open/sdk/helpers/auth_helper.rb
|
|
33
33
|
- lib/tiktok/open/sdk/helpers/response_helper.rb
|
|
34
34
|
- lib/tiktok/open/sdk/helpers/string_utils_helper.rb
|
|
35
|
+
- lib/tiktok/open/sdk/helpers/validators/post_info_validator.rb
|
|
36
|
+
- lib/tiktok/open/sdk/helpers/validators/post_publish_validator.rb
|
|
37
|
+
- lib/tiktok/open/sdk/helpers/validators/source_info_validator.rb
|
|
35
38
|
- lib/tiktok/open/sdk/helpers/validators/token_validator.rb
|
|
36
39
|
- lib/tiktok/open/sdk/http_client.rb
|
|
37
40
|
- lib/tiktok/open/sdk/open_api/auth/client.rb
|