mangoapps-ex-sdk-ruby 19.1.1 โ 19.1.2
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 +4 -1039
- data/lib/mangoapps/client.rb +24 -14
- data/lib/mangoapps/config.rb +3 -2
- data/lib/mangoapps/modules/feeds/feeds.rb +2 -2
- data/lib/mangoapps/modules/learn/course_catalog.rb +2 -2
- data/lib/mangoapps/modules/learn/course_details.rb +2 -2
- data/lib/mangoapps/modules/learn/my_learning.rb +2 -2
- data/lib/mangoapps/modules/notifications/my_priority_items.rb +2 -2
- data/lib/mangoapps/modules/posts/get_post_by_id.rb +2 -2
- data/lib/mangoapps/modules/recognitions/core_value_tags.rb +2 -2
- data/lib/mangoapps/modules/recognitions/get_profile_awards.rb +2 -2
- data/lib/mangoapps/modules/recognitions/leaderboard_info.rb +2 -2
- data/lib/mangoapps/modules/tasks/get_task_details.rb +2 -2
- data/lib/mangoapps/modules/users.rb +2 -2
- data/lib/mangoapps/modules/wikis/get_wiki_details.rb +2 -2
- data/lib/mangoapps/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -1,25 +1,7 @@
|
|
1
1
|
# MangoApps Ruby SDK
|
2
2
|
|
3
|
-
A clean,
|
4
|
-
|
5
|
-
## Features
|
6
|
-
|
7
|
-
- ๐ **OAuth2/OpenID Connect** authentication with automatic token refresh and userinfo endpoint
|
8
|
-
- ๐ **Internal API Authentication** - Alternative authentication using API keys for server-to-server communication
|
9
|
-
- ๐ค **Automatic Authentication Detection** - Automatically detects and prioritizes Internal API over OAuth credentials
|
10
|
-
- ๐ **Pagination Support** - All list APIs support optional page and limit parameters for efficient data retrieval
|
11
|
-
- ๐ **Simple API** with intuitive method names and clean dot notation
|
12
|
-
- ๐งช **Real TDD** - no mocking, only actual OAuth testing
|
13
|
-
- ๐ **Automatic retries** with exponential backoff
|
14
|
-
- ๐ **Comprehensive error handling** with specific exception types
|
15
|
-
- ๐ก๏ธ **Security-first** design with PKCE support and HTTPS enforcement
|
16
|
-
- ๐ง **Environment variable configuration** for secure credentials
|
17
|
-
- ๐ **Well-documented** with examples and guides
|
18
|
-
- โจ **Clean Response API** - Automatic response wrapping with intuitive dot notation access
|
19
|
-
- ๐ **Notifications Module** - User priority items including requests, events, quizzes, surveys, tasks, and todos
|
20
|
-
- ๐ฐ **Feeds Module** - User activity feeds with unread counts and feed details
|
21
|
-
- ๐ **Posts Module** - Get all posts with filtering options and post management
|
22
|
-
- ๐ **HTTPS Always** - All OAuth endpoints use HTTPS with automatic redirect handling
|
3
|
+
A clean, Ruby SDK for MangoApps APIs with OAuth2/OpenID Connect authentication.
|
4
|
+
|
23
5
|
|
24
6
|
## Installation
|
25
7
|
|
@@ -41,83 +23,6 @@ Or install it directly:
|
|
41
23
|
gem install mangoapps-ex-sdk-ruby
|
42
24
|
```
|
43
25
|
|
44
|
-
**Current Version**: 0.15.2 (includes OAuth userinfo endpoint, HTTPS security enhancements, Internal API authentication, automatic authentication detection, and pagination support)
|
45
|
-
|
46
|
-
## Quick Start
|
47
|
-
|
48
|
-
### 1. Environment Setup
|
49
|
-
|
50
|
-
For testing purposes, create a `.env` file with your MangoApps credentials:
|
51
|
-
|
52
|
-
```bash
|
53
|
-
# .env (for testing only)
|
54
|
-
MANGOAPPS_DOMAIN=yourdomain.mangoapps.com
|
55
|
-
|
56
|
-
# OAuth2 Authentication (Option 1)
|
57
|
-
MANGOAPPS_CLIENT_ID=your_client_id_here
|
58
|
-
MANGOAPPS_CLIENT_SECRET=your_client_secret_here
|
59
|
-
MANGOAPPS_REDIRECT_URI=https://localhost:3000/oauth/callback
|
60
|
-
MANGOAPPS_SCOPE=openid profile email
|
61
|
-
|
62
|
-
# Internal API Authentication (Option 2 - Alternative to OAuth)
|
63
|
-
# Contact MangoApps support team to get your Internal API Key and Secret
|
64
|
-
MANGOAPPS_INTERNAL_API_KEY=your_internal_api_key
|
65
|
-
MANGOAPPS_INTERNAL_API_SECRET=your_internal_api_secret
|
66
|
-
```
|
67
|
-
|
68
|
-
**Note**: The `.env` file is only used for testing. In production, you should handle token storage and management according to your application's security requirements.
|
69
|
-
|
70
|
-
### 2. Rails Integration
|
71
|
-
|
72
|
-
For Rails applications, see our comprehensive [Rails OAuth Guide](RAILS_OAUTH_GUIDE.md) which includes:
|
73
|
-
|
74
|
-
- Simple OAuth 2.0 flow implementation
|
75
|
-
- Token storage and management
|
76
|
-
- OAuth userinfo endpoint integration
|
77
|
-
- HTTPS security enforcement
|
78
|
-
- Complete callback handling
|
79
|
-
|
80
|
-
### 3. Configuration
|
81
|
-
|
82
|
-
```ruby
|
83
|
-
require "mangoapps"
|
84
|
-
|
85
|
-
# For testing - automatically loads from .env file and detects authentication method
|
86
|
-
config = MangoApps::Config.new
|
87
|
-
# Output: ๐ Using Internal API authentication (if internal API credentials found)
|
88
|
-
# Output: ๐ Using OAuth2 authentication (if OAuth credentials found)
|
89
|
-
|
90
|
-
# For production - OAuth2 configuration
|
91
|
-
config = MangoApps::Config.new(
|
92
|
-
domain: "yourdomain.mangoapps.com",
|
93
|
-
client_id: "your_client_id",
|
94
|
-
client_secret: "your_client_secret",
|
95
|
-
redirect_uri: "https://localhost:3000/oauth/callback",
|
96
|
-
scope: "openid profile email"
|
97
|
-
)
|
98
|
-
client = MangoApps::Client.new(config)
|
99
|
-
|
100
|
-
# For production - Internal API configuration (Alternative to OAuth)
|
101
|
-
# Note: Contact MangoApps support team to get your Internal API Key and Secret
|
102
|
-
config = MangoApps::Config.new(
|
103
|
-
domain: "yourdomain.mangoapps.com",
|
104
|
-
internal_api_key: "your_internal_api_key",
|
105
|
-
internal_api_secret: "your_internal_api_secret"
|
106
|
-
)
|
107
|
-
client = MangoApps::Client.new(config)
|
108
|
-
```
|
109
|
-
|
110
|
-
### 3. OAuth Authentication
|
111
|
-
|
112
|
-
#### Quick Start (Recommended)
|
113
|
-
```bash
|
114
|
-
# Get OAuth token (interactive)
|
115
|
-
./run_auth.sh
|
116
|
-
|
117
|
-
# Run tests to verify everything works
|
118
|
-
./run_tests.sh
|
119
|
-
```
|
120
|
-
|
121
26
|
#### Basic Usage Example
|
122
27
|
```ruby
|
123
28
|
require 'mangoapps-ex-sdk-ruby'
|
@@ -220,92 +125,7 @@ if wikis.wikis.any?
|
|
220
125
|
end
|
221
126
|
```
|
222
127
|
|
223
|
-
|
224
|
-
```ruby
|
225
|
-
# Generate authorization URL
|
226
|
-
state = SecureRandom.hex(16)
|
227
|
-
auth_url = client.authorization_url(state: state)
|
228
|
-
puts "Open this URL to authorize: #{auth_url}"
|
229
|
-
|
230
|
-
# After user authorizes, exchange code for tokens
|
231
|
-
tokens = client.authenticate!(authorization_code: params[:code])
|
232
|
-
|
233
|
-
# Store tokens securely in your application
|
234
|
-
# (implementation depends on your storage solution)
|
235
|
-
store_tokens(tokens.access_token, tokens.refresh_token)
|
236
|
-
|
237
|
-
# Now you can make API calls with clean dot notation
|
238
|
-
user = client.me
|
239
|
-
puts "Welcome, #{user.user_profile.minimal_profile.name}!"
|
240
|
-
|
241
|
-
# Get OAuth user info from userinfo endpoint
|
242
|
-
userinfo = client.get_userinfo
|
243
|
-
puts "OAuth User: #{userinfo.name} (#{userinfo.email})"
|
244
|
-
puts "Subject ID: #{userinfo.sub}"
|
245
|
-
puts "Username: #{userinfo.preferred_username}"
|
246
|
-
```
|
247
|
-
|
248
|
-
#### OAuth Userinfo Endpoint
|
249
|
-
|
250
|
-
The SDK provides access to the OAuth userinfo endpoint for getting authenticated user information:
|
251
|
-
|
252
|
-
```ruby
|
253
|
-
# Get user info from OAuth userinfo endpoint
|
254
|
-
userinfo = client.get_userinfo
|
255
|
-
|
256
|
-
# Access OAuth user data with clean dot notation
|
257
|
-
puts "Name: #{userinfo.name}"
|
258
|
-
puts "Email: #{userinfo.email}"
|
259
|
-
puts "Subject ID: #{userinfo.sub}"
|
260
|
-
puts "Username: #{userinfo.preferred_username}"
|
261
|
-
|
262
|
-
# Available OAuth userinfo fields:
|
263
|
-
# - sub: Subject identifier (unique user ID)
|
264
|
-
# - name: Full name
|
265
|
-
# - email: Email address
|
266
|
-
# - preferred_username: Username
|
267
|
-
# - email_verified: Email verification status
|
268
|
-
# - locale: User locale
|
269
|
-
# - zoneinfo: Timezone information
|
270
|
-
```
|
271
|
-
|
272
|
-
#### HTTPS Security Features
|
273
|
-
|
274
|
-
The SDK enforces HTTPS for all OAuth operations:
|
275
|
-
|
276
|
-
```ruby
|
277
|
-
# Automatic HTTPS enforcement
|
278
|
-
# - Discovery endpoints always use HTTPS
|
279
|
-
# - Userinfo endpoints always use HTTPS
|
280
|
-
# - Automatic redirect handling (301/302)
|
281
|
-
# - SSL certificate verification
|
282
|
-
|
283
|
-
# Example: Even if discovery returns HTTP URLs, they're converted to HTTPS
|
284
|
-
config = MangoApps::Config.new(domain: "example.mangoapps.com")
|
285
|
-
client = MangoApps::Client.new(config)
|
286
|
-
|
287
|
-
# This will automatically use HTTPS
|
288
|
-
userinfo = client.get_userinfo
|
289
|
-
```
|
290
|
-
|
291
|
-
### 4. Automatic Authentication Detection
|
292
|
-
|
293
|
-
The SDK automatically detects and prioritizes authentication methods:
|
294
|
-
|
295
|
-
1. **Internal API Credentials** (highest priority) - If `MANGOAPPS_INTERNAL_API_KEY` and `MANGOAPPS_INTERNAL_API_SECRET` are found
|
296
|
-
2. **OAuth Credentials** (fallback) - If `MANGOAPPS_CLIENT_ID` and `MANGOAPPS_CLIENT_SECRET` are found
|
297
|
-
|
298
|
-
```ruby
|
299
|
-
# Automatic detection - no configuration needed
|
300
|
-
config = MangoApps::Config.new
|
301
|
-
# Shows: ๐ Using Internal API authentication (if internal API found)
|
302
|
-
# Shows: ๐ Using OAuth2 authentication (if OAuth found)
|
303
|
-
|
304
|
-
client = MangoApps::Client.new(config)
|
305
|
-
# All API calls work automatically with detected authentication method
|
306
|
-
```
|
307
|
-
|
308
|
-
### 5. Pagination Support
|
128
|
+
### Pagination Support
|
309
129
|
|
310
130
|
Most list APIs support optional pagination parameters for efficient data retrieval:
|
311
131
|
|
@@ -337,803 +157,6 @@ items = client.get_library_items(library_id, category_id, offset: 0, limit: 15)
|
|
337
157
|
- Tasks: `page: 1, limit: 5` (smaller default for task management)
|
338
158
|
- Posts: `offset: 0, limit: 20` with `filter_by: "all"`
|
339
159
|
|
340
|
-
### 6. Internal API Authentication (Alternative to OAuth)
|
341
|
-
|
342
|
-
For applications that need direct API access without OAuth flow, you can use internal API authentication:
|
343
|
-
|
344
|
-
> **๐ Getting API Credentials**: Contact the MangoApps support team to obtain your Internal API Key and Secret for server-to-server authentication.
|
345
|
-
|
346
|
-
```ruby
|
347
|
-
# Configure with internal API credentials
|
348
|
-
config = MangoApps::Config.new(
|
349
|
-
domain: "yourdomain.mangoapps.com",
|
350
|
-
internal_api_key: "your_internal_api_key",
|
351
|
-
internal_api_secret: "your_internal_api_secret",
|
352
|
-
)
|
353
|
-
client = MangoApps::Client.new(config)
|
354
|
-
|
355
|
-
# Use the SDK normally - authentication is handled automatically
|
356
|
-
user = client.me
|
357
|
-
puts "Hello, #{user.user_profile.minimal_profile.name}!"
|
358
|
-
|
359
|
-
# Get user info (uses /me endpoint for internal API)
|
360
|
-
userinfo = client.get_userinfo
|
361
|
-
puts "User: #{userinfo.name} (#{userinfo.email})"
|
362
|
-
|
363
|
-
# All other API calls work the same way
|
364
|
-
posts = client.get_all_posts
|
365
|
-
notifications = client.notifications
|
366
|
-
```
|
367
|
-
|
368
|
-
#### Internal API Headers
|
369
|
-
|
370
|
-
The SDK automatically adds the required headers for internal API authentication:
|
371
|
-
|
372
|
-
```ruby
|
373
|
-
# These headers are automatically added to all requests:
|
374
|
-
# - Internal-Api-Key: your_api_key
|
375
|
-
# - Internal-Api-Secret: your_api_secret
|
376
|
-
```
|
377
|
-
|
378
|
-
#### When to Use Internal API vs OAuth
|
379
|
-
|
380
|
-
- **OAuth2**: Use for user-facing applications where users need to authenticate
|
381
|
-
- **Internal API**: Use for server-to-server communication, automation, or internal tools
|
382
|
-
|
383
|
-
## Response Format
|
384
|
-
|
385
|
-
The SDK automatically wraps all API responses in a `MangoApps::Response` object that provides clean dot notation access:
|
386
|
-
|
387
|
-
```ruby
|
388
|
-
# Clean dot notation access (automatic response wrapping):
|
389
|
-
user = client.me
|
390
|
-
name = user.user_profile.minimal_profile.name
|
391
|
-
email = user.user_profile.minimal_profile.email
|
392
|
-
```
|
393
|
-
|
394
|
-
### Response Features
|
395
|
-
|
396
|
-
- **๐ฏ Dot Notation Access**: `response.user.name` for clean, intuitive API access
|
397
|
-
- **๐ Automatic Wrapping**: All responses are automatically wrapped in `MangoApps::Response`
|
398
|
-
- **๐ Hash Compatibility**: Still supports `[]` access if needed
|
399
|
-
- **๐ Enumerable Support**: Arrays and hashes work as expected
|
400
|
-
- **๐ Raw Data Access**: Use `response.raw_data` for original response
|
401
|
-
- **โก Type Safety**: Better IDE support and autocomplete
|
402
|
-
- **๐จ Clean Code**: No more verbose nested hash access
|
403
|
-
|
404
|
-
## API Resources
|
405
|
-
|
406
|
-
### Users Module
|
407
|
-
|
408
|
-
```ruby
|
409
|
-
# Get current user profile
|
410
|
-
user = client.me
|
411
|
-
|
412
|
-
# Access user data with clean dot notation
|
413
|
-
puts "User: #{user.user_profile.minimal_profile.name}"
|
414
|
-
puts "Email: #{user.user_profile.minimal_profile.email}"
|
415
|
-
puts "Points: #{user.user_profile.gamification.total_points}"
|
416
|
-
puts "Followers: #{user.user_profile.user_data.followers}"
|
417
|
-
```
|
418
|
-
|
419
|
-
### Learn Module
|
420
|
-
|
421
|
-
#### Course Catalog
|
422
|
-
```ruby
|
423
|
-
# Get course catalog
|
424
|
-
courses = client.course_catalog
|
425
|
-
|
426
|
-
# Access course data with clean dot notation
|
427
|
-
courses.courses.each do |course|
|
428
|
-
puts "#{course.name} - #{course.course_type}"
|
429
|
-
end
|
430
|
-
```
|
431
|
-
|
432
|
-
#### Course Categories
|
433
|
-
```ruby
|
434
|
-
# Get all course categories (no pagination)
|
435
|
-
categories = client.course_categories
|
436
|
-
|
437
|
-
# Access category data with clean dot notation
|
438
|
-
categories.all_categories.each do |category|
|
439
|
-
puts "#{category.name} - Position: #{category.position}"
|
440
|
-
end
|
441
|
-
```
|
442
|
-
|
443
|
-
#### Course Details
|
444
|
-
```ruby
|
445
|
-
# Get detailed course information by course ID
|
446
|
-
course_id = 604
|
447
|
-
course = client.course_details(course_id)
|
448
|
-
|
449
|
-
# Access course data with clean dot notation
|
450
|
-
course_data = course.course
|
451
|
-
puts "Course: #{course_data.name} (ID: #{course_data.id})"
|
452
|
-
puts "Description: #{course_data.description}"
|
453
|
-
puts "Type: #{course_data.course_type}"
|
454
|
-
puts "Delivery Mode: #{course_data.delivery_mode}"
|
455
|
-
puts "Instructors: #{course_data.instructors.length}"
|
456
|
-
puts "Fields: #{course_data.fields.length}"
|
457
|
-
|
458
|
-
# Access course URLs
|
459
|
-
puts "Start Course URL: #{course_data.start_course_url}"
|
460
|
-
puts "Go to Course URL: #{course_data.goto_course_url}"
|
461
|
-
|
462
|
-
# Access course fields (details, certification, etc.)
|
463
|
-
course_data.fields.each do |field|
|
464
|
-
puts "Field: #{field.field_name}"
|
465
|
-
field.course_sub_fields.each do |sub_field|
|
466
|
-
puts " #{sub_field.field_name}: #{sub_field.field_value}"
|
467
|
-
end
|
468
|
-
end
|
469
|
-
```
|
470
|
-
|
471
|
-
#### My Learning
|
472
|
-
```ruby
|
473
|
-
# Get user's learning progress and courses
|
474
|
-
learning = client.my_learning
|
475
|
-
|
476
|
-
# Access user learning data with clean dot notation
|
477
|
-
puts "User: #{learning.user_name} (ID: #{learning.user_id})"
|
478
|
-
puts "Total training time: #{learning.total_training_time}"
|
479
|
-
puts "Ongoing courses: #{learning.ongoing_course_count}"
|
480
|
-
puts "Completed courses: #{learning.completed_course_count}"
|
481
|
-
puts "Registered courses: #{learning.registered_course_count}"
|
482
|
-
|
483
|
-
# Access learning sections
|
484
|
-
learning.section.each do |section|
|
485
|
-
puts "#{section.label} - #{section.count} courses"
|
486
|
-
|
487
|
-
# Access courses in each section
|
488
|
-
section.courses.each do |course|
|
489
|
-
puts " ๐ #{course.name} - #{course.course_progress}% progress"
|
490
|
-
end
|
491
|
-
end
|
492
|
-
```
|
493
|
-
|
494
|
-
### Recognitions Module
|
495
|
-
|
496
|
-
#### Award Categories
|
497
|
-
```ruby
|
498
|
-
# Get award categories
|
499
|
-
categories = client.award_categories
|
500
|
-
|
501
|
-
# Access award category data with clean dot notation
|
502
|
-
categories.award_categories.each do |category|
|
503
|
-
puts "#{category.name} (ID: #{category.id}) - Permission: #{category.recipient_permission}"
|
504
|
-
end
|
505
|
-
```
|
506
|
-
|
507
|
-
#### Core Value Tags
|
508
|
-
```ruby
|
509
|
-
# Get core value tags
|
510
|
-
tags = client.core_value_tags
|
511
|
-
|
512
|
-
# Access core value tag data with clean dot notation
|
513
|
-
tags.core_value_tags.each do |tag|
|
514
|
-
puts "#{tag.name} (ID: #{tag.id}) - Color: ##{tag.color}"
|
515
|
-
end
|
516
|
-
```
|
517
|
-
|
518
|
-
#### Leaderboard Info
|
519
|
-
```ruby
|
520
|
-
# Get leaderboard information
|
521
|
-
leaderboard = client.leaderboard_info
|
522
|
-
|
523
|
-
# Check if leaderboard data is available
|
524
|
-
if leaderboard.leaderboard_info
|
525
|
-
# Access user leaderboard with clean dot notation
|
526
|
-
leaderboard.leaderboard_info.user_info.each do |user|
|
527
|
-
puts "๐
#{user.name} (Rank: #{user.rank}) - Awards: #{user.award_count}"
|
528
|
-
end
|
529
|
-
|
530
|
-
# Access team leaderboard with clean dot notation
|
531
|
-
leaderboard.leaderboard_info.team_info.each do |team|
|
532
|
-
puts "๐ #{team.name} (Rank: #{team.rank}) - Awards: #{team.award_count}"
|
533
|
-
end
|
534
|
-
else
|
535
|
-
puts "No leaderboard data configured"
|
536
|
-
end
|
537
|
-
```
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
#### Get Awards List
|
542
|
-
```ruby
|
543
|
-
# Get awards list for a specific category
|
544
|
-
response = client.get_awards_list(category_id: 4303)
|
545
|
-
|
546
|
-
# Access award data with clean dot notation
|
547
|
-
response.get_awards_list.each do |award|
|
548
|
-
puts "#{award.name} (ID: #{award.id})"
|
549
|
-
puts " Description: #{award.description}"
|
550
|
-
puts " Points: #{award.points}"
|
551
|
-
puts " Reward Points: #{award.reward_points}"
|
552
|
-
puts " Image: #{award.attachment_url}"
|
553
|
-
end
|
554
|
-
```
|
555
|
-
|
556
|
-
#### Get Profile Awards
|
557
|
-
```ruby
|
558
|
-
# Get user profile awards
|
559
|
-
response = client.get_profile_awards
|
560
|
-
|
561
|
-
# Access core value tags with counts
|
562
|
-
response.core_value_tags.each do |tag|
|
563
|
-
puts "#{tag.name} (ID: #{tag.id}) - Count: #{tag.count}"
|
564
|
-
end
|
565
|
-
|
566
|
-
# Access award feeds
|
567
|
-
response.feeds.each do |feed|
|
568
|
-
puts "#{feed.feed_property.title} - Points: #{feed.recognition_points}"
|
569
|
-
puts "From: #{feed.from_user.name}"
|
570
|
-
puts "Body: #{feed.body}"
|
571
|
-
end
|
572
|
-
```
|
573
|
-
|
574
|
-
|
575
|
-
#### My Priority Items
|
576
|
-
```ruby
|
577
|
-
# Get user's priority items
|
578
|
-
response = client.my_priority_items
|
579
|
-
|
580
|
-
# Access priority items data
|
581
|
-
response.data.each do |item|
|
582
|
-
puts "#{item.title} (ID: #{item.id}) - Count: #{item.count}"
|
583
|
-
puts " Action Type: #{item.action_type}"
|
584
|
-
puts " Icon: #{item.icon} (#{item.icon_color})"
|
585
|
-
puts " Details: #{item.info_details}"
|
586
|
-
end
|
587
|
-
|
588
|
-
# Check response status
|
589
|
-
puts "Success: #{response.success}"
|
590
|
-
puts "Display Type: #{response.display_type}"
|
591
|
-
```
|
592
|
-
|
593
|
-
#### Feeds
|
594
|
-
```ruby
|
595
|
-
# Get user's activity feeds
|
596
|
-
response = client.feeds
|
597
|
-
|
598
|
-
# Access feeds data
|
599
|
-
response.feeds.each do |feed|
|
600
|
-
puts "#{feed.feed_property.title} (ID: #{feed.id})"
|
601
|
-
puts " From: #{feed.from_user.name} | Group: #{feed.group_name}"
|
602
|
-
puts " Type: #{feed.feed_type} | Category: #{feed.category}"
|
603
|
-
puts " Created: #{Time.at(feed.created_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
604
|
-
puts " Unread: #{feed.unread}"
|
605
|
-
puts " Body: #{feed.body[0..100]}..."
|
606
|
-
end
|
607
|
-
|
608
|
-
# Access unread counts
|
609
|
-
puts "Unread feeds: #{response.unread_counts.unread_feeds_count}"
|
610
|
-
puts "Direct messages: #{response.unread_counts.direct_messages_count}"
|
611
|
-
puts "What's new: #{response.unread_counts.whats_new_count}"
|
612
|
-
|
613
|
-
# Check response metadata
|
614
|
-
puts "Limit: #{response.limit} | Version: #{response.mangoapps_version}"
|
615
|
-
```
|
616
|
-
|
617
|
-
#### Get All Posts
|
618
|
-
```ruby
|
619
|
-
# Get all posts with filtering
|
620
|
-
response = client.get_all_posts(filter_by: "all")
|
621
|
-
|
622
|
-
# Access posts data
|
623
|
-
response.feeds.each do |post|
|
624
|
-
puts "#{post.tile.tile_name} (ID: #{post.id})"
|
625
|
-
puts " From: #{post.from_user.name} | Group: #{post.group_name}"
|
626
|
-
puts " Post ID: #{post.post_id} | View count: #{post.total_view_count}"
|
627
|
-
puts " Created: #{Time.at(post.created_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
628
|
-
puts " Comments: #{post.comments.length} | Likes: #{post.like_count}"
|
629
|
-
puts " Content: #{post.tile.tile_content[0..100]}..."
|
630
|
-
end
|
631
|
-
|
632
|
-
# Access post configuration
|
633
|
-
puts "Post view count visibility: #{response.post_view_count_visibility}"
|
634
|
-
puts "Post view count link config: #{response.post_view_count_link_config}"
|
635
|
-
```
|
636
|
-
|
637
|
-
#### Get Post By ID
|
638
|
-
```ruby
|
639
|
-
# Get detailed post information by ID
|
640
|
-
post_id = 59101
|
641
|
-
response = client.get_post_by_id(post_id, full_description: "Y")
|
642
|
-
|
643
|
-
# Access post details
|
644
|
-
post = response.post
|
645
|
-
puts "#{post.title} (ID: #{post.id})"
|
646
|
-
puts " Created by: #{post.created_name} (ID: #{post.creator_by})"
|
647
|
-
puts " Created: #{Time.at(post.created_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
648
|
-
puts " Conversation: #{post.conversation_name}"
|
649
|
-
puts " View count: #{post.total_view_count} | Likes: #{post.like_count} | Comments: #{post.comment_count}"
|
650
|
-
|
651
|
-
# Access tile information
|
652
|
-
if post.tile
|
653
|
-
puts " Tile: #{post.tile.tile_name}"
|
654
|
-
puts " Full description: #{post.tile.tile_full_description[0..200]}..."
|
655
|
-
puts " Image: #{post.tile.tile_image}"
|
656
|
-
end
|
657
|
-
|
658
|
-
# Check post permissions
|
659
|
-
puts " Can edit: #{post.can_edit} | Can comment: #{post.can_comment} | Can delete: #{post.can_delete}"
|
660
|
-
puts " Is draft: #{post.is_draft} | Archived: #{post.archived}"
|
661
|
-
```
|
662
|
-
|
663
|
-
#### Libraries Management
|
664
|
-
```ruby
|
665
|
-
# Get user's document libraries
|
666
|
-
libraries = client.get_libraries
|
667
|
-
|
668
|
-
# Access libraries data
|
669
|
-
puts "๐ User Libraries:"
|
670
|
-
libraries.libraries.each do |library|
|
671
|
-
puts " โข #{library.name} (ID: #{library.id})"
|
672
|
-
puts " Type: #{library.library_type} | View: #{library.view_mode}"
|
673
|
-
puts " Items: #{library.total_items_count} | Categories: #{library.categories.length}"
|
674
|
-
puts " Edit access: #{library.edit_access} | Position: #{library.position}"
|
675
|
-
puts " Banner: #{library.banner_color} | Icon: #{library.icon_properties.color}"
|
676
|
-
|
677
|
-
# Access library categories
|
678
|
-
if library.categories.any?
|
679
|
-
puts " Categories:"
|
680
|
-
library.categories.first(3).each do |category|
|
681
|
-
puts " - #{category.name} (#{category.library_items_count} items)"
|
682
|
-
end
|
683
|
-
end
|
684
|
-
puts ""
|
685
|
-
end
|
686
|
-
```
|
687
|
-
|
688
|
-
#### Get Library Categories
|
689
|
-
```ruby
|
690
|
-
# Get detailed library information and categories by library ID
|
691
|
-
library_id = 9776
|
692
|
-
response = client.get_library_categories(library_id)
|
693
|
-
|
694
|
-
# Access library details
|
695
|
-
library = response.library
|
696
|
-
puts "#{library.name} (ID: #{library.id})"
|
697
|
-
puts " Type: #{library.library_type} | View: #{library.view_mode}"
|
698
|
-
puts " Description: #{library.description}"
|
699
|
-
puts " Total items: #{library.total_items_count} | Categories: #{library.categories.length}"
|
700
|
-
puts " Edit access: #{library.edit_access} | Position: #{library.position}"
|
701
|
-
|
702
|
-
# Access library properties
|
703
|
-
puts " Banner color: #{library.banner_color} | Icon color enabled: #{library.enable_icon_color}"
|
704
|
-
puts " Created: #{Time.at(library.created_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
705
|
-
puts " Updated: #{Time.at(library.updated_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
706
|
-
|
707
|
-
# Access icon properties
|
708
|
-
if library.icon_properties
|
709
|
-
puts " Icon color: #{library.icon_properties.color} | Icon class: #{library.icon_properties.class}"
|
710
|
-
end
|
711
|
-
|
712
|
-
# Access categories
|
713
|
-
if library.categories.any?
|
714
|
-
puts " Categories:"
|
715
|
-
library.categories.each do |category|
|
716
|
-
puts " โข #{category.name} (ID: #{category.id})"
|
717
|
-
puts " Items: #{category.library_items_count} | Rank: #{category.rank}"
|
718
|
-
puts " Is system: #{category.is_system} | Icon: #{category.icon || 'None'}"
|
719
|
-
if category.description
|
720
|
-
puts " Description: #{category.description[0..100]}..."
|
721
|
-
end
|
722
|
-
end
|
723
|
-
end
|
724
|
-
```
|
725
|
-
|
726
|
-
#### Get Library Items
|
727
|
-
```ruby
|
728
|
-
# Get library items by library ID and category ID
|
729
|
-
library_id = 9776
|
730
|
-
category_id = 50114
|
731
|
-
response = client.get_library_items(library_id, category_id)
|
732
|
-
|
733
|
-
# Access library items data
|
734
|
-
puts "Category: #{response.category_name}"
|
735
|
-
puts "View mode: #{response.view_mode} | Library type: #{response.library_type}"
|
736
|
-
puts "Library ID: #{response.library_id} | Can add: #{response.can_add}"
|
737
|
-
puts "Icon color: #{response.enable_icon_color}"
|
738
|
-
|
739
|
-
# Access library items
|
740
|
-
if response.library_items.any?
|
741
|
-
puts "Library Items:"
|
742
|
-
response.library_items.each do |item|
|
743
|
-
puts " โข #{item.name} (ID: #{item.id})"
|
744
|
-
puts " Link type: #{item.link_type} | Link: #{item.link[0..50]}..."
|
745
|
-
|
746
|
-
# Handle different link types
|
747
|
-
if item.link_type == "ExternalLink"
|
748
|
-
if item.icon_properties
|
749
|
-
puts " Icon: #{item.icon_properties.color} | Class: #{item.icon_properties.class}"
|
750
|
-
end
|
751
|
-
elsif item.link_type == "Attachment"
|
752
|
-
puts " Attachment ID: #{item.attachment_id} | File type: #{item.file_type}"
|
753
|
-
puts " Likes: #{item.likes_count} | Is liked: #{item.is_liked}"
|
754
|
-
puts " Image: #{item.image_url}"
|
755
|
-
puts " Short URL: #{item.short_url[0..50]}..."
|
756
|
-
end
|
757
|
-
end
|
758
|
-
else
|
759
|
-
puts "No library items found"
|
760
|
-
end
|
761
|
-
```
|
762
|
-
|
763
|
-
#### Trackers Management
|
764
|
-
```ruby
|
765
|
-
# Get user's trackers
|
766
|
-
trackers = client.get_trackers
|
767
|
-
|
768
|
-
# Access trackers data
|
769
|
-
puts "๐ User Trackers:"
|
770
|
-
puts " Total trackers: #{trackers.trackers.length}"
|
771
|
-
puts " Transaction ID: #{trackers.transaction_id || 'None'}"
|
772
|
-
puts ""
|
773
|
-
|
774
|
-
# Display recent trackers
|
775
|
-
puts "๐ Recent Trackers:"
|
776
|
-
trackers.trackers.first(5).each do |tracker|
|
777
|
-
puts " โข #{tracker.name} (ID: #{tracker.id})"
|
778
|
-
puts " Last submission: #{Time.at(tracker.last_submission_date.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
779
|
-
puts " Conversation: #{tracker.conversation_name} (ID: #{tracker.conversation_id})"
|
780
|
-
puts " Pinned: #{tracker.is_pinned} | Can share: #{tracker.can_share}"
|
781
|
-
|
782
|
-
# Access tracker icon info
|
783
|
-
if tracker.tracker_icon_info
|
784
|
-
puts " Icon: #{tracker.tracker_icon_info.color_code} | Class: #{tracker.tracker_icon_info.icon_url}"
|
785
|
-
end
|
786
|
-
|
787
|
-
puts " MLink: #{tracker.mlink[0..50]}..."
|
788
|
-
puts ""
|
789
|
-
end
|
790
|
-
```
|
791
|
-
|
792
|
-
#### Attachments Management
|
793
|
-
```ruby
|
794
|
-
# Get user's folders
|
795
|
-
folders = client.get_folders
|
796
|
-
|
797
|
-
# Access folders data
|
798
|
-
puts "๐ User Folders:"
|
799
|
-
puts " Total folders: #{folders.folders.length}"
|
800
|
-
puts " Transaction ID: #{folders.transaction_id || 'None'}"
|
801
|
-
puts ""
|
802
|
-
|
803
|
-
# Display folders
|
804
|
-
puts "๐ Available Folders:"
|
805
|
-
folders.folders.each do |folder|
|
806
|
-
puts " โข #{folder.name} (ID: #{folder.id})"
|
807
|
-
puts " Path: #{folder.relativePath}"
|
808
|
-
puts " Child count: #{folder.child_count} | Can save: #{folder.can_save}"
|
809
|
-
puts " Pinned: #{folder.is_pinned} | Virtual: #{folder.is_virtual_folder}"
|
810
|
-
puts " Folder rel: #{folder.folder_rel} | Type: #{folder.folder_type_from_db || 'None'}"
|
811
|
-
puts " Show in upload: #{folder.show_in_upload} | Show in move: #{folder.show_in_move}"
|
812
|
-
puts " Filter: #{folder.filter} | Show permissions: #{folder.show_permission_options}"
|
813
|
-
|
814
|
-
# Show conversation and user IDs if available
|
815
|
-
if folder.conversation_id
|
816
|
-
puts " Conversation ID: #{folder.conversation_id}"
|
817
|
-
end
|
818
|
-
if folder.user_id
|
819
|
-
puts " User ID: #{folder.user_id}"
|
820
|
-
end
|
821
|
-
|
822
|
-
puts ""
|
823
|
-
end
|
824
|
-
```
|
825
|
-
|
826
|
-
#### File and Folder Management
|
827
|
-
```ruby
|
828
|
-
# Get user's folders first
|
829
|
-
folders = client.get_folders
|
830
|
-
|
831
|
-
# Find a folder with content
|
832
|
-
if folders.folders.any?
|
833
|
-
folder = folders.folders.find { |f| f.child_count.to_i > 0 }
|
834
|
-
|
835
|
-
if folder
|
836
|
-
puts "๐ Exploring folder: #{folder.name} (ID: #{folder.id})"
|
837
|
-
|
838
|
-
# Get files and folders inside this folder
|
839
|
-
folder_contents = client.get_folder_files(folder.id, include_folders: "Y")
|
840
|
-
|
841
|
-
puts "๐ Folder Contents:"
|
842
|
-
puts " Folder name: #{folder_contents.name}"
|
843
|
-
puts " Total count: #{folder_contents.total_count}"
|
844
|
-
puts " Role: #{folder_contents.role_name}"
|
845
|
-
puts " Domain suspended: #{folder_contents.is_domain_suspended}"
|
846
|
-
puts " Show in upload: #{folder_contents.show_in_upload}"
|
847
|
-
puts ""
|
848
|
-
|
849
|
-
# Display files and folders
|
850
|
-
puts "๐ Files and Folders:"
|
851
|
-
folder_contents.files.first(10).each do |item|
|
852
|
-
puts " โข #{item.filename} (ID: #{item.id})"
|
853
|
-
puts " Type: #{item.is_folder ? 'Folder' : 'File'}"
|
854
|
-
puts " Size: #{item.size} bytes"
|
855
|
-
puts " Uploader: #{item.uploader_name} (ID: #{item.user_id})"
|
856
|
-
puts " Updated: #{Time.at(item.updated_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
857
|
-
puts " Visibility: #{item.visibility} | Privacy: #{item.privacy_type}"
|
858
|
-
puts " Pinned: #{item.is_pinned} | Liked: #{item.is_liked}"
|
859
|
-
puts " Can save: #{item.can_save} | Show permissions: #{item.show_permission_options}"
|
860
|
-
|
861
|
-
# Show role permissions
|
862
|
-
if item.role
|
863
|
-
puts " Permissions: Edit: #{item.role.can_edit} | Share: #{item.role.can_share} | Restore: #{item.role.can_restore}"
|
864
|
-
end
|
865
|
-
|
866
|
-
# Show links
|
867
|
-
if item.mLink
|
868
|
-
puts " MLink: #{item.mLink[0..50]}..."
|
869
|
-
end
|
870
|
-
|
871
|
-
puts ""
|
872
|
-
end
|
873
|
-
else
|
874
|
-
puts "No folders with content found"
|
875
|
-
end
|
876
|
-
else
|
877
|
-
puts "No folders found"
|
878
|
-
end
|
879
|
-
```
|
880
|
-
|
881
|
-
#### Task Management
|
882
|
-
```ruby
|
883
|
-
# Get user's tasks with filtering and pagination
|
884
|
-
tasks = client.get_tasks(filter: "Pending_Tasks", page: 1, limit: 5)
|
885
|
-
|
886
|
-
# Access tasks data
|
887
|
-
puts "๐ User Tasks:"
|
888
|
-
puts " Total tasks: #{tasks.tasks.task.length}"
|
889
|
-
puts " Transaction ID: #{tasks.transaction_id || 'None'}"
|
890
|
-
puts ""
|
891
|
-
|
892
|
-
# Display tasks
|
893
|
-
puts "๐ Task List:"
|
894
|
-
tasks.tasks.task.each do |task|
|
895
|
-
puts " โข #{task.task_title} (ID: #{task.id})"
|
896
|
-
puts " Status: #{task.status} | Bucket: #{task.bucket}"
|
897
|
-
puts " Assigned to: #{task.assigned_to_name} (ID: #{task.assigned_to})"
|
898
|
-
puts " Created by: #{task.creator_name} (ID: #{task.creator_id})"
|
899
|
-
puts " Created: #{Time.at(task.created_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
900
|
-
puts " Assigned: #{Time.at(task.assigned_on.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
901
|
-
puts " Due: #{task.due} | Due on: #{task.due_on ? Time.at(task.due_on.to_i).strftime('%Y-%m-%d %H:%M:%S') : 'None'}"
|
902
|
-
puts " Is overdue: #{task.is_overdue} | Can be started: #{task.task_can_be_started}"
|
903
|
-
puts " Milestone: #{task.milestone_name || 'None'} (ID: #{task.milestone_id || 'None'})"
|
904
|
-
puts " Project: #{task.conversation_name} (ID: #{task.project_id})"
|
905
|
-
puts " Visibility: #{task.visibility} | Priority: #{task.personal_priority}"
|
906
|
-
|
907
|
-
# Show reviewers
|
908
|
-
if task.reviewers && task.reviewers.reviewer
|
909
|
-
reviewers = task.reviewers.reviewer
|
910
|
-
puts " Reviewers: #{reviewers.length} reviewers"
|
911
|
-
reviewers.first(3).each do |reviewer|
|
912
|
-
puts " - #{reviewer.user_name} (Status: #{reviewer.status})"
|
913
|
-
end
|
914
|
-
end
|
915
|
-
|
916
|
-
# Show next actions
|
917
|
-
if task.next_actions && task.next_actions.action
|
918
|
-
actions = task.next_actions.action
|
919
|
-
puts " Available actions: #{actions.join(', ')}"
|
920
|
-
end
|
921
|
-
|
922
|
-
# Show links
|
923
|
-
if task.mlink
|
924
|
-
puts " MLink: #{task.mlink[0..50]}..."
|
925
|
-
end
|
926
|
-
|
927
|
-
puts ""
|
928
|
-
end
|
929
|
-
```
|
930
|
-
|
931
|
-
#### Task Details Management
|
932
|
-
```ruby
|
933
|
-
# Get detailed information for a specific task
|
934
|
-
task_details = client.get_task_details("394153")
|
935
|
-
|
936
|
-
# Access task details data
|
937
|
-
puts "๐ Task Details:"
|
938
|
-
puts " Task ID: #{task_details.task.id}"
|
939
|
-
puts " Title: #{task_details.task.task_title}"
|
940
|
-
puts " Status: #{task_details.task.status} | Bucket: #{task_details.task.bucket}"
|
941
|
-
puts " Assigned to: #{task_details.task.assigned_to_name} (ID: #{task_details.task.assigned_to})"
|
942
|
-
puts " Created by: #{task_details.task.creator_name} (ID: #{task_details.task.creator_id})"
|
943
|
-
puts " Created: #{Time.at(task_details.task.created_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
944
|
-
puts " Assigned: #{Time.at(task_details.task.assigned_on.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
945
|
-
puts " Due: #{task_details.task.due} | Due on: #{task_details.task.due_on ? Time.at(task_details.task.due_on.to_i).strftime('%Y-%m-%d %H:%M:%S') : 'None'}"
|
946
|
-
puts " Is overdue: #{task_details.task.is_overdue} | Can be started: #{task_details.task.task_can_be_started}"
|
947
|
-
puts " Milestone: #{task_details.task.milestone_name || 'None'} (ID: #{task_details.task.milestone_id || 'None'})"
|
948
|
-
puts " Project: #{task_details.task.conversation_name} (ID: #{task_details.task.project_id})"
|
949
|
-
puts " Visibility: #{task_details.task.visibility} | Priority: #{task_details.task.personal_priority}"
|
950
|
-
puts " Transaction ID: #{task_details.transaction_id || 'None'}"
|
951
|
-
puts ""
|
952
|
-
|
953
|
-
# Show task timeline
|
954
|
-
if task_details.task.started_on
|
955
|
-
puts "๐
Started: #{Time.at(task_details.task.started_on.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
956
|
-
end
|
957
|
-
if task_details.task.finished_on
|
958
|
-
puts "๐
Finished: #{Time.at(task_details.task.finished_on.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
959
|
-
end
|
960
|
-
if task_details.task.delivered_on
|
961
|
-
puts "๐
Delivered: #{Time.at(task_details.task.delivered_on.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
962
|
-
end
|
963
|
-
|
964
|
-
# Show task history
|
965
|
-
if task_details.task.reopened_on
|
966
|
-
puts "๐
Reopened: #{Time.at(task_details.task.reopened_on.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
967
|
-
end
|
968
|
-
if task_details.task.restarted_on
|
969
|
-
puts "๐
Restarted: #{Time.at(task_details.task.restarted_on.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
970
|
-
end
|
971
|
-
|
972
|
-
# Show reviewers
|
973
|
-
if task_details.task.reviewers && task_details.task.reviewers.reviewer
|
974
|
-
reviewers = task_details.task.reviewers.reviewer
|
975
|
-
puts "๐ฅ Reviewers: #{reviewers.length} reviewers"
|
976
|
-
reviewers.first(5).each do |reviewer|
|
977
|
-
puts " - #{reviewer.user_name} (Status: #{reviewer.status})"
|
978
|
-
end
|
979
|
-
end
|
980
|
-
|
981
|
-
# Show next actions
|
982
|
-
if task_details.task.next_actions && task_details.task.next_actions.action
|
983
|
-
actions = task_details.task.next_actions.action
|
984
|
-
puts "โก Available actions: #{actions.join(', ')}"
|
985
|
-
end
|
986
|
-
|
987
|
-
# Show task content
|
988
|
-
if task_details.task.name
|
989
|
-
puts "๐ Task content: #{task_details.task.name[0..200]}..."
|
990
|
-
end
|
991
|
-
if task_details.task.notes
|
992
|
-
puts "๐ Notes: #{task_details.task.notes[0..200]}..."
|
993
|
-
end
|
994
|
-
|
995
|
-
# Show links
|
996
|
-
if task_details.task.mlink
|
997
|
-
puts "๐ MLink: #{task_details.task.mlink}"
|
998
|
-
end
|
999
|
-
|
1000
|
-
# Show attachments
|
1001
|
-
if task_details.task.attachments
|
1002
|
-
puts "๐ Attachments: #{task_details.task.attachments.length} attachments"
|
1003
|
-
end
|
1004
|
-
if task_details.task.attachment_references
|
1005
|
-
puts "๐ Attachment references: #{task_details.task.attachment_references.length} references"
|
1006
|
-
end
|
1007
|
-
```
|
1008
|
-
|
1009
|
-
#### Wiki Management
|
1010
|
-
```ruby
|
1011
|
-
# Get user's wikis with filtering and pagination
|
1012
|
-
wikis = client.get_wikis(mode: "my", limit: 20, offset: 0)
|
1013
|
-
|
1014
|
-
# Access wikis data
|
1015
|
-
puts "๐ User Wikis:"
|
1016
|
-
puts " Total wikis: #{wikis.wikis.length}"
|
1017
|
-
puts " Transaction ID: #{wikis.transaction_id || 'None'}"
|
1018
|
-
puts ""
|
1019
|
-
|
1020
|
-
# Display wikis
|
1021
|
-
puts "๐ Wiki List:"
|
1022
|
-
wikis.wikis.each do |wiki|
|
1023
|
-
puts " โข #{wiki.title} (ID: #{wiki.id})"
|
1024
|
-
puts " Updated: #{Time.at(wiki.updated_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
1025
|
-
puts " Children: #{wiki.children_count} | Can edit: #{wiki.can_edit}"
|
1026
|
-
puts " Conversation: #{wiki.conversation_name || 'None'} (ID: #{wiki.conversation_id})"
|
1027
|
-
puts " Is draft: #{wiki.is_draft} | PDF access: #{wiki.generate_pdf_access}"
|
1028
|
-
puts " User: #{wiki.user_name || 'None'} | Status: #{wiki.status || 'None'}"
|
1029
|
-
puts " Governance enabled: #{wiki.governance_enabled} | Governance date: #{wiki.governance_date || 'None'}"
|
1030
|
-
|
1031
|
-
# Show icon properties
|
1032
|
-
if wiki.icon_properties
|
1033
|
-
background_color = wiki.icon_properties.respond_to?(:'background-color') ? wiki.icon_properties.send(:'background-color') : nil
|
1034
|
-
puts " Icon: #{wiki.icon_properties.class} | Color: #{background_color || 'None'}"
|
1035
|
-
end
|
1036
|
-
|
1037
|
-
# Show user image URL
|
1038
|
-
if wiki.user_image_url
|
1039
|
-
puts " User image: #{wiki.user_image_url[0..50]}..."
|
1040
|
-
end
|
1041
|
-
|
1042
|
-
puts ""
|
1043
|
-
end
|
1044
|
-
```
|
1045
|
-
|
1046
|
-
#### Wiki Details Management
|
1047
|
-
```ruby
|
1048
|
-
# Get detailed information for a specific wiki
|
1049
|
-
wiki_details = client.get_wiki_details("7212")
|
1050
|
-
|
1051
|
-
# Access wiki details data
|
1052
|
-
puts "๐ Wiki Details:"
|
1053
|
-
puts " Wiki ID: #{wiki_details.wiki.details.id}"
|
1054
|
-
puts " Title: #{wiki_details.wiki.details.title}"
|
1055
|
-
puts " Status: #{wiki_details.wiki.details.status} | Platform: #{wiki_details.wiki.details.platform}"
|
1056
|
-
puts " Created: #{Time.at(wiki_details.wiki.details.created_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
1057
|
-
puts " Updated: #{Time.at(wiki_details.wiki.details.updated_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
|
1058
|
-
puts " Modified: #{wiki_details.wiki.details.modified_on}"
|
1059
|
-
puts " Created by: #{wiki_details.wiki.details.created_by_name} (ID: #{wiki_details.wiki.details.user_id})"
|
1060
|
-
puts " Updated by: #{wiki_details.wiki.details.updated_by_name} (ID: #{wiki_details.wiki.details.last_updated_by})"
|
1061
|
-
puts " Conversation: #{wiki_details.wiki.details.conversation_name} (ID: #{wiki_details.wiki.details.conversation_id})"
|
1062
|
-
puts " Read count: #{wiki_details.wiki.details.total_read_count} | Children: #{wiki_details.wiki.details.children_count}"
|
1063
|
-
puts " Edit permissions: #{wiki_details.wiki.details.edit_permissions} | Commentable: #{wiki_details.wiki.details.is_commentable}"
|
1064
|
-
puts " Generate PDF access: #{wiki_details.wiki.details.generate_pdf_access} | Show TOC: #{wiki_details.wiki.details.show_toc}"
|
1065
|
-
puts " Has TOC: #{wiki_details.wiki.details.has_toc} | Archived: #{wiki_details.wiki.details.archived}"
|
1066
|
-
puts " Domain ID: #{wiki_details.wiki.details.domain_id} | Feed ID: #{wiki_details.wiki.details.feed_id}"
|
1067
|
-
puts ""
|
1068
|
-
|
1069
|
-
# Show wiki content
|
1070
|
-
if wiki_details.wiki.details.description
|
1071
|
-
puts "๐ Description: #{wiki_details.wiki.details.description[0..300]}..."
|
1072
|
-
end
|
1073
|
-
|
1074
|
-
# Show banner URL
|
1075
|
-
if wiki_details.wiki.details.banner_url
|
1076
|
-
puts "๐ผ๏ธ Banner URL: #{wiki_details.wiki.details.banner_url}"
|
1077
|
-
end
|
1078
|
-
|
1079
|
-
# Show wiki permissions
|
1080
|
-
puts "๐ Wiki Permissions:"
|
1081
|
-
puts " Can comment: #{wiki_details.wiki.can_comment}"
|
1082
|
-
puts " Can edit: #{wiki_details.wiki.can_edit}"
|
1083
|
-
puts " Can delete: #{wiki_details.wiki.can_delete}"
|
1084
|
-
puts " Can rename: #{wiki_details.wiki.can_rename}"
|
1085
|
-
puts " Can move: #{wiki_details.wiki.can_move}"
|
1086
|
-
puts " Can duplicate: #{wiki_details.wiki.can_duplicate}"
|
1087
|
-
|
1088
|
-
# Show wiki links
|
1089
|
-
if wiki_details.wiki.mlink
|
1090
|
-
puts "๐ MLink: #{wiki_details.wiki.mlink}"
|
1091
|
-
end
|
1092
|
-
|
1093
|
-
# Show attachments
|
1094
|
-
if wiki_details.wiki.attachments
|
1095
|
-
puts "๐ Attachments: #{wiki_details.wiki.attachments.length} attachments"
|
1096
|
-
end
|
1097
|
-
if wiki_details.wiki.attachment_references
|
1098
|
-
puts "๐ Attachment references: #{wiki_details.wiki.attachment_references.length} references"
|
1099
|
-
end
|
1100
|
-
|
1101
|
-
# Show reactions
|
1102
|
-
if wiki_details.wiki.reactions
|
1103
|
-
reactions = wiki_details.wiki.reactions
|
1104
|
-
puts "๐ Reactions: Like: #{reactions.like_count}, Superlike: #{reactions.superlike_count}"
|
1105
|
-
puts "๐ Reactions: Haha: #{reactions.haha_count}, Yay: #{reactions.yay_count}, Wow: #{reactions.wow_count}, Sad: #{reactions.sad_count}"
|
1106
|
-
puts "๐ค User reactions: Liked: #{reactions.liked}, Superliked: #{reactions.superliked}"
|
1107
|
-
end
|
1108
|
-
|
1109
|
-
# Show reaction data
|
1110
|
-
if wiki_details.wiki.reaction_data
|
1111
|
-
reaction_data = wiki_details.wiki.reaction_data
|
1112
|
-
puts "๐ Reaction data: #{reaction_data.length} reaction types"
|
1113
|
-
reaction_data.each do |reaction|
|
1114
|
-
puts " - #{reaction.label}: #{reaction.count} (Reacted: #{reaction.reacted})"
|
1115
|
-
end
|
1116
|
-
end
|
1117
|
-
|
1118
|
-
# Show comment count
|
1119
|
-
puts "๐ฌ Comment count: #{wiki_details.wiki.comment_count}"
|
1120
|
-
|
1121
|
-
# Show wiki status
|
1122
|
-
puts "๐ Is pinned: #{wiki_details.wiki.is_pinned}"
|
1123
|
-
puts "๐ Is draft: #{wiki_details.wiki.is_draft}"
|
1124
|
-
puts "๐ Governance enabled: #{wiki_details.wiki.governance_enabled}"
|
1125
|
-
|
1126
|
-
# Show hashtags
|
1127
|
-
if wiki_details.wiki.hashtags
|
1128
|
-
hashtags = wiki_details.wiki.hashtags
|
1129
|
-
puts "๐ท๏ธ Hashtags: #{hashtags.length} hashtags"
|
1130
|
-
hashtags.each do |hashtag|
|
1131
|
-
puts " - #{hashtag}"
|
1132
|
-
end
|
1133
|
-
end
|
1134
|
-
```
|
1135
|
-
|
1136
|
-
|
1137
160
|
## Available Modules
|
1138
161
|
|
1139
162
|
### โ
Currently Implemented
|
@@ -1737,64 +760,6 @@ config = MangoApps::Config.new(
|
|
1737
760
|
# - SSL certificate verification enabled
|
1738
761
|
```
|
1739
762
|
|
1740
|
-
|
1741
|
-
## Development
|
1742
|
-
|
1743
|
-
### For SDK Users
|
1744
|
-
|
1745
|
-
If you're using this SDK in your application, you only need:
|
1746
|
-
|
1747
|
-
1. **Install the gem**: `gem install mangoapps-ex-sdk-ruby`
|
1748
|
-
2. **Configure OAuth**: Set up your MangoApps OAuth credentials
|
1749
|
-
3. **Start coding**: Use the examples above
|
1750
|
-
|
1751
|
-
### For SDK Developers
|
1752
|
-
|
1753
|
-
If you're contributing to or extending this SDK, see our comprehensive developer documentation:
|
1754
|
-
|
1755
|
-
๐ **[DEVELOPER.md](DEVELOPER.md)** - Complete guide for SDK development including:
|
1756
|
-
- Adding new APIs and modules
|
1757
|
-
- Testing guidelines (real TDD approach)
|
1758
|
-
- Development workflow
|
1759
|
-
- Code style and standards
|
1760
|
-
- Module architecture
|
1761
|
-
- Error handling
|
1762
|
-
- Documentation standards
|
1763
|
-
- Release process
|
1764
|
-
|
1765
|
-
### Quick Development Setup
|
1766
|
-
|
1767
|
-
```bash
|
1768
|
-
git clone https://github.com/MangoAppsInc/mangoapps-ex-sdk-ruby.git
|
1769
|
-
cd mangoapps-ex-sdk-ruby
|
1770
|
-
cp .env.example .env
|
1771
|
-
# Edit .env with your MangoApps credentials (for testing only)
|
1772
|
-
bundle install
|
1773
|
-
```
|
1774
|
-
|
1775
|
-
### Testing the SDK
|
1776
|
-
|
1777
|
-
This SDK uses **real TDD** - no mocking, only actual OAuth testing:
|
1778
|
-
|
1779
|
-
```bash
|
1780
|
-
# Get OAuth token (first time or when expired)
|
1781
|
-
./run_auth.sh
|
1782
|
-
|
1783
|
-
# Run tests
|
1784
|
-
./run_tests.sh
|
1785
|
-
|
1786
|
-
# Run specific module tests
|
1787
|
-
./run_tests.sh learn
|
1788
|
-
./run_tests.sh users
|
1789
|
-
./run_tests.sh recognitions
|
1790
|
-
./run_tests.sh notifications
|
1791
|
-
./run_tests.sh feeds
|
1792
|
-
./run_tests.sh posts
|
1793
|
-
|
1794
|
-
# Interactive testing
|
1795
|
-
./run_irb.sh
|
1796
|
-
```
|
1797
|
-
|
1798
763
|
### Current API Coverage
|
1799
764
|
|
1800
765
|
- โ
**Learn Module**: Course catalog, categories, course details, and my learning (4 endpoints)
|
@@ -1838,4 +803,4 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
1838
803
|
|
1839
804
|
## Changelog
|
1840
805
|
|
1841
|
-
See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.
|
806
|
+
See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.
|