talknote_rb 0.1.0 โ 0.2.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/.github/dependabot.yml +11 -0
- data/.github/workflows/main.yml +37 -0
- data/Gemfile +6 -3
- data/Gemfile.lock +71 -34
- data/README.md +351 -13
- data/examples/complete_csv_export_example.rb +268 -0
- data/examples/dm_csv_export_example.rb +133 -0
- data/examples/dm_example.rb +55 -0
- data/examples/group_csv_export_example.rb +146 -0
- data/examples/group_example.rb +107 -0
- data/lib/talknote/cli.rb +142 -37
- data/lib/talknote/client.rb +56 -13
- data/lib/talknote/version.rb +1 -1
- data/lib/talknote.rb +2 -0
- data/talknote_rb.gemspec +9 -4
- metadata +86 -10
- data/.travis.yml +0 -6
@@ -0,0 +1,268 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Example: Export all Talknote conversations (DMs and Groups) to separate CSV files
|
5
|
+
require_relative '../lib/talknote'
|
6
|
+
require 'csv'
|
7
|
+
require 'time'
|
8
|
+
require 'fileutils'
|
9
|
+
|
10
|
+
def safe_get(hash, key, default = '')
|
11
|
+
return default if hash.nil?
|
12
|
+
hash[key] || default
|
13
|
+
end
|
14
|
+
|
15
|
+
def format_timestamp(timestamp)
|
16
|
+
return '' if timestamp.nil? || timestamp.empty?
|
17
|
+
Time.parse(timestamp).strftime('%Y-%m-%d %H:%M:%S')
|
18
|
+
rescue
|
19
|
+
timestamp
|
20
|
+
end
|
21
|
+
|
22
|
+
def export_all_to_csv(output_dir = "talknote_export_#{Time.now.strftime('%Y%m%d_%H%M%S')}")
|
23
|
+
puts "๐ Talknote Complete CSV Export"
|
24
|
+
puts "=" * 50
|
25
|
+
puts "โ ๏ธ ๆณจๆ: Exportๅฆ็ใฏ้ซ่ฒ ่ทๅฆ็ใฎใใใๅคง้ใฎใใผใฟใใใๅ ดๅใ"
|
26
|
+
puts " ใตใผใใผๅดใฎ่ฒ ่ทๅถ้ใซใใๅฆ็ใไธญๆญใใใๅฏ่ฝๆงใใใใพใใ"
|
27
|
+
puts " ๅฆ็ใๆญขใพใฃใๅ ดๅใฏใๆ้ใใใใฆๅๅฎ่กใใฆใใ ใใใ"
|
28
|
+
puts
|
29
|
+
puts "Exporting all conversations to directory: #{output_dir}"
|
30
|
+
puts
|
31
|
+
|
32
|
+
# Create output directory
|
33
|
+
FileUtils.mkdir_p(output_dir)
|
34
|
+
|
35
|
+
begin
|
36
|
+
client = Talknote::Client.new
|
37
|
+
puts "โ
Successfully initialized Talknote client"
|
38
|
+
rescue StandardError => e
|
39
|
+
puts "โ Failed to initialize client: #{e.message}"
|
40
|
+
puts "\nMake sure you've run: talknote init -i CLIENT_ID -s CLIENT_SECRET"
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
|
44
|
+
total_conversations = 0
|
45
|
+
total_messages = 0
|
46
|
+
|
47
|
+
# Export DM conversations
|
48
|
+
puts "\n๐ฑ Exporting DM conversations..."
|
49
|
+
dm_filename = File.join(output_dir, "dm_conversations.csv")
|
50
|
+
|
51
|
+
CSV.open(dm_filename, 'w', encoding: 'UTF-8') do |csv|
|
52
|
+
csv << [
|
53
|
+
'conversation_id',
|
54
|
+
'conversation_name',
|
55
|
+
'message_id',
|
56
|
+
'user_id',
|
57
|
+
'user_name',
|
58
|
+
'message',
|
59
|
+
'created_at',
|
60
|
+
'message_type'
|
61
|
+
]
|
62
|
+
|
63
|
+
begin
|
64
|
+
dm_response = client.dm
|
65
|
+
dm_conversations = dm_response.dig('data', 'threads') || []
|
66
|
+
puts "Found #{dm_conversations.size} DM conversations"
|
67
|
+
total_conversations += dm_conversations.size
|
68
|
+
|
69
|
+
dm_conversations.each_with_index do |conversation, index|
|
70
|
+
conversation_id = safe_get(conversation, 'id')
|
71
|
+
conversation_name = safe_get(conversation, 'title')
|
72
|
+
|
73
|
+
print " Processing DM #{index + 1}/#{dm_conversations.size}: #{conversation_name}"
|
74
|
+
|
75
|
+
# ๆณจๆ: Exportๅฆ็ใฏ้ซ่ฒ ่ทใใใใใใใAPIๅถ้ใ่ฒ ่ทๅถ้ใซใใๅฆ็ใๅๆญขใใใๅฏ่ฝๆงใใใใพใ
|
76
|
+
# ใฌใผใๅถ้ใๅ้ฟใใใใใๅไผ่ฉฑๅฆ็้ใซ้ฉๅใชๅพ
ๆฉๆ้ใ่จญใใฆใใพใ
|
77
|
+
|
78
|
+
begin
|
79
|
+
messages_response = client.dm_list(conversation_id)
|
80
|
+
messages = messages_response.dig('data', 'msg') || []
|
81
|
+
total_messages += messages.size
|
82
|
+
|
83
|
+
messages.each do |message|
|
84
|
+
csv << [
|
85
|
+
conversation_id,
|
86
|
+
conversation_name,
|
87
|
+
safe_get(message, 'id'),
|
88
|
+
safe_get(message, 'user_id'),
|
89
|
+
safe_get(message, 'user_name'),
|
90
|
+
safe_get(message, 'message'),
|
91
|
+
format_timestamp(safe_get(message, 'created_at')),
|
92
|
+
safe_get(message, 'type', 'text')
|
93
|
+
]
|
94
|
+
end
|
95
|
+
|
96
|
+
puts " (#{messages.size} messages)"
|
97
|
+
|
98
|
+
rescue Talknote::Error => e
|
99
|
+
puts " โ Error: #{e.message}"
|
100
|
+
csv << [
|
101
|
+
conversation_id,
|
102
|
+
conversation_name,
|
103
|
+
'',
|
104
|
+
'',
|
105
|
+
'',
|
106
|
+
"ERROR: #{e.message}",
|
107
|
+
format_timestamp(Time.now.to_s),
|
108
|
+
'error'
|
109
|
+
]
|
110
|
+
end
|
111
|
+
|
112
|
+
# ใฌใผใๅถ้ๅฏพ็ญ: ใตใผใใผใธใฎ่ฒ ่ทใ่ปฝๆธใใใใใๅไผ่ฉฑๅฆ็ๅพใซๅพ
ๆฉๆ้ใ่จญใใ
|
113
|
+
sleep(1)
|
114
|
+
end
|
115
|
+
|
116
|
+
rescue Talknote::Error => e
|
117
|
+
puts "โ DM API Error: #{e.message}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Export Group conversations
|
122
|
+
puts "\n๐ฅ Exporting group conversations..."
|
123
|
+
group_filename = File.join(output_dir, "group_conversations.csv")
|
124
|
+
|
125
|
+
CSV.open(group_filename, 'w', encoding: 'UTF-8') do |csv|
|
126
|
+
csv << [
|
127
|
+
'group_id',
|
128
|
+
'group_name',
|
129
|
+
'message_id',
|
130
|
+
'sender_id',
|
131
|
+
'sender_name',
|
132
|
+
'message',
|
133
|
+
'created_at',
|
134
|
+
'message_type',
|
135
|
+
'unread_count'
|
136
|
+
]
|
137
|
+
|
138
|
+
begin
|
139
|
+
groups_response = client.group
|
140
|
+
groups = groups_response.dig('data', 'groups') || []
|
141
|
+
puts "Found #{groups.size} groups"
|
142
|
+
total_conversations += groups.size
|
143
|
+
|
144
|
+
groups.each_with_index do |group, index|
|
145
|
+
group_id = safe_get(group, 'id')
|
146
|
+
group_name = safe_get(group, 'name')
|
147
|
+
|
148
|
+
print " Processing group #{index + 1}/#{groups.size}: #{group_name}"
|
149
|
+
|
150
|
+
# ๆณจๆ: Exportๅฆ็ใฏ้ซ่ฒ ่ทใใใใใใใAPIๅถ้ใ่ฒ ่ทๅถ้ใซใใๅฆ็ใๅๆญขใใใๅฏ่ฝๆงใใใใพใ
|
151
|
+
# ใฌใผใๅถ้ใๅ้ฟใใใใใๅใฐใซใผใๅฆ็้ใซ้ฉๅใชๅพ
ๆฉๆ้ใ่จญใใฆใใพใ
|
152
|
+
|
153
|
+
# Get unread count
|
154
|
+
unread_count = 0
|
155
|
+
begin
|
156
|
+
unread_response = client.group_unread(group_id)
|
157
|
+
unread_count = unread_response.dig('data', 'unread_count') || 0
|
158
|
+
rescue Talknote::Error
|
159
|
+
# Ignore unread count errors
|
160
|
+
end
|
161
|
+
|
162
|
+
begin
|
163
|
+
messages_response = client.group_list(group_id)
|
164
|
+
messages = messages_response.dig('data', 'messages') || []
|
165
|
+
total_messages += messages.size
|
166
|
+
|
167
|
+
messages.each do |message|
|
168
|
+
csv << [
|
169
|
+
group_id,
|
170
|
+
group_name,
|
171
|
+
safe_get(message, 'id'),
|
172
|
+
safe_get(message, 'sender_id'),
|
173
|
+
safe_get(message, 'sender_name'),
|
174
|
+
safe_get(message, 'message'),
|
175
|
+
format_timestamp(safe_get(message, 'created_at')),
|
176
|
+
safe_get(message, 'type', 'text'),
|
177
|
+
unread_count
|
178
|
+
]
|
179
|
+
end
|
180
|
+
|
181
|
+
puts " (#{messages.size} messages, #{unread_count} unread)"
|
182
|
+
|
183
|
+
rescue Talknote::Error => e
|
184
|
+
puts " โ Error: #{e.message}"
|
185
|
+
csv << [
|
186
|
+
group_id,
|
187
|
+
group_name,
|
188
|
+
'',
|
189
|
+
'',
|
190
|
+
'',
|
191
|
+
"ERROR: #{e.message}",
|
192
|
+
format_timestamp(Time.now.to_s),
|
193
|
+
'error',
|
194
|
+
unread_count
|
195
|
+
]
|
196
|
+
end
|
197
|
+
|
198
|
+
# ใฌใผใๅถ้ๅฏพ็ญ: ใตใผใใผใธใฎ่ฒ ่ทใ่ปฝๆธใใใใใๅใฐใซใผใๅฆ็ๅพใซๅพ
ๆฉๆ้ใ่จญใใ
|
199
|
+
sleep(1)
|
200
|
+
end
|
201
|
+
|
202
|
+
rescue Talknote::Error => e
|
203
|
+
puts "โ Group API Error: #{e.message}"
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# Create summary file
|
208
|
+
summary_filename = File.join(output_dir, "export_summary.txt")
|
209
|
+
File.write(summary_filename, <<~SUMMARY)
|
210
|
+
Talknote Export Summary
|
211
|
+
=======================
|
212
|
+
Export Date: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}
|
213
|
+
|
214
|
+
Files Created:
|
215
|
+
- dm_conversations.csv (Direct Messages)
|
216
|
+
- group_conversations.csv (Group Messages)
|
217
|
+
- export_summary.txt (This file)
|
218
|
+
|
219
|
+
Statistics:
|
220
|
+
- Total Conversations: #{total_conversations}
|
221
|
+
- Total Messages Exported: #{total_messages}
|
222
|
+
|
223
|
+
CSV Format:
|
224
|
+
|
225
|
+
DM Conversations:
|
226
|
+
- conversation_id: Unique identifier for the DM conversation
|
227
|
+
- conversation_name: Name of the conversation
|
228
|
+
- message_id: Unique identifier for the message
|
229
|
+
- sender_id: ID of the message sender
|
230
|
+
- sender_name: Name of the message sender
|
231
|
+
- message: The message content
|
232
|
+
- created_at: Timestamp when the message was created
|
233
|
+
- message_type: Type of message (text, image, etc.)
|
234
|
+
|
235
|
+
Group Conversations:
|
236
|
+
- group_id: Unique identifier for the group
|
237
|
+
- group_name: Name of the group
|
238
|
+
- message_id: Unique identifier for the message
|
239
|
+
- sender_id: ID of the message sender
|
240
|
+
- sender_name: Name of the message sender
|
241
|
+
- message: The message content
|
242
|
+
- created_at: Timestamp when the message was created
|
243
|
+
- message_type: Type of message (text, image, etc.)
|
244
|
+
- unread_count: Number of unread messages in the group
|
245
|
+
SUMMARY
|
246
|
+
|
247
|
+
puts
|
248
|
+
puts "๐ Complete export finished!"
|
249
|
+
puts "๐ Total conversations: #{total_conversations}"
|
250
|
+
puts "๐ Total messages exported: #{total_messages}"
|
251
|
+
puts "๐ Files saved in directory: #{output_dir}"
|
252
|
+
puts
|
253
|
+
puts "Files created:"
|
254
|
+
puts " - #{dm_filename}"
|
255
|
+
puts " - #{group_filename}"
|
256
|
+
puts " - #{summary_filename}"
|
257
|
+
|
258
|
+
rescue StandardError => e
|
259
|
+
puts "๐ฅ Unexpected error: #{e.message}"
|
260
|
+
puts e.backtrace.first(5).join("\n")
|
261
|
+
exit 1
|
262
|
+
end
|
263
|
+
|
264
|
+
if __FILE__ == $0
|
265
|
+
# Allow custom output directory as command line argument
|
266
|
+
output_dir = ARGV[0] || "talknote_export_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
|
267
|
+
export_all_to_csv(output_dir)
|
268
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Example: Export all DM conversations to CSV
|
5
|
+
require_relative '../lib/talknote'
|
6
|
+
require 'csv'
|
7
|
+
require 'time'
|
8
|
+
|
9
|
+
def safe_get(hash, key, default = '')
|
10
|
+
return default if hash.nil?
|
11
|
+
hash[key] || default
|
12
|
+
end
|
13
|
+
|
14
|
+
def format_timestamp(timestamp)
|
15
|
+
return '' if timestamp.nil? || timestamp.empty?
|
16
|
+
Time.parse(timestamp).strftime('%Y-%m-%d %H:%M:%S')
|
17
|
+
rescue
|
18
|
+
timestamp
|
19
|
+
end
|
20
|
+
|
21
|
+
def export_dm_to_csv(filename = "dm_export_#{Time.now.strftime('%Y%m%d_%H%M%S')}.csv")
|
22
|
+
puts "=== Talknote DM CSV Export ==="
|
23
|
+
puts "โ ๏ธ ๆณจๆ: Exportๅฆ็ใฏ้ซ่ฒ ่ทๅฆ็ใฎใใใๅคง้ใฎใใผใฟใใใๅ ดๅใ"
|
24
|
+
puts " ใตใผใใผๅดใฎ่ฒ ่ทๅถ้ใซใใๅฆ็ใไธญๆญใใใๅฏ่ฝๆงใใใใพใใ"
|
25
|
+
puts " ๅฆ็ใๆญขใพใฃใๅ ดๅใฏใๆ้ใใใใฆๅๅฎ่กใใฆใใ ใใใ"
|
26
|
+
puts
|
27
|
+
puts "Exporting all DM conversations to: #{filename}"
|
28
|
+
puts
|
29
|
+
|
30
|
+
begin
|
31
|
+
client = Talknote::Client.new
|
32
|
+
puts "โ
Successfully initialized Talknote client"
|
33
|
+
rescue StandardError => e
|
34
|
+
puts "โ Failed to initialize client: #{e.message}"
|
35
|
+
puts "\nMake sure you've run: talknote init -i CLIENT_ID -s CLIENT_SECRET"
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
CSV.open(filename, 'w', encoding: 'UTF-8') do |csv|
|
40
|
+
# CSV header
|
41
|
+
csv << [
|
42
|
+
'conversation_id',
|
43
|
+
'conversation_name',
|
44
|
+
'message_id',
|
45
|
+
'user_id',
|
46
|
+
'user_name',
|
47
|
+
'message',
|
48
|
+
'created_at',
|
49
|
+
'message_type'
|
50
|
+
]
|
51
|
+
|
52
|
+
begin
|
53
|
+
# Get all DM conversations
|
54
|
+
puts "๐ Getting all DM conversations..."
|
55
|
+
dm_response = client.dm
|
56
|
+
dm_conversations = dm_response.dig('data', 'threads') || []
|
57
|
+
puts "Found #{dm_conversations.size} DM conversations"
|
58
|
+
|
59
|
+
total_messages = 0
|
60
|
+
|
61
|
+
dm_conversations.each_with_index do |conversation, index|
|
62
|
+
conversation_id = safe_get(conversation, 'id')
|
63
|
+
conversation_name = safe_get(conversation, 'title')
|
64
|
+
|
65
|
+
puts "Processing conversation #{index + 1}/#{dm_conversations.size}: #{conversation_name} (ID: #{conversation_id})"
|
66
|
+
|
67
|
+
# ๆณจๆ: Exportๅฆ็ใฏ้ซ่ฒ ่ทใใใใใใใAPIๅถ้ใ่ฒ ่ทๅถ้ใซใใๅฆ็ใๅๆญขใใใๅฏ่ฝๆงใใใใพใ
|
68
|
+
# ใฌใผใๅถ้ใๅ้ฟใใใใใๅไผ่ฉฑๅฆ็ๅใซ้ฉๅใชๅพ
ๆฉๆ้ใ่จญใใฆใใพใ
|
69
|
+
|
70
|
+
begin
|
71
|
+
# Get messages from this conversation
|
72
|
+
messages_response = client.dm_list(conversation_id)
|
73
|
+
messages = messages_response.dig('data', 'msg') || []
|
74
|
+
|
75
|
+
puts " Found #{messages.size} messages"
|
76
|
+
total_messages += messages.size
|
77
|
+
|
78
|
+
messages.each do |message|
|
79
|
+
csv << [
|
80
|
+
conversation_id,
|
81
|
+
conversation_name,
|
82
|
+
safe_get(message, 'id'),
|
83
|
+
safe_get(message, 'user_id'),
|
84
|
+
safe_get(message, 'user_name'),
|
85
|
+
safe_get(message, 'message'),
|
86
|
+
format_timestamp(safe_get(message, 'created_at')),
|
87
|
+
safe_get(message, 'type', 'text')
|
88
|
+
]
|
89
|
+
end
|
90
|
+
|
91
|
+
rescue Talknote::Error => e
|
92
|
+
puts " โ Error getting messages for conversation #{conversation_id}: #{e.message}"
|
93
|
+
# Add error row to CSV
|
94
|
+
csv << [
|
95
|
+
conversation_id,
|
96
|
+
conversation_name,
|
97
|
+
'',
|
98
|
+
'',
|
99
|
+
'',
|
100
|
+
"ERROR: #{e.message}",
|
101
|
+
format_timestamp(Time.now.to_s),
|
102
|
+
'error'
|
103
|
+
]
|
104
|
+
end
|
105
|
+
|
106
|
+
# ใฌใผใๅถ้ๅฏพ็ญ: ใตใผใใผใธใฎ่ฒ ่ทใ่ปฝๆธใใใใใๅไผ่ฉฑๅฆ็ๅพใซๅพ
ๆฉๆ้ใ่จญใใ
|
107
|
+
# ๅคง้ใฎไผ่ฉฑใใใๅ ดๅใAPIๅถ้ใๅณใใๅ ดๅใฏใใใฎๅคใ่ชฟๆดใใฆใใ ใใ
|
108
|
+
sleep(1)
|
109
|
+
end
|
110
|
+
|
111
|
+
puts
|
112
|
+
puts "๐ Export completed successfully!"
|
113
|
+
puts "๐ Total conversations: #{dm_conversations.size}"
|
114
|
+
puts "๐ Total messages exported: #{total_messages}"
|
115
|
+
puts "๐ File saved as: #{filename}"
|
116
|
+
|
117
|
+
rescue Talknote::Error => e
|
118
|
+
puts "โ API Error: #{e.message}"
|
119
|
+
exit 1
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
rescue StandardError => e
|
124
|
+
puts "๐ฅ Unexpected error: #{e.message}"
|
125
|
+
puts e.backtrace.first(5).join("\n")
|
126
|
+
exit 1
|
127
|
+
end
|
128
|
+
|
129
|
+
if __FILE__ == $0
|
130
|
+
# Allow custom filename as command line argument
|
131
|
+
filename = ARGV[0] || "dm_export_#{Time.now.strftime('%Y%m%d_%H%M%S')}.csv"
|
132
|
+
export_dm_to_csv(filename)
|
133
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Example usage of the Talknote DM API
|
5
|
+
require_relative '../lib/talknote'
|
6
|
+
|
7
|
+
begin
|
8
|
+
# Initialize the client
|
9
|
+
client = Talknote::Client.new
|
10
|
+
|
11
|
+
puts "=== Talknote DM API Example ==="
|
12
|
+
puts
|
13
|
+
|
14
|
+
# Get all DM conversations
|
15
|
+
puts "1. Getting all DM conversations..."
|
16
|
+
dm_response = client.dm
|
17
|
+
dm_conversations = dm_response.dig('data', 'threads') || []
|
18
|
+
puts "Found #{dm_conversations.size} DM conversations"
|
19
|
+
puts
|
20
|
+
|
21
|
+
if dm_conversations.any?
|
22
|
+
# Get the first conversation ID for examples
|
23
|
+
first_conversation = dm_conversations.first
|
24
|
+
conversation_id = first_conversation['id']
|
25
|
+
|
26
|
+
puts "2. Getting messages from conversation #{conversation_id}..."
|
27
|
+
messages = client.dm_list(conversation_id)
|
28
|
+
puts "Found #{messages.size} messages in this conversation"
|
29
|
+
puts
|
30
|
+
|
31
|
+
puts "3. Getting unread count for conversation #{conversation_id}..."
|
32
|
+
unread_count = client.dm_unread(conversation_id)
|
33
|
+
puts "Unread messages: #{unread_count}"
|
34
|
+
puts
|
35
|
+
|
36
|
+
# Example of sending a message (commented out to avoid spam)
|
37
|
+
# puts "4. Sending a test message..."
|
38
|
+
# result = client.dm_post(conversation_id, "Hello from Ruby client!")
|
39
|
+
# puts "Message sent: #{result}"
|
40
|
+
# puts
|
41
|
+
else
|
42
|
+
puts "No DM conversations found"
|
43
|
+
end
|
44
|
+
|
45
|
+
rescue Talknote::Error => e
|
46
|
+
puts "Talknote API Error: #{e.message}"
|
47
|
+
exit 1
|
48
|
+
rescue Errno::ENOENT => e
|
49
|
+
puts "Authentication token not found. Please run 'bundle exec talknote init' first."
|
50
|
+
exit 1
|
51
|
+
rescue => e
|
52
|
+
puts "Unexpected error: #{e.message}"
|
53
|
+
puts e.backtrace.join("\n")
|
54
|
+
exit 1
|
55
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Example: Export all group conversations to CSV
|
5
|
+
require_relative '../lib/talknote'
|
6
|
+
require 'csv'
|
7
|
+
require 'time'
|
8
|
+
|
9
|
+
def safe_get(hash, key, default = '')
|
10
|
+
return default if hash.nil?
|
11
|
+
hash[key] || default
|
12
|
+
end
|
13
|
+
|
14
|
+
def format_timestamp(timestamp)
|
15
|
+
return '' if timestamp.nil? || timestamp.empty?
|
16
|
+
Time.parse(timestamp).strftime('%Y-%m-%d %H:%M:%S')
|
17
|
+
rescue
|
18
|
+
timestamp
|
19
|
+
end
|
20
|
+
|
21
|
+
def export_groups_to_csv(filename = "group_export_#{Time.now.strftime('%Y%m%d_%H%M%S')}.csv")
|
22
|
+
puts "=== Talknote Group CSV Export ==="
|
23
|
+
puts "โ ๏ธ ๆณจๆ: Exportๅฆ็ใฏ้ซ่ฒ ่ทๅฆ็ใฎใใใๅคง้ใฎใใผใฟใใใๅ ดๅใ"
|
24
|
+
puts " ใตใผใใผๅดใฎ่ฒ ่ทๅถ้ใซใใๅฆ็ใไธญๆญใใใๅฏ่ฝๆงใใใใพใใ"
|
25
|
+
puts " ๅฆ็ใๆญขใพใฃใๅ ดๅใฏใๆ้ใใใใฆๅๅฎ่กใใฆใใ ใใใ"
|
26
|
+
puts
|
27
|
+
puts "Exporting all group conversations to: #{filename}"
|
28
|
+
puts
|
29
|
+
|
30
|
+
begin
|
31
|
+
client = Talknote::Client.new
|
32
|
+
puts "โ
Successfully initialized Talknote client"
|
33
|
+
rescue StandardError => e
|
34
|
+
puts "โ Failed to initialize client: #{e.message}"
|
35
|
+
puts "\nMake sure you've run: talknote init -i CLIENT_ID -s CLIENT_SECRET"
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
CSV.open(filename, 'w', encoding: 'UTF-8') do |csv|
|
40
|
+
# CSV header
|
41
|
+
csv << [
|
42
|
+
'group_id',
|
43
|
+
'group_name',
|
44
|
+
'message_id',
|
45
|
+
'sender_id',
|
46
|
+
'sender_name',
|
47
|
+
'message',
|
48
|
+
'created_at',
|
49
|
+
'message_type',
|
50
|
+
'unread_count'
|
51
|
+
]
|
52
|
+
|
53
|
+
begin
|
54
|
+
# Get all groups
|
55
|
+
puts "๐ Getting all groups..."
|
56
|
+
groups_response = client.group
|
57
|
+
groups = groups_response.dig('data', 'groups') || []
|
58
|
+
puts "Found #{groups.size} groups"
|
59
|
+
|
60
|
+
total_messages = 0
|
61
|
+
|
62
|
+
groups.each_with_index do |group, index|
|
63
|
+
group_id = safe_get(group, 'id')
|
64
|
+
group_name = safe_get(group, 'name')
|
65
|
+
|
66
|
+
puts "Processing group #{index + 1}/#{groups.size}: #{group_name} (ID: #{group_id})"
|
67
|
+
|
68
|
+
# ๆณจๆ: Exportๅฆ็ใฏ้ซ่ฒ ่ทใใใใใใใAPIๅถ้ใ่ฒ ่ทๅถ้ใซใใๅฆ็ใๅๆญขใใใๅฏ่ฝๆงใใใใพใ
|
69
|
+
# ใฌใผใๅถ้ใๅ้ฟใใใใใๅใฐใซใผใๅฆ็ๅใซ้ฉๅใชๅพ
ๆฉๆ้ใ่จญใใฆใใพใ
|
70
|
+
|
71
|
+
# Get unread count for this group
|
72
|
+
unread_count = 0
|
73
|
+
begin
|
74
|
+
unread_response = client.group_unread(group_id)
|
75
|
+
unread_count = unread_response.dig('data', 'unread_count') || 0
|
76
|
+
puts " Unread messages: #{unread_count}"
|
77
|
+
rescue Talknote::Error => e
|
78
|
+
puts " โ Could not get unread count: #{e.message}"
|
79
|
+
end
|
80
|
+
|
81
|
+
begin
|
82
|
+
# Get messages from this group
|
83
|
+
messages_response = client.group_list(group_id)
|
84
|
+
messages = messages_response.dig('data', 'messages') || []
|
85
|
+
|
86
|
+
puts " Found #{messages.size} messages"
|
87
|
+
total_messages += messages.size
|
88
|
+
|
89
|
+
messages.each do |message|
|
90
|
+
csv << [
|
91
|
+
group_id,
|
92
|
+
group_name,
|
93
|
+
safe_get(message, 'id'),
|
94
|
+
safe_get(message, 'sender_id'),
|
95
|
+
safe_get(message, 'sender_name'),
|
96
|
+
safe_get(message, 'message'),
|
97
|
+
format_timestamp(safe_get(message, 'created_at')),
|
98
|
+
safe_get(message, 'type', 'text'),
|
99
|
+
unread_count
|
100
|
+
]
|
101
|
+
end
|
102
|
+
|
103
|
+
rescue Talknote::Error => e
|
104
|
+
puts " โ Error getting messages for group #{group_id}: #{e.message}"
|
105
|
+
# Add error row to CSV
|
106
|
+
csv << [
|
107
|
+
group_id,
|
108
|
+
group_name,
|
109
|
+
'',
|
110
|
+
'',
|
111
|
+
'',
|
112
|
+
"ERROR: #{e.message}",
|
113
|
+
format_timestamp(Time.now.to_s),
|
114
|
+
'error',
|
115
|
+
unread_count
|
116
|
+
]
|
117
|
+
end
|
118
|
+
|
119
|
+
# ใฌใผใๅถ้ๅฏพ็ญ: ใตใผใใผใธใฎ่ฒ ่ทใ่ปฝๆธใใใใใๅใฐใซใผใๅฆ็ๅพใซๅพ
ๆฉๆ้ใ่จญใใ
|
120
|
+
# ๅคง้ใฎใฐใซใผใใใใๅ ดๅใAPIๅถ้ใๅณใใๅ ดๅใฏใใใฎๅคใ่ชฟๆดใใฆใใ ใใ
|
121
|
+
sleep(1)
|
122
|
+
end
|
123
|
+
|
124
|
+
puts
|
125
|
+
puts "๐ Export completed successfully!"
|
126
|
+
puts "๐ Total groups: #{groups.size}"
|
127
|
+
puts "๐ Total messages exported: #{total_messages}"
|
128
|
+
puts "๐ File saved as: #{filename}"
|
129
|
+
|
130
|
+
rescue Talknote::Error => e
|
131
|
+
puts "โ API Error: #{e.message}"
|
132
|
+
exit 1
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
rescue StandardError => e
|
137
|
+
puts "๐ฅ Unexpected error: #{e.message}"
|
138
|
+
puts e.backtrace.first(5).join("\n")
|
139
|
+
exit 1
|
140
|
+
end
|
141
|
+
|
142
|
+
if __FILE__ == $0
|
143
|
+
# Allow custom filename as command line argument
|
144
|
+
filename = ARGV[0] || "group_export_#{Time.now.strftime('%Y%m%d_%H%M%S')}.csv"
|
145
|
+
export_groups_to_csv(filename)
|
146
|
+
end
|