fathom-ruby 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f0c6eb3ccab98b13b2c4f4dacb7e2ef07f6659f9bfb24b2a834d5983194628f6
4
+ data.tar.gz: 30783d708be6bac671f90739022765abec159da0bbf91b779fe0312e2a9658cf
5
+ SHA512:
6
+ metadata.gz: acdcb1635c7fb6d30d48c66aa02e9878d4ae4c1e6ee49f4a91dba102133bbb90af14f389d90cec728603d2fbc522decad1adeadce600c1dd018d88e894d6df13
7
+ data.tar.gz: 88c8c3124dfbfcbcd02b060f9b6ba929361fe4cb676765b87882ab84d3944fb2d36715a930f867aad37fc48a3b031763759d30e987be8dcaa197c0af7552d489
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --require spec_helper
2
+ --color
3
+ --format documentation
4
+
data/.rubocop.yml ADDED
@@ -0,0 +1,59 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+ Exclude:
6
+ - 'vendor/**/*'
7
+ - 'bin/**/*'
8
+ - 'tmp/**/*'
9
+
10
+ Style/Documentation:
11
+ Enabled: false
12
+
13
+ Style/StringLiterals:
14
+ Enabled: true
15
+ EnforcedStyle: double_quotes
16
+
17
+ Style/StringLiteralsInInterpolation:
18
+ Enabled: true
19
+ EnforcedStyle: double_quotes
20
+
21
+ Layout/LineLength:
22
+ Max: 120
23
+
24
+ Metrics/MethodLength:
25
+ Max: 20
26
+
27
+ Metrics/AbcSize:
28
+ Max: 20
29
+ Exclude:
30
+ - 'lib/fathom/client.rb' # HTTP client needs complex response handling
31
+
32
+ Metrics/CyclomaticComplexity:
33
+ Max: 7
34
+ Exclude:
35
+ - 'lib/fathom/client.rb' # HTTP client has many response codes to handle
36
+
37
+ Metrics/ParameterLists:
38
+ Max: 5
39
+ Exclude:
40
+ - 'lib/fathom/client.rb' # Request retry logic needs multiple params
41
+
42
+ Metrics/ClassLength:
43
+ Max: 100
44
+ Exclude:
45
+ - 'lib/fathom/client.rb' # HTTP client is inherently complex
46
+
47
+ Metrics/BlockLength:
48
+ Exclude:
49
+ - 'spec/**/*'
50
+ - '*.gemspec'
51
+
52
+ Style/FrozenStringLiteralComment:
53
+ Enabled: true
54
+ EnforcedStyle: always
55
+
56
+ Naming/PredicateMethod:
57
+ Exclude:
58
+ - 'lib/fathom/resource.rb' # delete is a REST method, not a predicate
59
+
data/CHANGELOG.md ADDED
@@ -0,0 +1,33 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [1.0.0] - 2025-10-17
11
+
12
+ ### Added
13
+ - Full support for Fathom API v1
14
+ - **Meetings API**: List, retrieve, fetch summaries and transcripts
15
+ - **Recordings API**: Get summaries and transcripts with async delivery support
16
+ - **Teams API**: List teams and manage team members
17
+ - **Team Members API**: List and filter team members
18
+ - **Webhooks API**: Full CRUD operations (create, list, retrieve, delete)
19
+ - Automatic rate limiting with exponential backoff and configurable retries
20
+ - Comprehensive error handling with custom error classes
21
+ - Built with Ruby's native `Net::HTTP` (no external HTTP dependencies)
22
+ - Ruby 3.1+ support with modern syntax (endless methods, shorthand hash, pattern matching)
23
+ - Extensive test coverage (125 examples, 94.87% coverage)
24
+ - Live API integration test script
25
+ - Full RuboCop compliance
26
+
27
+ ### Technical Details
28
+ - Authentication via `X-Api-Key` header
29
+ - Dynamic attribute access with `method_missing`
30
+ - Rate limit tracking and automatic retry logic
31
+ - Pagination support with cursor-based navigation
32
+ - Proper handling of API response formats
33
+
@@ -0,0 +1,38 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, religion, or sexual identity
10
+ and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to a positive environment for our
15
+ community include:
16
+
17
+ * Demonstrating empathy and kindness toward other people
18
+ * Being respectful of differing opinions, viewpoints, and experiences
19
+ * Giving and gracefully accepting constructive feedback
20
+ * Accepting responsibility and apologizing to those affected by our mistakes,
21
+ and learning from the experience
22
+ * Focusing on what is best not just for us as individuals, but for the
23
+ overall community
24
+
25
+ ## Enforcement
26
+
27
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
28
+ reported to the community leaders responsible for enforcement.
29
+ All complaints will be reviewed and investigated promptly and fairly.
30
+
31
+ ## Attribution
32
+
33
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
34
+ version 2.0, available at
35
+ https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
36
+
37
+ [homepage]: https://www.contributor-covenant.org
38
+
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in fathom-ruby.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ # Development dependencies
11
+ group :development do
12
+ gem "irb", "~> 1.0"
13
+ gem "openssl"
14
+ gem "rdoc", "~> 6.0"
15
+ gem "rspec", "~> 3.0"
16
+ gem "rubocop", "~> 1.21"
17
+ gem "simplecov", "~> 0.22"
18
+ gem "webmock", "~> 3.0"
19
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Juan Rodriguez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,509 @@
1
+ # Fathom Ruby
2
+
3
+ [Fathom](https://fathom.ai) is an AI meeting assistant that records, transcribes, highlights, and summarizes your meetings so you can focus on the conversation.
4
+
5
+ This is a comprehensive Ruby gem for interacting with the [Fathom API](https://developers.fathom.ai). This gem provides easy access to Fathom's REST API for managing meetings, recordings, teams, webhooks, and more.
6
+
7
+ [![CI](https://github.com/j4rs/fathom-ruby/workflows/CI/badge.svg)](https://github.com/j4rs/fathom-ruby/actions)
8
+ [![Gem Version](https://badge.fury.io/rb/fathom-ruby.svg)](https://badge.fury.io/rb/fathom-ruby)
9
+
10
+ ## Features
11
+
12
+ - 🔄 Automatic rate limiting with configurable retries
13
+ - 🛡️ Comprehensive error handling
14
+ - 📝 Full support for all the existing Fathom API resources
15
+ - 🎯 Simple and intuitive API
16
+ - ✅ Verified against [official Fathom API documentation](https://developers.fathom.ai/api-reference)
17
+
18
+ ## Requirements
19
+
20
+ - Ruby >= 3.1.0
21
+
22
+ ## Installation
23
+
24
+ Add this line to your application's Gemfile:
25
+
26
+ ```ruby
27
+ gem 'fathom-ruby'
28
+ ```
29
+
30
+ And then execute:
31
+
32
+ ```bash
33
+ $ bundle install
34
+ ```
35
+
36
+ Or install it yourself as:
37
+
38
+ ```bash
39
+ $ gem install fathom-ruby
40
+ ```
41
+
42
+ ## Configuration
43
+
44
+ ### Basic Setup
45
+
46
+ Configure the gem with your Fathom API key:
47
+
48
+ ```ruby
49
+ require 'fathom'
50
+
51
+ Fathom.api_key = "your_api_key_here"
52
+ ```
53
+
54
+ ### Configuration Options
55
+
56
+ ```ruby
57
+ Fathom.configure do |config|
58
+ config.api_key = "your_api_key_here"
59
+
60
+ # Enable/disable automatic retries on rate limits (default: true)
61
+ config.auto_retry = true
62
+
63
+ # Maximum number of retry attempts (default: 3)
64
+ config.max_retries = 3
65
+
66
+ # Enable debug logging (default: false)
67
+ config.debug = Rails.env.development?
68
+
69
+ # Enable HTTP request/response logging (default: false)
70
+ config.debug_http = Rails.env.development?
71
+ end
72
+ ```
73
+
74
+ ### Rails Configuration
75
+
76
+ Create an initializer at `config/initializers/fathom.rb`:
77
+
78
+ ```ruby
79
+ require 'fathom'
80
+
81
+ Fathom.configure do |config|
82
+ config.api_key = ENV['FATHOM_API_KEY']
83
+ # ... rest of the settings (like above)
84
+ end
85
+ ```
86
+
87
+ ## Usage
88
+
89
+ > **📋 Important Notes:**
90
+ > - The Fathom API uses **cursor-based pagination**, not offset-based
91
+ > - Response format is `{ items: [...] }`, not `{ data: [...] }`
92
+ > - **Team Members**: No individual IDs - filter by team name instead
93
+ > - **Recordings**: No list/retrieve endpoints - use specialized endpoints for summary/transcript
94
+ > - See [API_CORRECTIONS.md](API_CORRECTIONS.md) for complete details on API structure
95
+
96
+ ### Meetings
97
+
98
+ List all meetings:
99
+
100
+ ```ruby
101
+ # Get all meetings
102
+ meetings = Fathom::Meeting.all
103
+
104
+ # With query parameters
105
+ meetings = Fathom::Meeting.all(
106
+ cursor: "eyJwYWdlX251bSI6Mn0=", # Cursor-based pagination
107
+ include_summary: true, # Include default_summary
108
+ include_transcript: true, # Include transcript
109
+ include_action_items: true, # Include action_items
110
+ teams: ["Sales", "Engineering"] # Filter by team names
111
+ )
112
+
113
+ # Filter by date range
114
+ meetings = Fathom::Meeting.all(
115
+ created_after: "2025-01-01T00:00:00Z",
116
+ created_before: "2025-01-31T23:59:59Z"
117
+ )
118
+
119
+ # Filter by calendar invitees
120
+ meetings = Fathom::Meeting.all(
121
+ "calendar_invitees[]" => "ceo@acme.com"
122
+ )
123
+ ```
124
+
125
+ Access meeting data:
126
+
127
+ ```ruby
128
+ meeting = meetings.first
129
+
130
+ # Basic fields
131
+ puts meeting.title
132
+ puts meeting.recording_id
133
+
134
+ # Embedded data (when requested with include_* params)
135
+ puts meeting.summary # Returns default_summary hash
136
+ puts meeting.summary["markdown_formatted"]
137
+ puts meeting.transcript # Returns transcript array
138
+ puts meeting.participants # Returns calendar_invitees array
139
+ puts meeting.action_items # Returns action_items array
140
+ ```
141
+
142
+ Fetch recording data for a meeting:
143
+
144
+ ```ruby
145
+ meeting = meetings.first
146
+
147
+ # Fetch summary from Recording API
148
+ if meeting.recording?
149
+ summary = meeting.fetch_summary
150
+ puts summary["template_name"]
151
+ puts summary["markdown_formatted"]
152
+
153
+ # Fetch transcript from Recording API
154
+ transcript = meeting.fetch_transcript
155
+ transcript.each do |segment|
156
+ puts "#{segment['speaker']['display_name']}: #{segment['text']}"
157
+ end
158
+ end
159
+ ```
160
+
161
+ ### Recordings
162
+
163
+ **Note**: Recordings don't have standard list/retrieve endpoints. They're accessed via their specialized endpoints:
164
+
165
+ Get summary for a recording:
166
+
167
+ ```ruby
168
+ # Synchronous - returns summary immediately
169
+ summary = Fathom::Recording.get_summary(123456789)
170
+
171
+ puts summary["template_name"] # e.g., "general"
172
+ puts summary["markdown_formatted"] # Formatted summary text
173
+ ```
174
+
175
+ Get transcript for a recording:
176
+
177
+ ```ruby
178
+ # Synchronous - returns transcript immediately
179
+ transcript = Fathom::Recording.get_transcript(123456789)
180
+
181
+ transcript.each do |segment|
182
+ speaker = segment["speaker"]["display_name"]
183
+ text = segment["text"]
184
+ timestamp = segment["timestamp"]
185
+
186
+ puts "[#{timestamp}] #{speaker}: #{text}"
187
+ end
188
+ ```
189
+
190
+ Async mode with webhooks:
191
+
192
+ ```ruby
193
+ # Async - sends result to your webhook URL
194
+ Fathom::Recording.get_summary(
195
+ 123456789,
196
+ destination_url: "https://your-app.com/webhooks/summary"
197
+ )
198
+
199
+ Fathom::Recording.get_transcript(
200
+ 123456789,
201
+ destination_url: "https://your-app.com/webhooks/transcript"
202
+ )
203
+ ```
204
+
205
+ ### Teams
206
+
207
+ List all teams:
208
+
209
+ ```ruby
210
+ teams = Fathom::Team.all
211
+
212
+ teams.each do |team|
213
+ puts team.name
214
+ puts "Created: #{team.created_at}"
215
+ end
216
+ ```
217
+
218
+ Get a specific team:
219
+
220
+ ```ruby
221
+ team = Fathom::Team.retrieve("team_id")
222
+ puts team.name
223
+ ```
224
+
225
+ List team members:
226
+
227
+ ```ruby
228
+ team = Fathom::Team.retrieve("team_id")
229
+ members = team.members # Automatically filters by team name
230
+
231
+ # Or directly by team name
232
+ members = Fathom::TeamMember.all(team: "Engineering")
233
+ ```
234
+
235
+ ### Team Members
236
+
237
+ List all team members:
238
+
239
+ ```ruby
240
+ # List all team members
241
+ members = Fathom::TeamMember.all
242
+
243
+ members.each do |member|
244
+ puts "#{member.name} (#{member.email})"
245
+ puts "Created: #{member.created_at}"
246
+ end
247
+ ```
248
+
249
+ Filter by team name:
250
+
251
+ ```ruby
252
+ # Filter by specific team name
253
+ members = Fathom::TeamMember.all(team: "Engineering")
254
+
255
+ members.each do |member|
256
+ puts "#{member.name} - #{member.email}"
257
+ end
258
+ ```
259
+
260
+ Pagination with cursor:
261
+
262
+ ```ruby
263
+ # First page
264
+ response = Fathom::TeamMember.all(team: "Sales")
265
+
266
+ # Next page (if cursor is available from API response)
267
+ next_page = Fathom::TeamMember.all(team: "Sales", cursor: "next_cursor_value")
268
+ ```
269
+
270
+ **Note:** Team members don't have individual IDs in the Fathom API. Use filtering instead of retrieving individual members.
271
+
272
+ ### Webhooks
273
+
274
+ List all webhooks:
275
+
276
+ ```ruby
277
+ webhooks = Fathom::Webhook.all
278
+
279
+ webhooks.each do |webhook|
280
+ puts "#{webhook.url}"
281
+ puts " Includes transcript: #{webhook.include_transcript?}"
282
+ puts " Includes summary: #{webhook.include_summary?}"
283
+ puts " Active: #{webhook.active?}"
284
+ end
285
+ ```
286
+
287
+ Create a webhook:
288
+
289
+ ```ruby
290
+ webhook = Fathom::Webhook.create(
291
+ url: "https://example.com/webhook",
292
+ # Specify which recordings should trigger the webhook:
293
+ # - my_recordings: Your own recordings
294
+ # - shared_external_recordings: Recordings shared with you externally
295
+ # - my_shared_with_team_recordings: Your recordings shared with your team
296
+ # - shared_team_recordings: Team recordings shared with you
297
+ triggered_for: ["my_recordings", "shared_external_recordings"],
298
+ include_transcript: true,
299
+ include_summary: true,
300
+ include_action_items: true,
301
+ include_crm_matches: false
302
+ )
303
+
304
+ puts webhook.id
305
+ puts webhook.secret
306
+ puts webhook.triggered_for # => ["my_recordings", "shared_external_recordings"]
307
+ ```
308
+
309
+ Get a specific webhook:
310
+
311
+ ```ruby
312
+ webhook = Fathom::Webhook.retrieve("webhook_id")
313
+
314
+ if webhook.active?
315
+ puts "Webhook is active"
316
+ end
317
+ ```
318
+
319
+ Delete a webhook:
320
+
321
+ ```ruby
322
+ webhook = Fathom::Webhook.retrieve("webhook_id")
323
+ webhook.delete
324
+ ```
325
+
326
+ Check webhook configuration:
327
+
328
+ ```ruby
329
+ webhook = Fathom::Webhook.retrieve("webhook_id")
330
+
331
+ puts "Active: #{webhook.active?}"
332
+ puts "Triggered for: #{webhook.triggered_for.join(', ')}"
333
+ puts "Includes transcript: #{webhook.include_transcript?}"
334
+ puts "Includes summary: #{webhook.include_summary?}"
335
+ puts "Includes action items: #{webhook.include_action_items?}"
336
+ puts "Includes CRM matches: #{webhook.include_crm_matches?}"
337
+ ```
338
+
339
+ ## Rate Limiting
340
+
341
+ The Fathom API has a rate limit of 60 requests per 60 seconds. This gem handles rate limiting automatically.
342
+
343
+ ### Automatic Retries (Default)
344
+
345
+ By default, the gem will automatically retry requests when rate limited:
346
+
347
+ ```ruby
348
+ Fathom.auto_retry = true # This is the default
349
+ Fathom.max_retries = 3 # Maximum retry attempts
350
+
351
+ # Requests will automatically retry with exponential backoff
352
+ meetings = Fathom::Meeting.all
353
+ ```
354
+
355
+ ### Manual Rate Limit Handling
356
+
357
+ Disable automatic retries and handle rate limits manually:
358
+
359
+ ```ruby
360
+ Fathom.auto_retry = false
361
+
362
+ begin
363
+ meetings = Fathom::Meeting.all
364
+ rescue Fathom::RateLimitError => e
365
+ # Handle rate limit error
366
+ puts "Rate limited. Remaining: #{e.rate_limit_remaining}"
367
+ puts "Reset in: #{e.rate_limit_reset} seconds"
368
+
369
+ # Wait and retry manually
370
+ sleep(e.rate_limit_reset)
371
+ retry
372
+ end
373
+ ```
374
+
375
+ ### Checking Rate Limit Info
376
+
377
+ Access rate limit information from any resource:
378
+
379
+ ```ruby
380
+ meetings = Fathom::Meeting.all
381
+ rate_info = meetings.first.rate_limit_info
382
+
383
+ puts "Limit: #{rate_info[:limit]}"
384
+ puts "Remaining: #{rate_info[:remaining]}"
385
+ puts "Reset in: #{rate_info[:reset]} seconds"
386
+ ```
387
+
388
+ ## Error Handling
389
+
390
+ The gem provides specific error classes for different scenarios:
391
+
392
+ ```ruby
393
+ begin
394
+ meeting = Fathom::Meeting.retrieve("invalid_id")
395
+ rescue Fathom::AuthenticationError => e
396
+ # 401 - Invalid API key
397
+ puts "Authentication failed: #{e.message}"
398
+ rescue Fathom::NotFoundError => e
399
+ # 404 - Resource not found
400
+ puts "Meeting not found: #{e.message}"
401
+ rescue Fathom::RateLimitError => e
402
+ # 429 - Rate limit exceeded
403
+ puts "Rate limited: #{e.message}"
404
+ rescue Fathom::BadRequestError => e
405
+ # 400 - Bad request
406
+ puts "Bad request: #{e.message}"
407
+ rescue Fathom::ForbiddenError => e
408
+ # 403 - Forbidden
409
+ puts "Access forbidden: #{e.message}"
410
+ rescue Fathom::ServerError => e
411
+ # 5xx - Server error
412
+ puts "Server error: #{e.message}"
413
+ rescue Fathom::Error => e
414
+ # Any other Fathom error
415
+ puts "Error: #{e.message}"
416
+ end
417
+ ```
418
+
419
+ All error objects include:
420
+
421
+ - `message` - Human-readable error message
422
+ - `http_status` - HTTP status code
423
+ - `response` - Raw response object
424
+
425
+ ## Dynamic Attribute Access
426
+
427
+ All resources support dynamic attribute access:
428
+
429
+ ```ruby
430
+ meeting = Fathom::Meeting.retrieve("meeting_id")
431
+
432
+ # Access attributes
433
+ meeting.title
434
+ meeting.summary
435
+ meeting["custom_field"]
436
+
437
+ # Set attributes
438
+ meeting.title = "New Title"
439
+ meeting["custom_field"] = "value"
440
+
441
+ # Convert to hash
442
+ meeting.to_h
443
+
444
+ # Convert to JSON
445
+ meeting.to_json
446
+ ```
447
+
448
+ ## Debugging
449
+
450
+ Enable debug logging to see what's happening:
451
+
452
+ ```ruby
453
+ # Basic debug logging
454
+ Fathom.debug = true
455
+
456
+ # HTTP request/response logging
457
+ Fathom.debug_http = true
458
+
459
+ # Now all API calls will be logged
460
+ meetings = Fathom::Meeting.all
461
+ # [Fathom] Rate limit: 59/60, resets in 60s
462
+ # [Fathom HTTP] GET https://api.fathom.ai/v1/meetings
463
+ # [Fathom HTTP] Response: 200 OK
464
+ ```
465
+
466
+ ### Testing live
467
+ Check [Test Live API Readme](./scripts/README.md) for instructions to test the API using a real API Key.
468
+
469
+ ## Development
470
+
471
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
472
+
473
+ ### Running Tests
474
+
475
+ ```bash
476
+ bundle exec rspec
477
+ ```
478
+
479
+ ### Running Rubocop
480
+
481
+ ```bash
482
+ bundle exec rubocop
483
+ ```
484
+
485
+ ## Contributing
486
+
487
+ Bug reports and pull requests are welcome on GitHub at https://github.com/yourusername/fathom-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](CODE_OF_CONDUCT.md).
488
+
489
+ 1. Fork it
490
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
491
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
492
+ 4. Push to the branch (`git push origin my-new-feature`)
493
+ 5. Create a new Pull Request
494
+
495
+ ## License
496
+
497
+ The gem is available as open source under the terms of the [MIT License](LICENSE).
498
+
499
+ ## Code of Conduct
500
+
501
+ Everyone interacting in the Fathom Ruby project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
502
+
503
+ ## Links
504
+
505
+ - [Fathom API Documentation](https://developers.fathom.ai)
506
+ - [Gem Documentation](https://rubydoc.info/gems/fathom-ruby)
507
+ - [GitHub Repository](https://github.com/yourusername/fathom-ruby)
508
+ - [Bug Reports](https://github.com/yourusername/fathom-ruby/issues)
509
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new
9
+
10
+ task default: %i[spec rubocop]