forem-ruby 0.1.0.beta1

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.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/forem-ruby.gemspec +17 -0
  4. data/lib/forem/api_operations/create.rb +47 -0
  5. data/lib/forem/api_operations/delete.rb +88 -0
  6. data/lib/forem/api_operations/list.rb +70 -0
  7. data/lib/forem/api_operations/request.rb +83 -0
  8. data/lib/forem/api_operations/retrieve.rb +43 -0
  9. data/lib/forem/api_operations/save.rb +53 -0
  10. data/lib/forem/api_operations/update.rb +47 -0
  11. data/lib/forem/api_requestor.rb +283 -0
  12. data/lib/forem/api_resource.rb +77 -0
  13. data/lib/forem/client.rb +279 -0
  14. data/lib/forem/configuration.rb +74 -0
  15. data/lib/forem/connection_manager.rb +75 -0
  16. data/lib/forem/errors.rb +118 -0
  17. data/lib/forem/forem_object.rb +264 -0
  18. data/lib/forem/forem_response.rb +50 -0
  19. data/lib/forem/list_object.rb +171 -0
  20. data/lib/forem/resources/admin_concept.rb +169 -0
  21. data/lib/forem/resources/admin_user.rb +152 -0
  22. data/lib/forem/resources/agent_session.rb +110 -0
  23. data/lib/forem/resources/analytics.rb +151 -0
  24. data/lib/forem/resources/article.rb +256 -0
  25. data/lib/forem/resources/billboard.rb +76 -0
  26. data/lib/forem/resources/comment.rb +43 -0
  27. data/lib/forem/resources/concept.rb +192 -0
  28. data/lib/forem/resources/follow.rb +78 -0
  29. data/lib/forem/resources/follower.rb +56 -0
  30. data/lib/forem/resources/health_check.rb +70 -0
  31. data/lib/forem/resources/organization.rb +79 -0
  32. data/lib/forem/resources/page.rb +52 -0
  33. data/lib/forem/resources/podcast_episode.rb +36 -0
  34. data/lib/forem/resources/profile_image.rb +44 -0
  35. data/lib/forem/resources/reaction.rb +61 -0
  36. data/lib/forem/resources/reading_list.rb +29 -0
  37. data/lib/forem/resources/recommended_articles_list.rb +45 -0
  38. data/lib/forem/resources/request_redirect.rb +60 -0
  39. data/lib/forem/resources/segment.rb +103 -0
  40. data/lib/forem/resources/survey.rb +96 -0
  41. data/lib/forem/resources/tag.rb +27 -0
  42. data/lib/forem/resources/trend.rb +80 -0
  43. data/lib/forem/resources/user.rb +229 -0
  44. data/lib/forem/resources/video.rb +28 -0
  45. data/lib/forem/services/admin_concept_service.rb +138 -0
  46. data/lib/forem/services/admin_user_service.rb +114 -0
  47. data/lib/forem/services/agent_session_service.rb +87 -0
  48. data/lib/forem/services/analytics_service.rb +93 -0
  49. data/lib/forem/services/article_service.rb +233 -0
  50. data/lib/forem/services/base_service.rb +45 -0
  51. data/lib/forem/services/billboard_service.rb +91 -0
  52. data/lib/forem/services/comment_service.rb +51 -0
  53. data/lib/forem/services/concept_service.rb +143 -0
  54. data/lib/forem/services/follow_service.rb +61 -0
  55. data/lib/forem/services/follower_service.rb +34 -0
  56. data/lib/forem/services/health_check_service.rb +46 -0
  57. data/lib/forem/services/organization_service.rb +103 -0
  58. data/lib/forem/services/page_service.rb +107 -0
  59. data/lib/forem/services/podcast_episode_service.rb +34 -0
  60. data/lib/forem/services/profile_image_service.rb +32 -0
  61. data/lib/forem/services/reaction_service.rb +72 -0
  62. data/lib/forem/services/reading_list_service.rb +35 -0
  63. data/lib/forem/services/recommended_articles_list_service.rb +87 -0
  64. data/lib/forem/services/request_redirect_service.rb +118 -0
  65. data/lib/forem/services/segment_service.rb +83 -0
  66. data/lib/forem/services/survey_service.rb +48 -0
  67. data/lib/forem/services/tag_service.rb +32 -0
  68. data/lib/forem/services/trend_service.rb +70 -0
  69. data/lib/forem/services/user_service.rb +61 -0
  70. data/lib/forem/services/video_service.rb +33 -0
  71. data/lib/forem/util.rb +43 -0
  72. data/lib/forem/version.rb +4 -0
  73. data/lib/forem.rb +91 -0
  74. metadata +111 -0
