chat_sdk-x 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df8df52963fbcdfc02f6457a2470c9708aa276d08443d5ec55a2174194db06c3
4
- data.tar.gz: 012ca08f40e7e0b86638879fdc4db880ec46e43f95e3e6b7632bd51212872db2
3
+ metadata.gz: b3d2500b4890fc426c2f4bf0ae98c4d20309818ddfe00c66518013481a6aa436
4
+ data.tar.gz: 51c114854c79621bdd093b06bc0d1f7a040533ea38f943ce7f6b9bfae056b51c
5
5
  SHA512:
6
- metadata.gz: 9762fc0118566399c42d729c675246cb326548083d8d8ed3d930503f892a450ad0cb64a026af4c573ebbad7873137a52df32e667a68d02a975e2981f275d9d62
7
- data.tar.gz: 77e54b2060e5ecdc190466eaf666d4a7ed20db53ee7ca382d46b2a99f87ade839b00ab5084cb9b4b8827a84a77d9fc0296990bb33991678493a63f990c4589dc
6
+ metadata.gz: 4f096900b3e142d8aba30b804c8ad49309755392876dd3741bb7824d92879bd09fc5b5aad4f888b6185556d34c001664eedc3af3fcdc83a1adaad6d3d2b19493
7
+ data.tar.gz: 7665fbb3b51567a21a4abf0007853845ed13a902f3cf1483e4b08eba2c5f23408e31001ebbb16f870f09af5d5de99ae8d01e113932bd977bd634802acd8809e2
@@ -7,7 +7,9 @@ require "rack/utils"
7
7
  module ChatSDK
8
8
  module X
9
9
  class Adapter < ChatSDK::Adapter::Base
10
- capabilities :direct_messages, :reactions, :delete_messages, :message_history
10
+ include ChatSDK::Adapter::MediaTypes
11
+
12
+ capabilities :direct_messages, :reactions, :delete_messages, :message_history, :file_uploads
11
13
 
12
14
  attr_reader :client
13
15
 
@@ -83,23 +85,23 @@ module ChatSDK
83
85
  raw: result
84
86
  )
85
87
  else
86
- payload = {text: text}
87
- payload[:reply] = {in_reply_to_tweet_id: channel_id} if channel_id && thread_id
88
- result = @client.create_tweet(**payload)
89
- tweet_id = result.dig("data", "id") || result["id"]
90
-
91
- ChatSDK::Message.new(
92
- id: tweet_id,
93
- text: text,
94
- author: ChatSDK::Author.new(id: @user_id || "bot", name: "bot", platform: :x, bot: true),
95
- thread_id: thread_id || "x:post:#{tweet_id}",
96
- channel_id: channel_id,
97
- platform: :x,
98
- raw: result
99
- )
88
+ reply_to = (channel_id if channel_id && thread_id)
89
+ result = @client.create_tweet(text: text, reply_to: reply_to)
90
+ parse_tweet_message(result, channel_id, thread_id: thread_id)
100
91
  end
101
92
  end
102
93
 
94
+ def upload_file(channel_id:, io:, filename:, thread_id: nil, comment: nil) # rubocop:disable Lint/UnusedMethodArgument
95
+ content_type = detect_content_type(filename)
96
+ bytes = io.respond_to?(:size) ? io.size : io.read.bytesize.tap { io.rewind }
97
+
98
+ media_id = @client.upload_media(io: io, content_type: content_type, total_bytes: bytes)
99
+
100
+ text = comment || ""
101
+ result = @client.create_tweet(text: text, media_ids: [media_id])
102
+ parse_tweet_message(result, channel_id)
103
+ end
104
+
103
105
  def delete_message(channel_id:, message_id:) # rubocop:disable Lint/UnusedMethodArgument
104
106
  @client.delete_tweet(tweet_id: message_id)
105
107
  end
@@ -141,6 +143,19 @@ module ChatSDK
141
143
  @client.unlike_tweet(user_id: @user_id, tweet_id: message_id)
