MangoApps Ruby SDK
A clean, Ruby SDK for MangoApps APIs with OAuth2/OpenID Connect authentication.
Installation
Add this line to your application's Gemfile:
gem "mangoapps-ex-sdk-ruby"
And then execute:
bundle install
Or install it directly:
gem install mangoapps-ex-sdk-ruby
Basic Usage Example
require 'mangoapps-ex-sdk-ruby'
# Initialize client
client = MangoApps::Client.new
# Get user profile
user = client.me
puts "Hello, #{user.name}!"
# Get OAuth user info (from OAuth userinfo endpoint)
userinfo = client.get_userinfo
puts "OAuth User: #{userinfo.name} (#{userinfo.email})"
puts "Username: #{userinfo.preferred_username}"
puts "Subject ID: #{userinfo.sub}"
# Get priority items
priority_items = client.my_priority_items
puts "You have #{priority_items.data.length} priority items:"
priority_items.data.each do |item|
puts " • #{item.title}: #{item.count} pending"
end
# Get available courses
courses = client.course_catalog
puts "Available courses: #{courses.courses.length}"
# Get activity feeds
feeds = client.feeds(offset: 0, limit: 20, all_comments: 'Y')
puts "Activity feeds: #{feeds.feeds.length} (unread: #{feeds.unread_counts.unread_feeds_count})"
# Get all posts
posts = client.get_all_posts(filter_by: "all", offset: 0, limit: 20)
puts "All posts: #{posts.feeds.length}"
# Get post details by ID
if posts.feeds.any?
post_id = posts.feeds.first.post_id
post_details = client.get_post_by_id(post_id, full_description: "Y")
puts "Post details: #{post_details.post.title}"
end
# Get user libraries
libraries = client.get_libraries(offset: 0, limit: 20)
puts "User libraries: #{libraries.libraries.length}"
# Get library categories by ID
if libraries.libraries.any?
library_id = libraries.libraries.first.id
library_details = client.get_library_categories(library_id, offset: 0, limit: 20)
puts "Library details: #{library_details.library.name}"
# Get library items from first category
if library_details.library.categories.any?
category_id = library_details.library.categories.first.id
library_items = client.get_library_items(library_id, category_id, offset: 0, limit: 20)
puts "Library items: #{library_items.library_items.length} items in #{library_items.category_name}"
end
end
# Get user trackers
trackers = client.get_trackers(page: 1, limit: 20)
puts "User trackers: #{trackers.trackers.length}"
# Get user folders (no pagination)
folders = client.get_folders
puts "User folders: #{folders.folders.length}"
# Get files from first folder with content (no pagination)
if folders.folders.any?
folder_with_content = folders.folders.find { |f| f.child_count.to_i > 0 }
if folder_with_content
folder_files = client.get_folder_files(folder_with_content.id, include_folders: "Y")
puts "Folder files: #{folder_files.files.length} items in #{folder_files.name}"
end
end
# Get user tasks
tasks = client.get_tasks(filter: "Pending_Tasks", page: 1, limit: 3)
puts "User tasks: #{tasks.tasks.task.length}"
# Get detailed information for a specific task
if tasks.tasks.task.any?
first_task = tasks.tasks.task.first
task_id = first_task.is_a?(Array) ? first_task[1] : first_task.id
task_details = client.get_task_details(task_id)
puts "Task details: #{task_details.task.task_title} (Status: #{task_details.task.status})"
end
# Get user wikis
wikis = client.get_wikis(mode: "my", offset: 0, limit: 5)
puts "User wikis: #{wikis.wikis.length}"
# Get detailed information for the first wiki
if wikis.wikis.any?
first_wiki = wikis.wikis.first
wiki_details = client.get_wiki_details(first_wiki.id)
puts "Wiki details: #{wiki_details.wiki.details.title} (Read count: #{wiki_details.wiki.details.total_read_count})"
end
Pagination Support
Most list APIs support optional pagination parameters for efficient data retrieval:
# Basic usage with default pagination
posts = client.get_all_posts
courses = client.course_catalog
# Pagination with custom offset and limit (offset-based)
posts = client.get_all_posts(filter_by: "all", offset: 20, limit: 10)
courses = client.course_catalog(page: 1, limit: 5)
# Pagination with custom page and limit (page-based)
tasks = client.get_tasks(filter: "Pending_Tasks", page: 1, limit: 10)
trackers = client.get_trackers(page: 1, limit: 15)
# Library items with offset-based pagination
items = client.get_library_items(library_id, category_id, offset: 0, limit: 15)
Pagination Types:
- Offset-based APIs:
get_all_posts,get_libraries,get_library_categories,get_library_items,notifications,get_wikis,feeds - Page-based APIs:
course_catalog,get_tasks,get_trackers - Non-paginated APIs:
course_categories,award_categories,get_awards_list,get_folders,get_folder_files
Default Pagination Values:
- Offset-based:
offset: 0, limit: 20 - Page-based:
page: 1, limit: 20 - Tasks:
page: 1, limit: 5(smaller default for task management) - Posts:
offset: 0, limit: 20withfilter_by: "all"
Available Modules
✅ Currently Implemented
Users Module
- User Profile:
client.me- Get current user information with clean dot notation access
Learn Module
- Course Catalog:
client.course_catalog- Get available courses - Course Categories:
client.course_categories- Get course categories - Course Details:
client.course_details(course_id)- Get detailed course information by ID - My Learning:
client.my_learning- Get user's learning progress and courses
Recognitions Module
- Award Categories:
client.award_categories- Get recognition award categories - Get Awards List:
client.get_awards_list(category_id: id)- Get awards for a specific category - Get Profile Awards:
client.get_profile_awards- Get user's personal awards and activity - Core Value Tags:
client.core_value_tags- Get core value tags for recognition - Leaderboard Info:
client.leaderboard_info- Get user and team leaderboard information
Notifications Module
- My Priority Items:
client.my_priority_items- Get user's priority items including requests, events, quizzes, surveys, tasks, and todos - Notifications:
client.notifications- Get user's notifications with unread counts and detailed notification information
Feeds Module
- Feeds:
client.feeds- Get user's activity feeds with unread counts and feed details
Posts Module
- Get All Posts:
client.get_all_posts(filter_by: "all")- Get all posts with filtering options - Get Post By ID:
client.get_post_by_id(post_id, full_description: "Y")- Get detailed post information by ID
Libraries Module
- Get Libraries:
client.get_libraries- Get user's document libraries with categories and items - Get Library Categories:
client.get_library_categories(library_id)- Get detailed library information and categories by library ID - Get Library Items:
client.get_library_items(library_id, category_id)- Get library items by library ID and category ID
Trackers Module
- Get Trackers:
client.get_trackers- Get user's trackers with submission dates and conversation details
Attachments Module
- Get Folders:
client.get_folders- Get user's file folders with permissions and metadata - Get Folder Files:
client.get_folder_files(folder_id, include_folders: "Y")- Get files and folders inside a specific folder
Tasks Module
- Get Tasks:
client.get_tasks(filter: "Pending_Tasks", page: 1, limit: 5)- Get user's tasks with filtering, pagination, and detailed task information - Get Task Details:
client.get_task_details(task_id)- Get detailed information for a specific task by ID
Wikis Module
- Get Wikis:
client.get_wikis(mode: "my", limit: 20, offset: 0)- Get user's wikis with filtering, pagination, and detailed wiki information - Get Wiki Details:
client.get_wiki_details(wiki_id)- Get detailed information for a specific wiki by ID
Complete Examples
Notifications Management
require 'mangoapps-ex-sdk-ruby'
# Initialize client
client = MangoApps::Client.new
# Get user's priority items
priority_items = client.my_priority_items
# Display all priority items with details
puts "🔔 User Priority Items Dashboard"
puts "================================"
puts "Success: #{priority_items.success}"
puts "Display Type: #{priority_items.display_type}"
puts ""
priority_items.data.each do |item|
puts "📋 #{item.title} (ID: #{item.id})"
puts " Count: #{item.count} pending items"
puts " Action Type: #{item.action_type}"
puts " Icon: #{item.icon} (#{item.icon_color})"
puts " Background: #{item.icon_bg_color}"
puts " Description: #{item.info_details.gsub(/<[^>]*>/, '').strip[0..100]}..."
puts ""
end
# Get user's notifications
notifications = client.notifications
# Display notifications dashboard
puts "🔔 User Notifications Dashboard"
puts "==============================="
puts "What's new: #{notifications.whats_new_count}"
puts "Unread feeds: #{notifications.unread_feeds_count}"
puts "Mentions: #{notifications.mention_count}"
puts "Direct messages: #{notifications.}"
puts "Unread notifications: #{notifications.unread_notification_count}"
puts ""
notifications.notifications.first(5).each do |notification|
puts "📢 #{notification.sender_name} (ID: #{notification.id})"
puts " Text: #{notification.text[0..100]}..."
puts " Type: #{notification.notification_type || 'None'}"
puts " Read: #{notification.is_read} | Updated: #{Time.at(notification.updated_at.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
puts " MLink: #{notification.mlink || 'None'}"
if notification. && notification..any?
puts " Mentions: #{notification..map { |tag| tag.mention }.join(', ')}"
end
puts ""
end
# Filter by specific action types
approval_items = priority_items.data.select { |item| item.action_type == 'approval' }
puts "🔍 Approval Items: #{approval_items.length}"
approval_items.each do |item|
puts " • #{item.title}: #{item.count} items"
end
# Get high-priority items (count > 5)
high_priority = priority_items.data.select { |item| item.count > 5 }
puts "⚠️ High Priority Items: #{high_priority.length}"
high_priority.each do |item|
puts " • #{item.title}: #{item.count} items"
end
User Profile Management
# Get current user profile
user = client.me
# Access user information with clean dot notation
puts "Name: #{user.user_profile.minimal_profile.name}"
puts "Email: #{user.user_profile.minimal_profile.email}"
puts "User Type: #{user.user_profile.minimal_profile.user_type}"
# Access user statistics
puts "Followers: #{user.user_profile.user_data.followers}"
puts "Following: #{user.user_profile.user_data.following}"
# Access gamification data
puts "Current Level: #{user.user_profile.gamification.current_level}"
puts "Total Points: #{user.user_profile.gamification.total_points}"
puts "Badges: #{user.user_profile.gamification.badges.length}"
# Access recognition data
puts "Reward Points Received: #{user.user_profile.recognition.total_reward_points_received}"
Learning Management
# Get course catalog
courses = client.course_catalog
# Browse available courses
courses.courses.each do |course|
puts "📚 #{course.name}"
puts " Type: #{course.course_type}"
puts " Delivery: #{course.delivery_mode}"
puts " URL: #{course.start_course_url}"
puts ""
# Get detailed course information
course_details = client.course_details(course.id)
detailed_course = course_details.course
puts " 📖 Detailed Info:"
puts " Description: #{detailed_course.description}"
puts " Instructors: #{detailed_course.instructors.length}"
puts " Fields: #{detailed_course.fields.length}"
puts ""
end
# Get course categories
categories = client.course_categories
# Browse course categories
categories.all_categories.each do |category|
puts "📂 #{category.name}"
puts " Position: #{category.position}"
puts " Icon: #{category.icon_properties}"
puts ""
end
# Get user's learning progress
learning = client.my_learning
# Display learning summary
puts "🎓 Learning Summary for #{learning.user_name}"
puts "⏱️ Total training time: #{learning.total_training_time}"
puts "📚 Ongoing: #{learning.ongoing_course_count} | ✅ Completed: #{learning.completed_course_count} | 📝 Registered: #{learning.registered_course_count}"
puts ""
# Browse learning sections
learning.section.each do |section|
puts "📂 #{section.label} (#{section.count} courses)"
section.courses.each do |course|
puts " 📚 #{course.name}"
puts " Progress: #{course.course_progress}%"
puts " Type: #{course.course_type}"
puts " URL: #{course.start_course_url}"
puts ""
end
end
Recognition Management
# Get award categories
categories = client.award_categories
# Display available award categories
puts "🏆 Available Award Categories:"
categories.award_categories.each do |category|
puts " • #{category.name} (ID: #{category.id})"
puts " Permission: #{category.}"
end
puts ""
# Get awards for a specific category
category_id = 4303 # Safety & Quality category
awards = client.get_awards_list(category_id: category_id)
# Display awards in the category
puts "🏆 Awards in Category #{category_id}:"
awards.get_awards_list.each do |award|
puts " • #{award.name} (ID: #{award.id})"
puts " Points: #{award.points} | Reward Points: #{award.reward_points || 'None'}"
puts " Description: #{award.description}"
end
puts ""
# Get user profile awards
profile_awards = client.get_profile_awards
# Display user's personal awards
puts "🏆 User Profile Awards:"
puts " Core Value Tags:"
profile_awards..each do |tag|
puts " • #{tag.name} (ID: #{tag.id}) - Count: #{tag.count}"
end
puts " Recent Awards:"
profile_awards.feeds.each do |feed|
puts " • #{feed.feed_property.title} - Points: #{feed.recognition_points}"
puts " From: #{feed.from_user.name}"
end
puts ""
# Get user priority items
priority_items = client.my_priority_items
# Display priority items
puts "🔔 User Priority Items:"
priority_items.data.each do |item|
puts " • #{item.title} (ID: #{item.id}) - Count: #{item.count}"
puts " Action Type: #{item.action_type} | Icon: #{item.icon}"
end
puts ""
# Get user activity feeds
feeds = client.feeds
# Display feeds
puts "📰 User Activity Feeds:"
puts " Total feeds: #{feeds.feeds.length}"
puts " Unread feeds: #{feeds.unread_counts.unread_feeds_count}"
puts " Direct messages: #{feeds.unread_counts.}"
puts " What's new: #{feeds.unread_counts.whats_new_count}"
puts ""
# Display recent feeds
puts "📰 Recent Feeds:"
feeds.feeds.first(3).each do |feed|
puts " • #{feed.feed_property.title} (ID: #{feed.id})"
puts " From: #{feed.from_user.name} | Group: #{feed.group_name}"
puts " Type: #{feed.feed_type} | Unread: #{feed.unread}"
end
puts ""
# Get all posts
posts = client.get_all_posts(filter_by: "all")
# Display posts
puts "📝 All Posts:"
puts " Total posts: #{posts.feeds.length}"
puts " Post view count visibility: #{posts.post_view_count_visibility}"
puts ""
# Display recent posts
puts "📝 Recent Posts:"
posts.feeds.first(3).each do |post|
puts " • #{post.tile.tile_name} (ID: #{post.id})"
puts " From: #{post.from_user.name} | Group: #{post.group_name}"
puts " Views: #{post.total_view_count} | Comments: #{post.comments.length}"
end
puts ""
# Get detailed post information
if posts.feeds.any?
first_post_id = posts.feeds.first.post_id
post_details = client.get_post_by_id(first_post_id, full_description: "Y")
puts "📝 Post Details (ID: #{first_post_id}):"
puts " Title: #{post_details.post.title}"
puts " Created by: #{post_details.post.created_name}"
puts " View count: #{post_details.post.total_view_count}"
puts " Can edit: #{post_details.post.can_edit} | Can comment: #{post_details.post.can_comment}"
puts " Full description available: #{post_details.post.tile.tile_full_description.length > 0 ? 'Yes' : 'No'}"
end
puts ""
# Get user libraries
libraries = client.get_libraries
puts "📚 User Libraries:"
puts " Total libraries: #{libraries.libraries.length}"
puts ""
# Display recent libraries
puts "📚 Recent Libraries:"
libraries.libraries.first(3).each do |library|
puts " • #{library.name} (ID: #{library.id})"
puts " Type: #{library.library_type} | Items: #{library.total_items_count}"
puts " Categories: #{library.categories.length} | Edit access: #{library.edit_access}"
end
puts ""
# Get detailed library information
if libraries.libraries.any?
first_library_id = libraries.libraries.first.id
library_details = client.get_library_categories(first_library_id)
puts "📚 Library Details (ID: #{first_library_id}):"
puts " Name: #{library_details.library.name}"
puts " Type: #{library_details.library.library_type} | View: #{library_details.library.view_mode}"
puts " Total items: #{library_details.library.total_items_count}"
puts " Categories: #{library_details.library.categories.length}"
puts " Edit access: #{library_details.library.edit_access}"
# Get library items from first category
if library_details.library.categories.any?
first_category_id = library_details.library.categories.first.id
library_items = client.get_library_items(first_library_id, first_category_id)
puts "📚 Library Items (Category: #{library_items.category_name}):"
puts " View mode: #{library_items.view_mode} | Library type: #{library_items.library_type}"
puts " Items count: #{library_items.library_items.length}"
puts " Can add: #{library_items.can_add}"
end
end
puts ""
# Get user trackers
trackers = client.get_trackers
puts "📊 User Trackers:"
puts " Total trackers: #{trackers.trackers.length}"
puts ""
# Display recent trackers
puts "📊 Recent Trackers:"
trackers.trackers.first(3).each do |tracker|
puts " • #{tracker.name} (ID: #{tracker.id})"
puts " Last submission: #{Time.at(tracker.last_submission_date.to_i).strftime('%Y-%m-%d %H:%M:%S')}"
puts " Conversation: #{tracker.conversation_name}"
puts " Pinned: #{tracker.is_pinned} | Can share: #{tracker.can_share}"
end
puts ""
# Get user folders
folders = client.get_folders
puts "📁 User Folders:"
puts " Total folders: #{folders.folders.length}"
puts ""
# Display first few folders
puts "📁 Available Folders:"
folders.folders.first(3).each do |folder|
puts " • #{folder.name} (ID: #{folder.id})"
puts " Path: #{folder.relativePath} | Child count: #{folder.child_count}"
puts " Can save: #{folder.can_save} | Pinned: #{folder.is_pinned}"
end
puts ""
# Get files from first folder with content
if folders.folders.any?
folder_with_content = folders.folders.find { |f| f.child_count.to_i > 0 }
if folder_with_content
folder_files = client.get_folder_files(folder_with_content.id, include_folders: "Y")
puts "📁 Folder Files:"
puts " Folder: #{folder_files.name} | Total: #{folder_files.total_count}"
puts " Role: #{folder_files.role_name} | Upload enabled: #{folder_files.show_in_upload}"
end
end
puts ""
# Get user tasks
tasks = client.get_tasks(filter: "Pending_Tasks", page: 1, limit: 3)
puts "📋 User Tasks:"
puts " Total tasks: #{tasks.tasks.task.length}"
puts ""
# Display first few tasks
puts "📋 Recent Tasks:"
tasks.tasks.task.first(3).each do |task|
puts " • #{task.task_title} (ID: #{task.id})"
puts " Status: #{task.status} | Assigned to: #{task.assigned_to_name}"
puts " Due: #{task.due_on ? Time.at(task.due_on.to_i).strftime('%Y-%m-%d') : 'None'}"
puts " Is overdue: #{task.is_overdue} | Priority: #{task.personal_priority}"
end
puts ""
# Get detailed information for the first task
if tasks.tasks.task.any?
first_task = tasks.tasks.task.first
task_id = first_task.is_a?(Array) ? first_task[1] : first_task.id
task_details = client.get_task_details(task_id)
puts "📋 Task Details:"
puts " Task: #{task_details.task.task_title} (ID: #{task_details.task.id})"
puts " Status: #{task_details.task.status} | Bucket: #{task_details.task.bucket}"
puts " Assigned to: #{task_details.task.assigned_to_name} | Created by: #{task_details.task.creator_name}"
puts " Due: #{task_details.task.due_on ? Time.at(task_details.task.due_on.to_i).strftime('%Y-%m-%d') : 'None'}"
puts " Is overdue: #{task_details.task.is_overdue} | Priority: #{task_details.task.personal_priority}"
puts " Milestone: #{task_details.task.milestone_name || 'None'}"
puts " Project: #{task_details.task.conversation_name}"
puts " Visibility: #{task_details.task.visibility}"
# Show reviewers
if task_details.task.reviewers && task_details.task.reviewers.reviewer
reviewers = task_details.task.reviewers.reviewer
puts " Reviewers: #{reviewers.length} reviewers"
end
# Show next actions
if task_details.task.next_actions && task_details.task.next_actions.action
actions = task_details.task.next_actions.action
puts " Available actions: #{actions.join(', ')}"
end
end
puts ""
# Get user wikis
wikis = client.get_wikis(mode: "my", limit: 5, offset: 0)
puts "📚 User Wikis:"
puts " Total wikis: #{wikis.wikis.length}"
puts ""
# Display first few wikis
puts "📚 Recent Wikis:"
wikis.wikis.first(3).each do |wiki|
puts " • #{wiki.title} (ID: #{wiki.id})"
puts " Updated: #{Time.at(wiki.updated_at.to_i).strftime('%Y-%m-%d')}"
puts " Children: #{wiki.children_count} | Can edit: #{wiki.can_edit}"
puts " Conversation: #{wiki.conversation_name || 'None'} (ID: #{wiki.conversation_id})"
puts " Is draft: #{wiki.is_draft} | PDF access: #{wiki.generate_pdf_access}"
end
puts ""
# Get detailed information for the first wiki
if wikis.wikis.any?
first_wiki = wikis.wikis.first
wiki_details = client.get_wiki_details(first_wiki.id)
puts "📚 Wiki Details:"
puts " Wiki: #{wiki_details.wiki.details.title} (ID: #{wiki_details.wiki.details.id})"
puts " Status: #{wiki_details.wiki.details.status} | Platform: #{wiki_details.wiki.details.platform}"
puts " Created by: #{wiki_details.wiki.details.created_by_name} | Updated by: #{wiki_details.wiki.details.updated_by_name}"
puts " Read count: #{wiki_details.wiki.details.total_read_count} | Children: #{wiki_details.wiki.details.children_count}"
puts " Conversation: #{wiki_details.wiki.details.conversation_name}"
puts " Edit permissions: #{wiki_details.wiki.details.} | Commentable: #{wiki_details.wiki.details.is_commentable}"
puts " Generate PDF access: #{wiki_details.wiki.details.generate_pdf_access} | Show TOC: #{wiki_details.wiki.details.show_toc}"
puts " Archived: #{wiki_details.wiki.details.archived} | Is draft: #{wiki_details.wiki.is_draft}"
# Show permissions
puts " Permissions: Comment: #{wiki_details.wiki.can_comment}, Edit: #{wiki_details.wiki.can_edit}, Delete: #{wiki_details.wiki.can_delete}"
# Show reactions
if wiki_details.wiki.reactions
reactions = wiki_details.wiki.reactions
puts " Reactions: Like: #{reactions.like_count}, Superlike: #{reactions.superlike_count}"
end
# Show comment count
puts " Comment count: #{wiki_details.wiki.comment_count}"
end
puts ""
# Get core value tags
= client.
# Display core value tags
puts "🎯 Core Value Tags:"
..each do |tag|
puts " • #{tag.name} (ID: #{tag.id})"
puts " Color: ##{tag.color}"
end
puts ""
# Get leaderboard information
leaderboard = client.leaderboard_info
# Display leaderboard if available
if leaderboard.leaderboard_info
puts "🏅 User Leaderboard:"
leaderboard.leaderboard_info.user_info.each do |user|
puts " #{user.rank}. #{user.name} - #{user.award_count} awards"
end
puts ""
puts "🏆 Team Leaderboard:"
leaderboard.leaderboard_info.team_info.each do |team|
puts " #{team.rank}. #{team.name} - #{team.award_count} awards"
end
else
puts "📊 No leaderboard data configured"
end
Error Handling with Clean Responses
begin
user = client.me
# Clean dot notation access
puts "Welcome, #{user.user_profile.minimal_profile.name}!"
rescue MangoApps::AuthenticationError => e
puts "Authentication failed: #{e.}"
# Redirect to OAuth flow
rescue MangoApps::APIError => e
puts "API error: #{e.}"
puts "Status: #{e.status_code}"
rescue MangoApps::RateLimitError => e
puts "Rate limited: #{e.}"
# Implement backoff strategy
end
Error Handling
The SDK provides specific exception types for different error scenarios:
begin
posts = client.posts_list
rescue MangoApps::AuthenticationError => e
puts "Authentication failed: #{e.}"
rescue MangoApps::APIError => e
puts "API error: #{e.}"
rescue MangoApps::RateLimitError => e
puts "Rate limited: #{e.}"
end
# OAuth-specific error handling
begin
userinfo = client.get_userinfo
rescue MangoApps::TokenExpiredError => e
puts "OAuth token expired: #{e.}"
# Refresh token or redirect to OAuth flow
rescue MangoApps::APIError => e
puts "OAuth userinfo error: #{e.}"
end
Available Exception Types
MangoApps::Error- Base error classMangoApps::APIError- General API errorsMangoApps::AuthenticationError- Authentication failuresMangoApps::TokenExpiredError- Token expirationMangoApps::DiscoveryError- OAuth discovery endpoint errorsMangoApps::TokenExchangeError- OAuth token exchange errorsMangoApps::BadRequestError- 400 errorsMangoApps::UnauthorizedError- 401 errorsMangoApps::ForbiddenError- 403 errorsMangoApps::NotFoundError- 404 errorsMangoApps::RateLimitError- 429 errorsMangoApps::ServerError- 5xx errors
Configuration Options
config = MangoApps::Config.new(
domain: "yourdomain.mangoapps.com",
client_id: "your_client_id",
client_secret: "your_client_secret",
redirect_uri: "https://localhost:3000/oauth/callback",
scope: "openid profile email",
timeout: 30,
open_timeout: 10,
logger: Logger.new(STDOUT)
)
# OAuth-specific configuration
# - All OAuth endpoints automatically use HTTPS
# - Automatic redirect handling for 301/302 responses
# - SSL certificate verification enabled
Current API Coverage
- ✅ Learn Module: Course catalog, categories, course details, and my learning (4 endpoints)
- ✅ Users Module: User profile and authentication (1 endpoint)
- ✅ Recognitions Module: Award categories, get awards list, get profile awards, core value tags, and leaderboard info (5 endpoints)
- ✅ Notifications Module: My priority items for requests, events, quizzes, surveys, tasks, and todos, and user notifications with unread counts (2 endpoints)
- ✅ Feeds Module: User activity feeds with unread counts and feed details (1 endpoint)
- ✅ Posts Module: Get all posts with filtering options and get post by ID (2 endpoints)
- ✅ Libraries Module: Get user's document libraries with categories and items, get library categories by ID, and get library items by library and category ID (3 endpoints)
- ✅ Trackers Module: Get user's trackers with submission dates and conversation details (1 endpoint)
- ✅ Attachments Module: Get user's file folders with permissions and metadata, and get files and folders inside specific folders (2 endpoints)
- ✅ Tasks Module: Get user's tasks with filtering, pagination, and detailed task information, and get detailed information for specific tasks (2 endpoints)
- ✅ Wikis Module: Get user's wikis with filtering, pagination, and detailed wiki information, and get detailed information for specific wikis (2 endpoints)
- ✅ Error Handling: Comprehensive error logging and testing
- ✅ OAuth Flow: Token management, refresh, and userinfo endpoint
- ✅ Internal API Auth: Alternative authentication using API keys
- ✅ Auto Detection: Automatic authentication method detection and prioritization
- ✅ Pagination Support: Optional page and limit parameters for all list APIs
- ✅ HTTPS Security: Automatic HTTPS enforcement with redirect handling
Total: 26 API endpoints across 11 modules + OAuth + Internal API + Auto Detection + Pagination
Contributing
- Fork the repository
- Create a feature branch
- Write real tests first (no mocking)
- Implement the feature
- Ensure all tests pass
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- Documentation: RubyDoc
- Issues: GitHub Issues
- MangoApps: Official Website
Changelog
See CHANGELOG.md for a list of changes and version history.