@@ -0,0 +1,45 @@
1
+ module Forem
2
+ module Services
3
+ # Abstract base class for all Forem API service objects.
4
+ #
5
+ # Each service wraps a specific area of the Forem API and delegates method
6
+ # calls to the corresponding model class, automatically injecting the
7
+ # client's {APIRequestor} so that the correct credentials and base URL are
8
+ # used for every request.
9
+ #
10
+ # Concrete subclasses (e.g. {ArticleService}, {UserService}) are accessed
11
+ # through the reader methods on {Client} and should not be instantiated
12
+ # directly.
13
+ #
14
+ # @abstract Subclass and add public methods that delegate to the
15
+ # appropriate model class.
16
+ #
17
+ # @see Client
18
+ # @see https://developers.forem.com/api/v1
19
+ class BaseService
20
+ # Create a new service instance bound to the given requestor.
21
+ #
22
+ # @param requestor [APIRequestor] the HTTP requestor that carries the
23
+ # client's configuration (API key, base URL, etc.)
24
+ # @return [BaseService] a new service instance
25
+ def initialize(requestor)
26
+ @requestor = requestor
27
+ end
28
+
29
+ private
30
+
31
+ # Merge the client's requestor into a per-request options hash.
32
+ #
33
+ # All service methods call this helper before forwarding opts to model
34
+ # class methods so that the model uses this client's requestor rather
35
+ # than the global one.
36
+ #
37
+ # @param opts [Hash] per-request options supplied by the caller
38
+ # @return [Hash] opts with the +:requestor+ key set to this service's
39
+ # {APIRequestor}
40
+ def opts_with_requestor(opts)
41
+ opts.merge(requestor: @requestor)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,91 @@
1
+ module Forem
2
+ module Services
3
+ # Service for interacting with the Forem Billboards API.
4
+ #
5
+ # Billboards are display ads shown within Forem communities.
6
+ # Access via {Client#billboards}. All methods inject the client's requestor
7
+ # automatically so no additional configuration is required.
8
+ #
9
+ # @example
10
+ # client = Forem::Client.new("your-api-key")
11
+ # billboards = client.billboards.list
12
+ # billboard = client.billboards.retrieve(3)
13
+ #
14
+ # @see Billboard
15
+ # @see https://developers.forem.com/api/v1
16
+ class BillboardService < BaseService
17
+ # List all billboards (display ads).
18
+ #
19
+ # @param params [Hash] query parameters
20
+ # @option params [Integer] :page page number (default: 1)
21
+ # @option params [Integer] :per_page number of results per page
22
+ # @param opts [Hash] per-request options
23
+ # @return [Array<Billboard>] list of billboards
24
+ #
25
+ # @example
26
+ # client.billboards.list
27
+ #
28
+ # @see https://developers.forem.com/api/v1
29
+ def list(params = {}, opts = {})
30
+ Billboard.list(params, opts_with_requestor(opts))
31
+ end
32
+
33
+ # Create a new billboard.
34
+ #
35
+ # @param params [Hash] billboard attributes
36
+ # @option params [String] :name internal name for the billboard
37
+ # @option params [String] :body_markdown ad body in Markdown / HTML
38
+ # @option params [String] :placement_area where to display the billboard
39
+ # @option params [Boolean] :published whether the billboard is live
40
+ # @option params [Integer] :organization_id organization this billboard
41
+ # belongs to
42
+ # @param opts [Hash] per-request options
43
+ # @return [Billboard] the newly created billboard
44
+ #
45
+ # @example
46
+ # client.billboards.create(
47
+ # name: "Summer Promo",
48
+ # body_markdown: "## Sale!\nUp to 50% off.",
49
+ # placement_area: "sidebar_left",
50
+ # published: true
51
+ # )
52
+ #
53
+ # @see https://developers.forem.com/api/v1
54
+ def create(params = {}, opts = {})
55
+ Billboard.create(params, opts_with_requestor(opts))
56
+ end
57
+
58
+ # Retrieve a single billboard by its numeric ID.
59
+ #
60
+ # @param id [Integer, String] the billboard ID
61
+ # @param opts [Hash] per-request options
62
+ # @return [Billboard] the billboard with the given ID
63
+ #
64
+ # @example
65
+ # client.billboards.retrieve(3)
66
+ #
67
+ # @see https://developers.forem.com/api/v1
68
+ def retrieve(id, opts = {})
69
+ Billboard.retrieve(id, opts_with_requestor(opts))
70
+ end
71
+
72
+ # Update an existing billboard.
73
+ #
74
+ # @param id [Integer, String] the billboard ID to update
75
+ # @param params [Hash] billboard attributes to change
76
+ # @option params [String] :name new internal name
77
+ # @option params [String] :body_markdown new body content
78
+ # @option params [Boolean] :published publish or unpublish the billboard
79
+ # @param opts [Hash] per-request options
80
+ # @return [Billboard] the updated billboard
81
+ #
82
+ # @example
83
+ # client.billboards.update(3, published: false)
84
+ #
85
+ # @see https://developers.forem.com/api/v1
86
+ def update(id, params = {}, opts = {})
87
+ Billboard.update(id, params, opts_with_requestor(opts))
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,51 @@
1
+ module Forem
2
+ module Services
3
+ # Service for interacting with the Forem Comments API.
4
+ #
5
+ # Access via {Client#comments}. All methods inject the client's requestor
6
+ # automatically so no additional configuration is required.
7
+ #
8
+ # @example
9
+ # client = Forem::Client.new("your-api-key")
10
+ # comments = client.comments.list(a_id: 12345)
11
+ # comment = client.comments.retrieve("abc123")
12
+ #
13
+ # @see Comment
14
+ # @see https://developers.forem.com/api/v1#/operations/getCommentsByArticleId
15
+ class CommentService < BaseService
16
+ # List comments for an article or podcast episode.
17
+ #
18
+ # @param params [Hash] query parameters
19
+ # @option params [Integer] :a_id article ID to fetch comments for
20
+ # @option params [Integer] :p_id podcast episode ID to fetch comments for
21
+ # @param opts [Hash] per-request options
22
+ # @return [Array<Comment>] top-level comments (with nested replies)
23
+ #
24
+ # @example Fetch comments for an article
25
+ # client.comments.list(a_id: 12345)
26
+ #
27
+ # @example Fetch comments for a podcast episode
28
+ # client.comments.list(p_id: 67)
29
+ #
30
+ # @see https://developers.forem.com/api/v1#/operations/getCommentsByArticleId
31
+ def list(params = {}, opts = {})
32
+ Comment.list(params, opts_with_requestor(opts))
33
+ end
34
+
35
+ # Retrieve a single comment by its ID.
36
+ #
37
+ # @param id [String] the comment ID (alphanumeric string as returned by
38
+ # the API)
39
+ # @param opts [Hash] per-request options
40
+ # @return [Comment] the comment with the given ID
41
+ #
42
+ # @example
43
+ # client.comments.retrieve("abc123")
44
+ #
45
+ # @see https://developers.forem.com/api/v1#/operations/getCommentById
46
+ def retrieve(id, opts = {})
47
+ Comment.retrieve(id, opts_with_requestor(opts))
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,143 @@
1
+ module Forem
2
+ module Services
3
+ # Service for interacting with the Forem Concepts API.
4
+ #
5
+ # Concepts are semantic, ML-generated categories: articles are classified
6
+ # under a concept when their embedding is close enough to the concept's
7
+ # anchor embedding. This service covers the public concept endpoints
8
+ # (+/api/concepts+); creating and deleting concepts is an admin-only
9
+ # operation exposed by {AdminConceptService}.
10
+ #
11
+ # Access via {Client#concepts}. All methods inject the client's requestor
12
+ # automatically so no additional configuration is required.
13
+ #
14
+ # @example
15
+ # client = Forem::Client.new("your-api-key")
16
+ # concepts = client.concepts.list(days: 30)
17
+ # concept = client.concepts.retrieve(concepts.first.id)
18
+ # concept.daily_metrics.first.articles_count
19
+ #
20
+ # @see Concept
21
+ # @see https://developers.forem.com/api/v1
22
+ class ConceptService < BaseService
23
+ # List the concepts accessible to the authenticated user.
24
+ #
25
+ # Super admins see every concept; other users see only the concepts
26
+ # they have been granted access to. Each concept includes nested
27
+ # +daily_metrics+ covering the last +days+ days, newest first.
28
+ #
29
+ # @param params [Hash] query parameters
30
+ # @option params [Integer] :page page number (default: 1)
31
+ # @option params [Integer] :per_page number of results per page
32
+ # (default: 50, max: 100)
33
+ # @option params [Integer] :days number of days of activity to include
34
+ # in +daily_metrics+ (default: 7, minimum: 1)
35
+ # @param opts [Hash] per-request options
36
+ # @return [Forem::ListObject<Concept>] paginated list of concepts
37
+ #
38
+ # @example
39
+ # client.concepts.list(per_page: 20, days: 30)
40
+ #
41
+ # @see https://developers.forem.com/api/v1
42
+ def list(params = {}, opts = {})
43
+ Concept.list(params, opts_with_requestor(opts))
44
+ end
45
+
46
+ # Retrieve a single concept by its numeric ID.
47
+ #
48
+ # The response includes nested +daily_metrics+ for the last +days+ days
49
+ # and a +top_articles+ array with the concept's three highest-scoring
50
+ # articles.
51
+ #
52
+ # @param id [Integer, String] the concept ID
53
+ # @param params [Hash] query parameters
54
+ # @option params [Integer] :days number of days of activity to include
55
+ # in +daily_metrics+ (default: 7, minimum: 1)
56
+ # @param opts [Hash] per-request options
57
+ # @return [Concept] the concept with the given ID
58
+ #
59
+ # @example
60
+ # concept = client.concepts.retrieve(7)
61
+ # concept.daily_metrics.map(&:popularity_score)
62
+ #
63
+ # @see https://developers.forem.com/api/v1
64
+ def retrieve(id, params = {}, opts = {})
65
+ Concept.retrieve(id, params, opts_with_requestor(opts))
66
+ end
67
+
68
+ # Update an existing concept.
69
+ #
70
+ # Params are wrapped in the +concept+ key expected by the API, so they
71
+ # can be passed flat. Only +score+, +description+, and
72
+ # +similarity_threshold+ are permitted. Updating the description
73
+ # regenerates the concept's anchor embedding; updating the description
74
+ # or the similarity threshold re-classifies existing articles in the
75
+ # background.
76
+ #
77
+ # @param id [Integer, String] the concept ID to update
78
+ # @param params [Hash] concept attributes to change
79
+ # @option params [Float] :score new curation score
80
+ # @option params [String] :description new semantic description used to
81
+ # regenerate the anchor embedding
82
+ # @option params [Float] :similarity_threshold new cosine distance
83
+ # threshold (0.0–1.0)
84
+ # @param opts [Hash] per-request options
85
+ # @return [Concept] the updated concept
86
+ #
87
+ # @example
88
+ # client.concepts.update(7, description: "Storage engines", score: 4.5)
89
+ #
90
+ # @see https://developers.forem.com/api/v1
91
+ def update(id, params = {}, opts = {})
92
+ Concept.update(id, params, opts_with_requestor(opts))
93
+ end
94
+
95
+ # List the published articles classified under a concept.
96
+ #
97
+ # Articles are ordered by semantic distance (closest first) with the
98
+ # article score as a tiebreaker, unless +sort+ is +"score"+.
99
+ #
100
+ # @param id [Integer, String] the concept ID
101
+ # @param params [Hash] query parameters
102
+ # @option params [String] :sort +"score"+ to sort by article score;
103
+ # otherwise sorted by semantic distance
104
+ # @option params [Integer] :page page number (default: 1)
105
+ # @option params [Integer] :per_page number of results per page
106
+ # (default: 10)
107
+ # @param opts [Hash] per-request options
108
+ # @return [Forem::ListObject<Forem::Article>] paginated list of articles
109
+ #
110
+ # @example
111
+ # client.concepts.articles(7, sort: "score", per_page: 25)
112
+ #
113
+ # @see https://developers.forem.com/api/v1
114
+ def articles(id, params = {}, opts = {})
115
+ Concept.articles(id, params, opts_with_requestor(opts))
116
+ end
117
+
118
+ # Semantically search the concepts accessible to the caller.
119
+ #
120
+ # The query is embedded and compared against each concept's anchor
121
+ # embedding. Results come back closest-first, each with +distance+ and
122
+ # +similarity+ alongside the usual concept fields. This endpoint
123
+ # requires an API key and is not paginated.
124
+ #
125
+ # @param params [Hash] query parameters
126
+ # @option params [String] :q (required) the search text
127
+ # @option params [Integer] :per_page number of concepts to return
128
+ # (default: 10, max: 50)
129
+ # @option params [Float] :threshold optional maximum cosine distance
130
+ # (0.0–2.0) for a concept to be included
131
+ # @param opts [Hash] per-request options
132
+ # @return [Array<Concept>] matching concepts, closest first
133
+ #
134
+ # @example
135
+ # client.concepts.search(q: "vector databases", per_page: 5)
136
+ #
137
+ # @see https://developers.forem.com/api/v1
138
+ def search(params = {}, opts = {})
139
+ Concept.search(params, opts_with_requestor(opts))
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,61 @@
1
+ module Forem
2
+ module Services
3
+ # Service for interacting with the Forem Follows API.
4
+ #
5
+ # Lists the tags the authenticated user follows, and follows users or
6
+ # organizations in bulk.
7
+ #
8
+ # @example
9
+ # client = Forem::Client.new("your-api-key")
10
+ # followed_tags = client.follows.list
11
+ # client.follows.create(user_ids: [42, 99])
12
+ #
13
+ # @see Follow
14
+ # @see https://developers.forem.com/api/v1#/operations/getFollowedTags
15
+ class FollowService < BaseService
16
+ # List tags followed by the authenticated user.
17
+ #
18
+ # @param params [Hash] query parameters
19
+ # @option params [Integer] :page page number (default: 1)
20
+ # @option params [Integer] :per_page number of results per page
21
+ # @param opts [Hash] per-request options
22
+ # @return [Forem::ListObject<Forem::Follow>] paginated list of
23
+ # followed tags for the current user.
24
+ #
25
+ # @example
26
+ # client.follows.list
27
+ #
28
+ # @see https://developers.forem.com/api/v1#/operations/getFollowedTags
29
+ def list(params = {}, opts = {})
30
+ Follow.list(params, opts_with_requestor(opts))
31
+ end
32
+
33
+ # Follow one or more users and/or organizations.
34
+ #
35
+ # The Forem API takes flat +user_ids+ and/or +organization_ids+
36
+ # arrays — not a wrapped +follows:+ key, despite the resource name.
37
+ # Tags are not followed through this endpoint.
38
+ #
39
+ # @param params [Hash] follow attributes
40
+ # @option params [Array<Integer>] :user_ids user IDs to follow
41
+ # @option params [Array<Integer>] :organization_ids org IDs to follow
42
+ # @param opts [Hash] per-request options
43
+ # @return [Forem::Follow] outcome object (e.g.
44
+ # <tt>#<Forem::Follow {"outcome" => "followed 2 users"}></tt>).
45
+ #
46
+ # @example Follow users in bulk
47
+ # client.follows.create(user_ids: [42, 99])
48
+ #
49
+ # @example Follow organizations
50
+ # client.follows.create(organization_ids: [7])
51
+ #
52
+ # @example Combined
53
+ # client.follows.create(user_ids: [42], organization_ids: [7])
54
+ #
55
+ # @see https://developers.forem.com/api/v1
56
+ def create(params = {}, opts = {})
57
+ Follow.create(params, opts_with_requestor(opts))
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,34 @@
1
+ module Forem
2
+ module Services
3
+ # Service for interacting with the Forem Followers API.
4
+ #
5
+ # Lists the users who follow the authenticated user.
6
+ # Access via {Client#followers}. All methods inject the client's requestor
7
+ # automatically so no additional configuration is required.
8
+ #
9
+ # @example
10
+ # client = Forem::Client.new("your-api-key")
11
+ # followers = client.followers.list(per_page: 50)
12
+ #
13
+ # @see Follower
14
+ # @see https://developers.forem.com/api/v1#/operations/getFollowers
15
+ class FollowerService < BaseService
16
+ # List users who follow the authenticated user.
17
+ #
18
+ # @param params [Hash] query parameters
19
+ # @option params [Integer] :page page number (default: 1)
20
+ # @option params [Integer] :per_page number of results per page (max: 1000)
21
+ # @option params [String] :sort sort order ("created_at" for most recent first)
22
+ # @param opts [Hash] per-request options
23
+ # @return [Array<Follower>] list of followers for the authenticated user
24
+ #
25
+ # @example
26
+ # client.followers.list(per_page: 100, sort: "created_at")
27
+ #
28
+ # @see https://developers.forem.com/api/v1#/operations/getFollowers
29
+ def list(params = {}, opts = {})
30
+ Follower.list(params, opts_with_requestor(opts))
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,46 @@
1
+ module Forem
2
+ module Services
3
+ # Service for interacting with the Forem Health Check API.
4
+ #
5
+ # In production these endpoints require the +health-check-token+
6
+ # header — pass +token:+ to each call. On localhost the token is
7
+ # bypassed by Forem core, so a local development instance accepts
8
+ # unauthenticated calls.
9
+ #
10
+ # @example Production
11
+ # client.health_checks.app(token: ENV["FOREM_HEALTH_CHECK_TOKEN"])
12
+ #
13
+ # @example Local development (token not required for localhost)
14
+ # client.health_checks.app
15
+ #
16
+ # @see HealthCheck
17
+ # @see https://developers.forem.com/api/v1
18
+ class HealthCheckService < BaseService
19
+ # Application-server health.
20
+ # @param token [String, nil] value for the +health-check-token+ header
21
+ # (required in production; bypassed on localhost).
22
+ # @param opts [Hash] per-request options
23
+ # @return [Forem::ForemObject] response body, e.g.
24
+ # <tt>{"message" => "App is up!"}</tt>
25
+ def app(token: nil, **opts)
26
+ HealthCheck.app(token: token, **opts_with_requestor(opts))
27
+ end
28
+
29
+ # Database connectivity & responsiveness.
30
+ # @param token [String, nil] value for the +health-check-token+ header.
31
+ # @param opts [Hash] per-request options
32
+ # @return [Forem::ForemObject]
33
+ def database(token: nil, **opts)
34
+ HealthCheck.database(token: token, **opts_with_requestor(opts))
35
+ end
36
+
37
+ # Cache (Redis) connectivity & responsiveness.
38
+ # @param token [String, nil] value for the +health-check-token+ header.
39
+ # @param opts [Hash] per-request options
40
+ # @return [Forem::ForemObject]
41
+ def cache(token: nil, **opts)
42
+ HealthCheck.cache(token: token, **opts_with_requestor(opts))
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,103 @@
1
+ module Forem
2
+ module Services
3
+ # Service for interacting with the Forem Organizations API.
4
+ #
5
+ # Access via {Client#organizations}. All methods inject the client's
6
+ # requestor automatically so no additional configuration is required.
7
+ #
8
+ # @example
9
+ # client = Forem::Client.new("your-api-key")
10
+ # orgs = client.organizations.list
11
+ # org = client.organizations.retrieve(7)
12
+ #
13
+ # @see Organization
14
+ # @see https://developers.forem.com/api/v1#/operations/getOrganizations
15
+ class OrganizationService < BaseService
16
+ # List all organizations.
17
+ #
18
+ # @param params [Hash] query parameters
19
+ # @option params [Integer] :page page number (default: 1)
20
+ # @option params [Integer] :per_page number of results per page
21
+ # @param opts [Hash] per-request options
22
+ # @return [Array<Organization>] list of organizations
23
+ #
24
+ # @example
25
+ # client.organizations.list(per_page: 25)
26
+ #
27
+ # @see https://developers.forem.com/api/v1#/operations/getOrganizations
28
+ def list(params = {}, opts = {})
29
+ Organization.list(params, opts_with_requestor(opts))
30
+ end
31
+
32
+ # Create a new organization.
33
+ #
34
+ # @param params [Hash] organization attributes
35
+ # @option params [String] :name display name of the organization
36
+ # @option params [String] :username unique username / slug
37
+ # @option params [String] :summary short description
38
+ # @option params [String] :url website URL
39
+ # @option params [String] :location location string
40
+ # @option params [String] :tech_stack technology stack description
41
+ # @param opts [Hash] per-request options
42
+ # @return [Organization] the newly created organization
43
+ #
44
+ # @example
45
+ # client.organizations.create(
46
+ # name: "Acme Corp",
47
+ # username: "acme",
48
+ # summary: "We make everything."
49
+ # )
50
+ #
51
+ # @see https://developers.forem.com/api/v1#/operations/createOrganization
52
+ def create(params = {}, opts = {})
53
+ Organization.create(params, opts_with_requestor(opts))
54
+ end
55
+
56
+ # Retrieve a single organization by its numeric ID.
57
+ #
58
+ # @param id [Integer, String] the organization ID
59
+ # @param opts [Hash] per-request options
60
+ # @return [Organization] the organization with the given ID
61
+ #
62
+ # @example
63
+ # client.organizations.retrieve(7)
64
+ #
65
+ # @see https://developers.forem.com/api/v1#/operations/getOrganizationById
66
+ def retrieve(id, opts = {})
67
+ Organization.retrieve(id, opts_with_requestor(opts))
68
+ end
69
+
70
+ # Update an existing organization.
71
+ #
72
+ # @param id [Integer, String] the organization ID to update
73
+ # @param params [Hash] organization attributes to change
74
+ # @option params [String] :name new display name
75
+ # @option params [String] :summary new description
76
+ # @option params [String] :url new website URL
77
+ # @param opts [Hash] per-request options
78
+ # @return [Organization] the updated organization
79
+ #
80
+ # @example
81
+ # client.organizations.update(7, summary: "Updated description.")
82
+ #
83
+ # @see https://developers.forem.com/api/v1#/operations/updateOrganization
84
+ def update(id, params = {}, opts = {})
85
+ Organization.update(id, params, opts_with_requestor(opts))
86
+ end
87
+
88
+ # Delete an organization.
89
+ #
90
+ # @param id [Integer, String] the organization ID to delete
91
+ # @param opts [Hash] per-request options
92
+ # @return [nil] returns nil on success
93
+ #
94
+ # @example
95
+ # client.organizations.delete(7)
96
+ #
97
+ # @see https://developers.forem.com/api/v1#/operations/deleteOrganization
98
+ def delete(id, opts = {})
99
+ Organization.delete(id, opts_with_requestor(opts))
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,107 @@
1
+ module Forem
2
+ module Services
3
+ # Service for interacting with the Forem Pages API.
4
+ #
5
+ # Pages are static landing pages within a Forem community.
6
+ # Access via {Client#pages}. All methods inject the client's requestor
7
+ # automatically so no additional configuration is required.
8
+ #
9
+ # @example
10
+ # client = Forem::Client.new("your-api-key")
11
+ # pages = client.pages.list
12
+ # page = client.pages.retrieve(10)
13
+ #
14
+ # @see Page
15
+ # @see https://developers.forem.com/api/v1
16
+ class PageService < BaseService
17
+ # List all static pages.
18
+ #
19
+ # @param params [Hash] query parameters
20
+ # @option params [Integer] :page page number (default: 1)
21
+ # @option params [Integer] :per_page number of results per page
22
+ # @param opts [Hash] per-request options
23
+ # @return [Array<Page>] list of static pages
24
+ #
25
+ # @example
26
+ # client.pages.list
27
+ #
28
+ # @see https://developers.forem.com/api/v1
29
+ def list(params = {}, opts = {})
30
+ Page.list(params, opts_with_requestor(opts))
31
+ end
32
+
33
+ # Create a new static page.
34
+ #
35
+ # @param params [Hash] page attributes
36
+ # @option params [String] :title page title
37
+ # @option params [String] :slug URL slug (must be unique)
38
+ # @option params [String] :body_markdown page body in Markdown
39
+ # @option params [String] :body_html page body in HTML (alternative to
40
+ # Markdown)
41
+ # @option params [Boolean] :is_top_level_path whether the page is
42
+ # accessible at the root path
43
+ # @option params [String] :description short description / meta tag
44
+ # @option params [String] :template page template name
45
+ # @param opts [Hash] per-request options
46
+ # @return [Page] the newly created page
47
+ #
48
+ # @example
49
+ # client.pages.create(
50
+ # title: "About Us",
51
+ # slug: "about",
52
+ # body_markdown: "## About\nWe are a community of developers."
53
+ # )
54
+ #
55
+ # @see https://developers.forem.com/api/v1
56
+ def create(params = {}, opts = {})
57
+ Page.create(params, opts_with_requestor(opts))
58
+ end
59
+
60
+ # Retrieve a single static page by its numeric ID.
61
+ #
62
+ # @param id [Integer, String] the page ID
63
+ # @param opts [Hash] per-request options
64
+ # @return [Page] the page with the given ID
65
+ #
66
+ # @example
67
+ # client.pages.retrieve(10)
68
+ #
69
+ # @see https://developers.forem.com/api/v1
70
+ def retrieve(id, opts = {})
71
+ Page.retrieve(id, opts_with_requestor(opts))
72
+ end
73
+
74
+ # Update an existing static page.
75
+ #
76
+ # @param id [Integer, String] the page ID to update
77
+ # @param params [Hash] page attributes to change
78
+ # @option params [String] :title new page title
79
+ # @option params [String] :body_markdown new body in Markdown
80
+ # @option params [String] :description new description
81
+ # @param opts [Hash] per-request options
82
+ # @return [Page] the updated page
83
+ #
84
+ # @example
85
+ # client.pages.update(10, title: "About Our Community")
86
+ #
87
+ # @see https://developers.forem.com/api/v1
88
+ def update(id, params = {}, opts = {})
89
+ Page.update(id, params, opts_with_requestor(opts))
90
+ end
91
+
92
+ # Delete a static page.
93
+ #
94
+ # @param id [Integer, String] the page ID to delete
95
+ # @param opts [Hash] per-request options
96
+ # @return [nil] returns nil on success
97
+ #
98
+ # @example
99
+ # client.pages.delete(10)
100
+ #
101
+ # @see https://developers.forem.com/api/v1
102
+ def delete(id, opts = {})
103
+ Page.delete(id, opts_with_requestor(opts))
104
+ end
105
+ end
106
+ end
107
+ end