142
144
  end
143
145
 
146
+ def get_user(user_id)
147
+ data = @client.get_user(user_id)
148
+ return nil unless data&.dig("data", "id")
149
+
150
+ ChatSDK::Author.new(
151
+ id: data.dig("data", "id"),
152
+ name: data.dig("data", "username"),
153
+ platform: :x,
154
+ bot: false,
155
+ raw: data
156
+ )
157
+ end
158
+
144
159
  def open_dm(user_id)
145
160
  user_id
146
161
  end
@@ -152,6 +167,22 @@ module ChatSDK
152
167
  def render(postable_message)
153
168
  postable_message.text
154
169
  end
170
+
171
+ private
172
+
173
+ def parse_tweet_message(result, channel_id, thread_id: nil)
174
+ tweet_id = result.dig("data", "id") || result["id"]
175
+
176
+ ChatSDK::Message.new(
177
+ id: tweet_id,
178
+ text: result.dig("data", "text") || "",
179
+ author: ChatSDK::Author.new(id: @user_id || "bot", name: "bot", platform: :x, bot: true),
180
+ thread_id: thread_id || "x:post:#{tweet_id}",
181
+ channel_id: channel_id,
182
+ platform: :x,
183
+ raw: result
184
+ )
185
+ end
155
186
  end
156
187
  end
157
188
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "base64"
4
+
3
5
  module ChatSDK
4
6
  module X
5
7
  class ApiClient < ChatSDK::ApiClient::Base
@@ -9,12 +11,42 @@ module ChatSDK
9
11
  @access_token = access_token
10
12
  end
11
13
 
12
- def create_tweet(text:, reply: nil)
14
+ def create_tweet(text:, reply_to: nil, media_ids: nil)
13
15
  body = {"text" => text}
14
- body["reply"] = reply if reply
16
+ body["reply"] = {"in_reply_to_tweet_id" => reply_to} if reply_to
17
+ body["media"] = {"media_ids" => media_ids} if media_ids&.any?
15
18
  request(:post, "/2/tweets", body)
16
19
  end
17
20
 
21
+ def upload_media(io:, content_type:, total_bytes:)
22
+ # INIT
23
+ init_result = request(:post, "/2/media/upload", {
24
+ command: "INIT",
25
+ total_bytes: total_bytes,
26
+ media_type: content_type
27
+ })
28
+ media_id = init_result.dig("data", "id") || init_result["media_id_string"]
29
+
30
+ # APPEND (single chunk, works for images <5MB)
31
+ response = upload_connection.post("/2/media/upload") do |req|
32
+ req.body = {
33
+ command: "APPEND",
34
+ media_id: media_id,
35
+ segment_index: 0,
36
+ media_data: Base64.strict_encode64(io.read)
37
+ }
38
+ end
39
+ handle_response(response)
40
+
41
+ # FINALIZE
42
+ request(:post, "/2/media/upload", {
43
+ command: "FINALIZE",
44
+ media_id: media_id
45
+ })
46
+
47
+ media_id
48
+ end
49
+
18
50
  def send_dm(participant_id:, text:)
19
51
  request(:post, "/2/dm_conversations/with/#{participant_id}/messages", {"text" => text})
20
52
  end
@@ -31,6 +63,10 @@ module ChatSDK
31
63
  request(:delete, "/2/tweets/#{tweet_id}")
32
64
  end
33
65
 
66
+ def get_user(user_id)
67
+ request(:get, "/2/users/#{user_id}?user.fields=name,username")
68
+ end
69
+
34
70
  def get_dm_events(participant_id:, cursor: nil, limit: 50)
35
71
  query = "max_results=#{[limit, 100].min}&dm_event.fields=id,text,sender_id,created_at"
36
72
  query += "&pagination_token=#{cursor}" if cursor
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chat_sdk-x
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Quentin Rousseau