omnisocials 0.5.0 → 0.6.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/README.md +19 -3
- data/lib/omnisocials/client.rb +3 -2
- data/lib/omnisocials/resources/approval_workflows.rb +20 -0
- data/lib/omnisocials/resources/inbox.rb +116 -23
- data/lib/omnisocials/resources/posts.rb +15 -5
- data/lib/omnisocials/version.rb +1 -1
- data/lib/omnisocials.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4b3fed727cadc18b6ea190937598241ea06e5ac3451f5a01e47e993f641f5332
|
|
4
|
+
data.tar.gz: 6adeeba6ddc69911b79c4b620ddc418e0dd372d6e76e3a417bd285ae54b44e9d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad4c11a0f91aa25cd0dfab676f0a28b5973d139a82137c0d753de697a453d710bd9f59f6c212596230fe727e37d20e117635d7b23d06f2f6aeeefce3d66b5ffa
|
|
7
|
+
data.tar.gz: 1b53388871737de150a7d71387472915b3e1bfcc7c8e245f45e5c3d87ea4ef2ee9d8047855876d33e1028c0b24272accfe663ef482e83bbdc4e60a72fe9268af
|
data/README.md
CHANGED
|
@@ -105,7 +105,7 @@ Note that `linkedin` targets a personal LinkedIn profile and `linkedin_page` tar
|
|
|
105
105
|
|
|
106
106
|
### Chained threads (X, Bluesky, Mastodon, Threads)
|
|
107
107
|
|
|
108
|
-
Pass 2 to 25 `thread_parts` to publish a chained thread instead of a single tweet (each part is at most 280 characters). Bluesky, Mastodon and Threads support the same `thread_parts` shape (Threads: 2 to 25 parts, 500 characters per part, up to 10 media per part; parts after the first publish as replies to the previous part, and the Threads caption is taken from part 1):
|
|
108
|
+
Pass 2 to 25 `thread_parts` to publish a chained thread instead of a single tweet (each part is at most 280 characters, 25,000 for X Premium/Premium+ accounts). Bluesky, Mastodon and Threads support the same `thread_parts` shape (Threads: 2 to 25 parts, 500 characters per part, up to 10 media per part; parts after the first publish as replies to the previous part, and the Threads caption is taken from part 1):
|
|
109
109
|
|
|
110
110
|
```ruby
|
|
111
111
|
post = client.posts.create(
|
|
@@ -392,13 +392,29 @@ end
|
|
|
392
392
|
client.inbox.mark_read(conversation_id)
|
|
393
393
|
client.inbox.reply(conversation_id, text: "Thanks for reaching out!")
|
|
394
394
|
|
|
395
|
-
#
|
|
395
|
+
# Hide or unhide a comment someone left on one of your posts (Facebook,
|
|
396
|
+
# Instagram, TikTok, YouTube, Threads). Delete removes it outright (Facebook,
|
|
397
|
+
# Instagram, TikTok; YouTube: hide instead), replies under it included.
|
|
396
398
|
message_id = messages["data"][0]["id"]
|
|
397
399
|
client.inbox.hide(message_id) # hide
|
|
398
400
|
client.inbox.hide(message_id, hide: false) # unhide
|
|
401
|
+
client.inbox.delete_message(message_id)
|
|
399
402
|
```
|
|
400
403
|
|
|
401
|
-
`platform` accepts `"instagram"`, `"facebook"`, `"linkedin"`, `"tiktok"`, `"youtube"`, `"x"`, or `"threads"`; `type` accepts `"dm"`, `"comment"`, or `"mention"`. Threads conversations are comments (replies people leave on your Threads posts) and mentions; there are no Threads DMs.
|
|
404
|
+
`platform` accepts `"instagram"`, `"facebook"`, `"linkedin"`, `"tiktok"`, `"youtube"`, `"x"`, or `"threads"`; `type` accepts `"dm"`, `"comment"`, or `"mention"`. Threads conversations are comments (replies people leave on your Threads posts) and mentions; there are no Threads DMs. Comments can be hidden on Facebook, Instagram, TikTok, YouTube, and Threads (Threads: incoming top-level replies only), and a hidden message keeps its place in the conversation with its `hidden` flag set; `hidden` is `true`/`false` on comments and `nil` on DMs. A comment/mention's `post` carries `url` (public link when the platform provides one) and `media_type` (the platform's own label) next to `id`, `caption`, and `thumbnail`. Threads inbox is currently rolling out; until Meta approves the permissions it is disabled on production and calls return a clear error, and it needs a Threads connection with the reply permission (a 401 `reauth_required` means reconnect Threads). TikTok and YouTube replies are comments only; TikTok replies are capped at 150 characters. Conversation ids are URL-encoded for you, so pass them exactly as returned - LinkedIn ids contain `":"` and `"()"` (e.g. `"linkedin_comment_urn:li:activity:123"`).
|
|
405
|
+
|
|
406
|
+
`next` hands out the next conversation that still needs a reply (the customer's latest DM with no reply after it, or an unreplied comment/mention that is not hidden), with the whole thread and the post it belongs to, so a reply can be drafted from one call. Replies typed in the native apps count as answers. Only unread items are served by default, so `mark_read` is the durable way to skip one; `exclude` skips conversation ids for the current session only. Pass `include_next: true` to `reply` to get the following item in the same response. `list_conversations(unanswered: true)` gives the same set as a plain list.
|
|
407
|
+
|
|
408
|
+
```ruby
|
|
409
|
+
item = client.inbox.next(platform: "instagram")
|
|
410
|
+
while item["data"]
|
|
411
|
+
message = item["data"]["message"]
|
|
412
|
+
puts "#{item["remaining"]} left. #{message["sender"]["username"]}: #{message["text"]}"
|
|
413
|
+
|
|
414
|
+
reply = client.inbox.reply(message["conversation_id"], text: "Thanks! DM sent.", include_next: true)
|
|
415
|
+
item = { "data" => reply["next"], "remaining" => reply["remaining"] || 0 }
|
|
416
|
+
end
|
|
417
|
+
```
|
|
402
418
|
|
|
403
419
|
Replying to an X DM costs 2 prepaid credits, debited from the company balance before the send and automatically refunded if the send fails:
|
|
404
420
|
|
data/lib/omnisocials/client.rb
CHANGED
|
@@ -59,8 +59,8 @@ module OmniSocials
|
|
|
59
59
|
].freeze
|
|
60
60
|
|
|
61
61
|
attr_reader :api_key, :base_url, :timeout, :max_retries,
|
|
62
|
-
:posts, :media, :folders, :hashtag_sets, :
|
|
63
|
-
:audio, :locations, :inbox, :webhooks
|
|
62
|
+
:posts, :media, :folders, :hashtag_sets, :approval_workflows,
|
|
63
|
+
:accounts, :analytics, :audio, :locations, :inbox, :webhooks
|
|
64
64
|
|
|
65
65
|
# api_key - API key (omsk_live_* / omsk_test_*). Falls back to the
|
|
66
66
|
# OMNISOCIALS_API_KEY environment variable. Raises
|
|
@@ -89,6 +89,7 @@ module OmniSocials
|
|
|
89
89
|
@media = Resources::Media.new(self)
|
|
90
90
|
@folders = Resources::Folders.new(self)
|
|
91
91
|
@hashtag_sets = Resources::HashtagSets.new(self)
|
|
92
|
+
@approval_workflows = Resources::ApprovalWorkflows.new(self)
|
|
92
93
|
@accounts = Resources::Accounts.new(self)
|
|
93
94
|
@analytics = Resources::Analytics.new(self)
|
|
94
95
|
@audio = Resources::Audio.new(self)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OmniSocials
|
|
4
|
+
module Resources
|
|
5
|
+
# Approval workflows resource: the workflows configured in the dashboard
|
|
6
|
+
# (Approvals). List them here and route a post through one at create time
|
|
7
|
+
# via approval_workflow_id on posts.create.
|
|
8
|
+
class ApprovalWorkflows
|
|
9
|
+
def initialize(client)
|
|
10
|
+
@client = client
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# GET /approval-workflows - the workflows this workspace can use
|
|
14
|
+
# (company-wide plus workspace-bound), with steps and named approvers.
|
|
15
|
+
def list
|
|
16
|
+
@client.request("GET", "/approval-workflows")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -24,24 +24,29 @@ module OmniSocials
|
|
|
24
24
|
#
|
|
25
25
|
# All filters are optional: platform ("instagram", "facebook",
|
|
26
26
|
# "linkedin", "tiktok", "youtube", "x", "threads"), type ("dm", "comment",
|
|
27
|
-
# "mention"), unread (only conversations with unread messages),
|
|
28
|
-
# (
|
|
29
|
-
#
|
|
27
|
+
# "mention"), unread (only conversations with unread messages),
|
|
28
|
+
# unanswered (only conversations that still need an answer: the
|
|
29
|
+
# customer's latest DM has no reply after it, for Instagram/Facebook DMs
|
|
30
|
+
# within the 24-hour messaging window only, or a comment/mention that
|
|
31
|
+
# has not been replied to and is not hidden; replies typed in the native
|
|
32
|
+
# apps count as answers, and read state is ignored, so use `next` for a
|
|
33
|
+
# work queue), limit (1-100), and cursor (an opaque cursor from a
|
|
34
|
+
# previous response's pagination["next_cursor"]).
|
|
30
35
|
#
|
|
31
36
|
# Threads conversations are type "comment" (replies people leave on the
|
|
32
37
|
# user's Threads posts; conversation ids look like
|
|
33
38
|
# "threads_comment_<rootPostId>") and "mention"
|
|
34
39
|
# ("threads_mention_<postId>"); there are no Threads DMs. Threads inbox
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
def list_conversations(platform: nil, type: nil, unread: nil, limit: nil, cursor: nil)
|
|
40
|
+
# needs a Threads connection with the reply permissions; connections made
|
|
41
|
+
# before those permissions existed must be reconnected once.
|
|
42
|
+
def list_conversations(platform: nil, type: nil, unread: nil, unanswered: nil, limit: nil, cursor: nil)
|
|
39
43
|
@client.request(
|
|
40
44
|
"GET", "/inbox/conversations",
|
|
41
45
|
query: {
|
|
42
46
|
"platform" => platform,
|
|
43
47
|
"type" => type,
|
|
44
48
|
"unread" => unread,
|
|
49
|
+
"unanswered" => unanswered,
|
|
45
50
|
"limit" => limit,
|
|
46
51
|
"cursor" => cursor
|
|
47
52
|
}
|
|
@@ -73,10 +78,9 @@ module OmniSocials
|
|
|
73
78
|
# text-only. Returns the created outgoing message.
|
|
74
79
|
#
|
|
75
80
|
# On a Threads conversation the reply publishes as a native Threads
|
|
76
|
-
# reply. Threads inbox
|
|
77
|
-
# until Meta App Review) and needs a Threads connection with the reply
|
|
81
|
+
# reply. The Threads inbox needs a Threads connection with the reply
|
|
78
82
|
# permission: a 401 with code "reauth_required" means the connection
|
|
79
|
-
# lacks that permission (reconnect Threads).
|
|
83
|
+
# lacks that permission (connected before it existed; reconnect Threads).
|
|
80
84
|
#
|
|
81
85
|
# Replying to an X DM costs 2 prepaid credits, debited from the
|
|
82
86
|
# company balance before the send and automatically refunded if the
|
|
@@ -86,12 +90,19 @@ module OmniSocials
|
|
|
86
90
|
# auto-suspended after the balance hit zero (top up and re-enable it
|
|
87
91
|
# in the dashboard to resume; DMs that arrived while suspended are
|
|
88
92
|
# not recovered).
|
|
89
|
-
|
|
93
|
+
#
|
|
94
|
+
# Pass include_next: true to also get "next" (the next conversation
|
|
95
|
+
# that needs an answer, the same object `next` returns under "data",
|
|
96
|
+
# using its default queue order and filters; nil when nothing is
|
|
97
|
+
# waiting) and "remaining" in the response. Saves the extra call when
|
|
98
|
+
# working through the inbox.
|
|
99
|
+
def reply(conversation_id, text: nil, attachment_url: nil, attachment_type: nil, include_next: nil)
|
|
90
100
|
body = Internal.drop_nil(
|
|
91
101
|
{
|
|
92
102
|
"text" => text,
|
|
93
103
|
"attachment_url" => attachment_url,
|
|
94
|
-
"attachment_type" => attachment_type
|
|
104
|
+
"attachment_type" => attachment_type,
|
|
105
|
+
"include_next" => include_next
|
|
95
106
|
}
|
|
96
107
|
)
|
|
97
108
|
@client.request(
|
|
@@ -100,18 +111,31 @@ module OmniSocials
|
|
|
100
111
|
)
|
|
101
112
|
end
|
|
102
113
|
|
|
103
|
-
# POST /inbox/messages/{id}/hide - hide or unhide a
|
|
104
|
-
# on one of the user's
|
|
105
|
-
#
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
#
|
|
114
|
+
# POST /inbox/messages/{id}/hide - hide or unhide a comment someone
|
|
115
|
+
# left on one of the user's posts, on the platform, as the post owner.
|
|
116
|
+
# Facebook, Instagram, TikTok, YouTube and Threads comments (Threads:
|
|
117
|
+
# incoming top-level replies only; Threads does not allow hiding nested
|
|
118
|
+
# replies). Pass hide: false to unhide. On YouTube, hide sets the
|
|
119
|
+
# comment's moderation status to rejected, which removes it and its
|
|
120
|
+
# replies from public view; unhide publishes it again. Returns the
|
|
121
|
+
# updated message with its "hidden" flag flipped; the message keeps its
|
|
122
|
+
# place in the conversation, and a hidden comment no longer counts as
|
|
123
|
+
# unanswered. The account must have been connected with the moderation
|
|
124
|
+
# permission (Facebook pages_manage_engagement, Instagram
|
|
125
|
+
# instagram_business_manage_comments).
|
|
109
126
|
#
|
|
110
|
-
# Errors: 400 "unsupported_platform" (not an incoming
|
|
111
|
-
#
|
|
112
|
-
# Threads refused), 401 "reauth_required" (
|
|
113
|
-
#
|
|
114
|
-
#
|
|
127
|
+
# Errors: 400 "unsupported_platform" (not an incoming comment on a
|
|
128
|
+
# supported platform), 400 "not_hideable" (Threads nested reply, or
|
|
129
|
+
# Threads refused), 401 "reauth_required" (the Threads reply permission
|
|
130
|
+
# or the TikTok comments authorization is missing or expired), 403
|
|
131
|
+
# "reconnect_required" (the account was connected without the
|
|
132
|
+
# comment-moderation permission; reconnect it in the dashboard), 404
|
|
133
|
+
# "not_found" (message not in this workspace) or
|
|
134
|
+
# "account_not_connected", 429 "quota_exceeded" (YouTube's daily API
|
|
135
|
+
# quota is used up; retry after midnight Pacific), 502 "platform_error"
|
|
136
|
+
# (the platform rejected the call). Threads inbox is currently rolling
|
|
137
|
+
# out; until Meta approves the permissions it is disabled on production
|
|
138
|
+
# and Threads calls return a clear error.
|
|
115
139
|
def hide(message_id, hide: true)
|
|
116
140
|
@client.request(
|
|
117
141
|
"POST", "/inbox/messages/#{encode_id(message_id)}/hide",
|
|
@@ -119,6 +143,75 @@ module OmniSocials
|
|
|
119
143
|
)
|
|
120
144
|
end
|
|
121
145
|
|
|
146
|
+
# DELETE /inbox/messages/{id} - delete a comment someone left on one of
|
|
147
|
+
# the user's posts, on the platform and from the inbox. Facebook,
|
|
148
|
+
# Instagram and TikTok comments only: YouTube's API does not let a
|
|
149
|
+
# channel delete other people's comments, hide those instead (`hide`).
|
|
150
|
+
# Replies under the deleted comment go with it (the platforms cascade
|
|
151
|
+
# the delete and the inbox mirrors that); their inbox ids come back as
|
|
152
|
+
# "removed_reply_ids". A comment that is already gone on the platform
|
|
153
|
+
# is still removed from the inbox. This cannot be undone. Returns
|
|
154
|
+
# { "data" => { "id", "conversation_id", "removed_reply_ids" } }.
|
|
155
|
+
#
|
|
156
|
+
# Errors: 400 "unsupported_platform" (not an incoming Facebook,
|
|
157
|
+
# Instagram or TikTok comment), 401 "reauth_required" (the TikTok
|
|
158
|
+
# comments authorization expired), 403 "reconnect_required" (the
|
|
159
|
+
# account was connected without the comment-moderation permission;
|
|
160
|
+
# reconnect it in the dashboard), 404 "not_found" (message not in this
|
|
161
|
+
# workspace) or "account_not_connected", 502 "platform_error" (the
|
|
162
|
+
# platform rejected the call).
|
|
163
|
+
def delete_message(message_id)
|
|
164
|
+
@client.request("DELETE", "/inbox/messages/#{encode_id(message_id)}")
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# GET /inbox/next - the next conversation that needs an answer: a work
|
|
168
|
+
# queue for answering the inbox. Returns the oldest (by default) item
|
|
169
|
+
# that still needs a reply, together with its conversation so far and
|
|
170
|
+
# the post it belongs to, so a reply can be drafted from one call. An
|
|
171
|
+
# item needs an answer when it is the customer's latest DM with no
|
|
172
|
+
# reply after it (Instagram/Facebook DMs within the 24-hour messaging
|
|
173
|
+
# window only, since Meta refuses replies outside it), or a
|
|
174
|
+
# comment/mention that has not been replied to and is not hidden.
|
|
175
|
+
# Replies typed in the native apps count as answers (they are mirrored
|
|
176
|
+
# into the inbox), so a thread a colleague answered on their phone is
|
|
177
|
+
# not served again. Instagram mentions are skipped (no reply path).
|
|
178
|
+
# Looks at the last 30 days of activity. Requires the inbox:read scope.
|
|
179
|
+
#
|
|
180
|
+
# Only unread items are served by default: marking a conversation read
|
|
181
|
+
# (`mark_read`) is how to skip one for good; pass include_read: true to
|
|
182
|
+
# include read-but-unanswered items. exclude is a session-local skip:
|
|
183
|
+
# conversation ids (an Array, or a comma-separated String) to leave out
|
|
184
|
+
# of this call, up to 100. order is "oldest" (default: the item that
|
|
185
|
+
# has waited longest first) or "newest". platform and type ("dm",
|
|
186
|
+
# "comment", "mention") narrow the queue.
|
|
187
|
+
#
|
|
188
|
+
# Returns { "data" => ..., "remaining" => Integer }. "data" is
|
|
189
|
+
# { "conversation", "message", "messages" }, or nil when nothing is
|
|
190
|
+
# waiting. "message" is the unanswered incoming item itself (the
|
|
191
|
+
# customer's latest DM, or the specific comment): its "id" is what
|
|
192
|
+
# `hide` and `delete_message` take, its "conversation_id" is what
|
|
193
|
+
# `reply` takes. "messages" is the conversation so far, oldest first
|
|
194
|
+
# (the most recent 50 messages for long DM threads). "remaining" is the
|
|
195
|
+
# number of unanswered items still waiting after this one (capped at
|
|
196
|
+
# 500), 0 when "data" is nil. To chain the queue, pass
|
|
197
|
+
# include_next: true to `reply` and it returns the next item in the
|
|
198
|
+
# same response. Errors: 400 "validation_error" (unknown platform, type
|
|
199
|
+
# or order).
|
|
200
|
+
def next(platform: nil, type: nil, order: nil, include_read: nil, exclude: nil)
|
|
201
|
+
exclude = exclude.join(",") if exclude.is_a?(Array)
|
|
202
|
+
exclude = nil if exclude == ""
|
|
203
|
+
@client.request(
|
|
204
|
+
"GET", "/inbox/next",
|
|
205
|
+
query: {
|
|
206
|
+
"platform" => platform,
|
|
207
|
+
"type" => type,
|
|
208
|
+
"order" => order,
|
|
209
|
+
"include_read" => include_read,
|
|
210
|
+
"exclude" => exclude
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
end
|
|
214
|
+
|
|
122
215
|
private
|
|
123
216
|
|
|
124
217
|
# URL-encode a conversation or message id for use in a path segment.
|
|
@@ -46,6 +46,13 @@ module OmniSocials
|
|
|
46
46
|
# POST /posts/create - create a post (draft, or scheduled when
|
|
47
47
|
# scheduled_at is set).
|
|
48
48
|
#
|
|
49
|
+
# approval_workflow_id (a workflow id from client.approval_workflows.list)
|
|
50
|
+
# routes the post through a saved approval workflow: it is created as
|
|
51
|
+
# in_approval (approval_status "pending") instead of scheduled, the
|
|
52
|
+
# approvers are notified, and it publishes at scheduled_at once the last
|
|
53
|
+
# step approves. Requires scheduled_at; not allowed with publish_now.
|
|
54
|
+
# Errors: 404 workflow_not_found, 400 validation_error.
|
|
55
|
+
#
|
|
49
56
|
# hashtag_set (set name, case-insensitive) or hashtag_set_id applies a
|
|
50
57
|
# saved hashtag set once at create time; tags already in a caption are
|
|
51
58
|
# skipped; Instagram's 30-hashtag cap returns error code
|
|
@@ -88,7 +95,7 @@ module OmniSocials
|
|
|
88
95
|
instagram: nil, facebook: nil, linkedin: nil,
|
|
89
96
|
linkedin_page: nil, tiktok: nil, x: nil, bluesky: nil,
|
|
90
97
|
mastodon: nil, threads: nil, google_business: nil,
|
|
91
|
-
linkedin_poll: nil)
|
|
98
|
+
linkedin_poll: nil, approval_workflow_id: nil)
|
|
92
99
|
body = create_body(
|
|
93
100
|
content: content, channels: channels, scheduled_at: scheduled_at,
|
|
94
101
|
media_ids: media_ids, media_urls: media_urls, type: type,
|
|
@@ -101,7 +108,8 @@ module OmniSocials
|
|
|
101
108
|
youtube: youtube, instagram: instagram, facebook: facebook,
|
|
102
109
|
linkedin: linkedin, linkedin_page: linkedin_page, tiktok: tiktok,
|
|
103
110
|
x: x, bluesky: bluesky, mastodon: mastodon, threads: threads,
|
|
104
|
-
google_business: google_business, linkedin_poll: linkedin_poll
|
|
111
|
+
google_business: google_business, linkedin_poll: linkedin_poll,
|
|
112
|
+
approval_workflow_id: approval_workflow_id
|
|
105
113
|
)
|
|
106
114
|
@client.request("POST", "/posts/create", json: body)
|
|
107
115
|
end
|
|
@@ -184,7 +192,7 @@ module OmniSocials
|
|
|
184
192
|
@client.request("PATCH", "/posts/#{post_id}", json: body)
|
|
185
193
|
end
|
|
186
194
|
|
|
187
|
-
# DELETE /posts/{id} -
|
|
195
|
+
# DELETE /posts/{id} - remove a post from OmniSocials (the live post stays on the platform). Returns nil (204).
|
|
188
196
|
def delete(post_id)
|
|
189
197
|
@client.request("DELETE", "/posts/#{post_id}")
|
|
190
198
|
end
|
|
@@ -239,7 +247,8 @@ module OmniSocials
|
|
|
239
247
|
hashtag_set_id:, hashtag_placement:, hashtag_platforms:,
|
|
240
248
|
pinterest:, youtube:, instagram:, facebook:, linkedin:,
|
|
241
249
|
linkedin_page:, tiktok:, x:, bluesky:, mastodon:,
|
|
242
|
-
threads:, google_business:, linkedin_poll
|
|
250
|
+
threads:, google_business:, linkedin_poll:,
|
|
251
|
+
approval_workflow_id: nil)
|
|
243
252
|
Internal.drop_nil(
|
|
244
253
|
{
|
|
245
254
|
"content" => content,
|
|
@@ -272,7 +281,8 @@ module OmniSocials
|
|
|
272
281
|
"mastodon" => mastodon,
|
|
273
282
|
"threads" => threads,
|
|
274
283
|
"google_business" => google_business,
|
|
275
|
-
"linkedin_poll" => linkedin_poll
|
|
284
|
+
"linkedin_poll" => linkedin_poll,
|
|
285
|
+
"approval_workflow_id" => approval_workflow_id
|
|
276
286
|
}
|
|
277
287
|
)
|
|
278
288
|
end
|
data/lib/omnisocials/version.rb
CHANGED
data/lib/omnisocials.rb
CHANGED
|
@@ -20,6 +20,7 @@ require_relative "omnisocials/resources/posts"
|
|
|
20
20
|
require_relative "omnisocials/resources/media"
|
|
21
21
|
require_relative "omnisocials/resources/folders"
|
|
22
22
|
require_relative "omnisocials/resources/hashtag_sets"
|
|
23
|
+
require_relative "omnisocials/resources/approval_workflows"
|
|
23
24
|
require_relative "omnisocials/resources/accounts"
|
|
24
25
|
require_relative "omnisocials/resources/analytics"
|
|
25
26
|
require_relative "omnisocials/resources/audio"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: omnisocials
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OmniSocials
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-09-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Schedule and publish social media posts, upload media, and read analytics
|
|
14
14
|
across Instagram, Facebook, LinkedIn, YouTube, TikTok, X, Pinterest, Bluesky, Threads,
|
|
@@ -27,6 +27,7 @@ files:
|
|
|
27
27
|
- lib/omnisocials/internal.rb
|
|
28
28
|
- lib/omnisocials/resources/accounts.rb
|
|
29
29
|
- lib/omnisocials/resources/analytics.rb
|
|
30
|
+
- lib/omnisocials/resources/approval_workflows.rb
|
|
30
31
|
- lib/omnisocials/resources/audio.rb
|
|
31
32
|
- lib/omnisocials/resources/folders.rb
|
|
32
33
|
- lib/omnisocials/resources/hashtag_sets.rb
|