bundleup-sdk 0.2.1 โ 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +224 -49
- data/lib/bundleup/client.rb +6 -6
- data/lib/bundleup/proxy.rb +1 -1
- data/lib/bundleup/resources/base.rb +1 -1
- data/lib/bundleup/resources/connection.rb +1 -1
- data/lib/bundleup/resources/integration.rb +1 -1
- data/lib/bundleup/resources/webhook.rb +1 -1
- data/lib/bundleup/unify/base.rb +1 -1
- data/lib/bundleup/unify/chat.rb +25 -1
- data/lib/bundleup/unify/crm.rb +30 -0
- data/lib/bundleup/unify/drive.rb +19 -0
- data/lib/bundleup/unify/git.rb +14 -1
- data/lib/bundleup/unify/ticketing.rb +19 -0
- data/lib/bundleup/unify.rb +33 -4
- data/lib/bundleup/version.rb +2 -2
- data/lib/bundleup.rb +4 -2
- data/sig/bundleup/unify/base.rbs +17 -0
- data/sig/bundleup/unify/chat.rbs +13 -0
- data/sig/bundleup/unify/crm.rbs +12 -0
- data/sig/bundleup/unify/drive.rbs +20 -0
- data/sig/bundleup/unify/git.rbs +53 -0
- data/sig/bundleup/unify/ticketing.rbs +19 -0
- data/sig/bundleup/unify.rbs +16 -0
- metadata +40 -3
- data/lib/bundleup/unify/pm.rb +0 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6e385086d7a4207cb36ec82ac134eab03155093407c098488ea40478d62f79d3
|
|
4
|
+
data.tar.gz: ca70fa9281ad486160c66a731e81c0ad56f200ad4e8fccf15e818340e43ea5d6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9245dcc515bff7307c4073bbc223ce3b2e5bdd8e3ff91dbb83cfdf95437c89bc7e03a7c3b8c9c0db0ca2bb0962df0c9597d127c0a3209d2bcb909e934c787f65
|
|
7
|
+
data.tar.gz: e472e19410d920eb5fbbe6abab03c2af1d1ea05945d7249d1be90c7d47ab7375d67dc503ba2698e57ce7b40ed9fed423400847b3dffefde47b51931c5ee74117
|
data/README.md
CHANGED
|
@@ -10,6 +10,7 @@ Official Ruby SDK for the [BundleUp](https://bundleup.io) API. Connect to 100+ i
|
|
|
10
10
|
- [Installation](#installation)
|
|
11
11
|
- [Requirements](#requirements)
|
|
12
12
|
- [Features](#features)
|
|
13
|
+
- [Examples](#examples)
|
|
13
14
|
- [Quick Start](#quick-start)
|
|
14
15
|
- [Authentication](#authentication)
|
|
15
16
|
- [Core Concepts](#core-concepts)
|
|
@@ -23,7 +24,6 @@ Official Ruby SDK for the [BundleUp](https://bundleup.io) API. Connect to 100+ i
|
|
|
23
24
|
- [Development](#development)
|
|
24
25
|
- [Contributing](#contributing)
|
|
25
26
|
- [License](#license)
|
|
26
|
-
- [Support](#support)
|
|
27
27
|
|
|
28
28
|
## Installation
|
|
29
29
|
|
|
@@ -77,6 +77,15 @@ The BundleUp SDK is tested and supported on:
|
|
|
77
77
|
- ๐ **Well Documented** - Extensive documentation and examples
|
|
78
78
|
- ๐งช **Tested** - Comprehensive test suite with RSpec
|
|
79
79
|
|
|
80
|
+
## Examples
|
|
81
|
+
|
|
82
|
+
Runnable examples are available in the [`examples/`](./examples) directory:
|
|
83
|
+
|
|
84
|
+
- [`examples/basic_usage.rb`](./examples/basic_usage.rb) - Client setup, connections, integrations, and webhooks
|
|
85
|
+
- [`examples/proxy_api.rb`](./examples/proxy_api.rb) - Proxy API GET request with a connection
|
|
86
|
+
- [`examples/unify_api.rb`](./examples/unify_api.rb) - Unify Chat, Git, PM, Ticketing, and Drive endpoint usage
|
|
87
|
+
- [`examples/README.md`](./examples/README.md) - Setup and execution instructions
|
|
88
|
+
|
|
80
89
|
## Quick Start
|
|
81
90
|
|
|
82
91
|
Get started with BundleUp in just a few lines of code:
|
|
@@ -85,7 +94,7 @@ Get started with BundleUp in just a few lines of code:
|
|
|
85
94
|
require 'bundleup'
|
|
86
95
|
|
|
87
96
|
# Initialize the client
|
|
88
|
-
client =
|
|
97
|
+
client = BundleUp::Client.new(ENV['BUNDLEUP_API_KEY'])
|
|
89
98
|
|
|
90
99
|
# List all active connections
|
|
91
100
|
connections = client.connections.list
|
|
@@ -119,10 +128,10 @@ The BundleUp SDK uses API keys for authentication. You can obtain your API key f
|
|
|
119
128
|
require 'bundleup'
|
|
120
129
|
|
|
121
130
|
# Initialize with API key
|
|
122
|
-
client =
|
|
131
|
+
client = BundleUp::Client.new('your_api_key_here')
|
|
123
132
|
|
|
124
133
|
# Or use environment variable (recommended)
|
|
125
|
-
client =
|
|
134
|
+
client = BundleUp::Client.new(ENV['BUNDLEUP_API_KEY'])
|
|
126
135
|
```
|
|
127
136
|
|
|
128
137
|
### Security Best Practices
|
|
@@ -154,14 +163,14 @@ Then in your application:
|
|
|
154
163
|
require 'dotenv/load'
|
|
155
164
|
require 'bundleup'
|
|
156
165
|
|
|
157
|
-
client =
|
|
166
|
+
client = BundleUp::Client.new(ENV['BUNDLEUP_API_KEY'])
|
|
158
167
|
```
|
|
159
168
|
|
|
160
169
|
**For Rails applications:**
|
|
161
170
|
|
|
162
171
|
```ruby
|
|
163
172
|
# config/initializers/bundleup.rb
|
|
164
|
-
BUNDLEUP_CLIENT =
|
|
173
|
+
BUNDLEUP_CLIENT = BundleUp::Client.new(ENV['BUNDLEUP_API_KEY'])
|
|
165
174
|
```
|
|
166
175
|
|
|
167
176
|
## Core Concepts
|
|
@@ -472,7 +481,7 @@ class WebhooksController < ApplicationController
|
|
|
472
481
|
skip_before_action :verify_authenticity_token
|
|
473
482
|
|
|
474
483
|
def create
|
|
475
|
-
signature = request.headers['
|
|
484
|
+
signature = request.headers['BundleUp-Signature']
|
|
476
485
|
payload = request.body.read
|
|
477
486
|
|
|
478
487
|
unless verify_signature(payload, signature)
|
|
@@ -631,6 +640,43 @@ unify = client.unify('conn_123abc')
|
|
|
631
640
|
|
|
632
641
|
The Chat API provides a unified interface for chat platforms like Slack, Discord, and Microsoft Teams.
|
|
633
642
|
|
|
643
|
+
##### List Users
|
|
644
|
+
|
|
645
|
+
Retrieve a list of users from the connected chat platform.
|
|
646
|
+
|
|
647
|
+
```ruby
|
|
648
|
+
result = unify.chat.users(
|
|
649
|
+
limit: 100,
|
|
650
|
+
after: nil,
|
|
651
|
+
include_raw: false
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
puts "Users: #{result['data']}"
|
|
655
|
+
puts "Next cursor: #{result['metadata']['next']}"
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
**Parameters:**
|
|
659
|
+
|
|
660
|
+
- `limit` (Integer, optional): Maximum number of users to return (default: 100, max: 1000)
|
|
661
|
+
- `after` (String, optional): Pagination cursor from previous response
|
|
662
|
+
- `include_raw` (Boolean, optional): Include raw API response from the integration (default: false)
|
|
663
|
+
|
|
664
|
+
**Response:**
|
|
665
|
+
|
|
666
|
+
```ruby
|
|
667
|
+
{
|
|
668
|
+
'data' => [
|
|
669
|
+
{
|
|
670
|
+
'id' => 'U1234567890',
|
|
671
|
+
'name' => 'Jane Doe'
|
|
672
|
+
}
|
|
673
|
+
],
|
|
674
|
+
'metadata' => {
|
|
675
|
+
'next' => 'cursor_abc123'
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
```
|
|
679
|
+
|
|
634
680
|
##### List Channels
|
|
635
681
|
|
|
636
682
|
Retrieve a list of channels from the connected chat platform.
|
|
@@ -691,6 +737,31 @@ end
|
|
|
691
737
|
puts "Fetched #{all_channels.length} total channels"
|
|
692
738
|
```
|
|
693
739
|
|
|
740
|
+
##### Send Message
|
|
741
|
+
|
|
742
|
+
Send a message to a channel on the connected chat platform.
|
|
743
|
+
|
|
744
|
+
```ruby
|
|
745
|
+
result = unify.chat.message('C1234567890', 'Hello from BundleUp! :wave:')
|
|
746
|
+
|
|
747
|
+
puts "Message sent: #{result['data']}"
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
**Parameters:**
|
|
751
|
+
|
|
752
|
+
- `channel_id` (String, required): The ID of the channel to send the message to
|
|
753
|
+
- `text` (String, required): Markdown-formatted message text
|
|
754
|
+
|
|
755
|
+
**Response:**
|
|
756
|
+
|
|
757
|
+
```ruby
|
|
758
|
+
{
|
|
759
|
+
'data' => {
|
|
760
|
+
# Raw response data from the chat provider
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
```
|
|
764
|
+
|
|
694
765
|
#### Git API
|
|
695
766
|
|
|
696
767
|
The Git API provides a unified interface for version control platforms like GitHub, GitLab, and Bitbucket.
|
|
@@ -831,20 +902,45 @@ puts "Releases: #{result['data']}"
|
|
|
831
902
|
}
|
|
832
903
|
```
|
|
833
904
|
|
|
834
|
-
|
|
905
|
+
##### List Branches
|
|
906
|
+
|
|
907
|
+
```ruby
|
|
908
|
+
result = unify.git.branches('organization/repo-name', limit: 50)
|
|
909
|
+
|
|
910
|
+
puts "Branches: #{result['data']}"
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
**Response:**
|
|
914
|
+
|
|
915
|
+
```ruby
|
|
916
|
+
{
|
|
917
|
+
'data' => [
|
|
918
|
+
{
|
|
919
|
+
'name' => 'main',
|
|
920
|
+
'commit_sha' => 'abc123def456',
|
|
921
|
+
'protected' => true
|
|
922
|
+
}
|
|
923
|
+
],
|
|
924
|
+
'metadata' => {
|
|
925
|
+
'next' => nil
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
```
|
|
929
|
+
|
|
930
|
+
#### Ticketing API
|
|
835
931
|
|
|
836
|
-
The
|
|
932
|
+
The Ticketing API provides a unified interface for ticketing and project management platforms like Jira, Linear, and Asana.
|
|
837
933
|
|
|
838
|
-
##### List
|
|
934
|
+
##### List Tickets
|
|
839
935
|
|
|
840
936
|
```ruby
|
|
841
|
-
result = unify.
|
|
937
|
+
result = unify.ticketing.tickets(
|
|
842
938
|
limit: 100,
|
|
843
939
|
after: nil,
|
|
844
940
|
include_raw: false
|
|
845
941
|
)
|
|
846
942
|
|
|
847
|
-
puts "
|
|
943
|
+
puts "Tickets: #{result['data']}"
|
|
848
944
|
```
|
|
849
945
|
|
|
850
946
|
**Response:**
|
|
@@ -871,8 +967,108 @@ puts "Issues: #{result['data']}"
|
|
|
871
967
|
**Filtering and sorting:**
|
|
872
968
|
|
|
873
969
|
```ruby
|
|
874
|
-
|
|
875
|
-
sorted_by_date = result['data'].sort_by { |
|
|
970
|
+
open_tickets = result['data'].select { |ticket| ticket['status'] == 'open' }
|
|
971
|
+
sorted_by_date = result['data'].sort_by { |ticket| Time.parse(ticket['created_at']) }.reverse
|
|
972
|
+
```
|
|
973
|
+
|
|
974
|
+
#### CRM API
|
|
975
|
+
|
|
976
|
+
The CRM API provides a unified interface for CRM platforms like Attio, HubSpot, PipeDrive, Salesforce and Zoho.
|
|
977
|
+
|
|
978
|
+
##### List Companies
|
|
979
|
+
|
|
980
|
+
```ruby
|
|
981
|
+
result = unify.crm.companies(
|
|
982
|
+
limit: 100,
|
|
983
|
+
after: nil,
|
|
984
|
+
include_raw: false
|
|
985
|
+
)
|
|
986
|
+
|
|
987
|
+
puts "Companies: #{result['data']}"
|
|
988
|
+
```
|
|
989
|
+
|
|
990
|
+
**Response:**
|
|
991
|
+
|
|
992
|
+
```ruby
|
|
993
|
+
{
|
|
994
|
+
'data' => [
|
|
995
|
+
{
|
|
996
|
+
'id' => '12345',
|
|
997
|
+
'name' => 'Acme Inc.',
|
|
998
|
+
'website' => 'https://acme.example.com'
|
|
999
|
+
}
|
|
1000
|
+
],
|
|
1001
|
+
'metadata' => {
|
|
1002
|
+
'next' => nil
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
##### List Contacts
|
|
1008
|
+
|
|
1009
|
+
```ruby
|
|
1010
|
+
result = unify.crm.contacts(
|
|
1011
|
+
limit: 100,
|
|
1012
|
+
after: nil,
|
|
1013
|
+
include_raw: false
|
|
1014
|
+
)
|
|
1015
|
+
|
|
1016
|
+
puts "Contacts: #{result['data']}"
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
**Response:**
|
|
1020
|
+
|
|
1021
|
+
```ruby
|
|
1022
|
+
{
|
|
1023
|
+
'data' => [
|
|
1024
|
+
{
|
|
1025
|
+
'id' => '67890',
|
|
1026
|
+
'name' => 'Jane Doe',
|
|
1027
|
+
'email' => 'jane@acme.example.com'
|
|
1028
|
+
}
|
|
1029
|
+
],
|
|
1030
|
+
'metadata' => {
|
|
1031
|
+
'next' => nil
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
#### Drive API
|
|
1037
|
+
|
|
1038
|
+
The Drive API provides a unified interface for file storage platforms like Google Drive, OneDrive, Box, Dropbox and Microsoft SharePoint.
|
|
1039
|
+
|
|
1040
|
+
##### List Files
|
|
1041
|
+
|
|
1042
|
+
```ruby
|
|
1043
|
+
result = unify.drive.files(
|
|
1044
|
+
limit: 100,
|
|
1045
|
+
after: nil,
|
|
1046
|
+
include_raw: false
|
|
1047
|
+
)
|
|
1048
|
+
|
|
1049
|
+
puts "Files: #{result['data']}"
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
**Response:**
|
|
1053
|
+
|
|
1054
|
+
```ruby
|
|
1055
|
+
{
|
|
1056
|
+
'data' => [
|
|
1057
|
+
{
|
|
1058
|
+
'id' => 'file_123',
|
|
1059
|
+
'name' => 'quarterly-report.pdf',
|
|
1060
|
+
'mime_type' => 'application/pdf',
|
|
1061
|
+
'size' => 204800,
|
|
1062
|
+
'created_at' => '2024-01-15T10:30:00Z',
|
|
1063
|
+
'updated_at' => '2024-01-20T14:22:00Z',
|
|
1064
|
+
'url' => 'https://drive.example.com/file_123',
|
|
1065
|
+
'is_folder' => false
|
|
1066
|
+
}
|
|
1067
|
+
],
|
|
1068
|
+
'metadata' => {
|
|
1069
|
+
'next' => nil
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
876
1072
|
```
|
|
877
1073
|
|
|
878
1074
|
## Error Handling
|
|
@@ -928,10 +1124,22 @@ lib/
|
|
|
928
1124
|
โ โโโ base.rb # Base Unify class
|
|
929
1125
|
โ โโโ chat.rb # Chat Unify API
|
|
930
1126
|
โ โโโ git.rb # Git Unify API
|
|
931
|
-
โ
|
|
1127
|
+
โ โโโ ticketing.rb # Ticketing Unify API
|
|
1128
|
+
โ โโโ crm.rb # CRM Unify API
|
|
1129
|
+
โ โโโ drive.rb # Drive Unify API
|
|
1130
|
+
sig/ # RBS type signatures (mirrors lib/)
|
|
932
1131
|
spec/ # Test files
|
|
933
1132
|
```
|
|
934
1133
|
|
|
1134
|
+
### Type Signatures
|
|
1135
|
+
|
|
1136
|
+
The gem ships [RBS](https://github.com/ruby/rbs) signatures for the Unify API under `sig/bundleup/unify/`. They're optional at runtime (deleting `sig/` doesn't change behavior) but give editors and `rbs` itself static types for `unify.chat.channels`, `unify.git.repos`, and so on.
|
|
1137
|
+
|
|
1138
|
+
```bash
|
|
1139
|
+
# Validate the signature files
|
|
1140
|
+
bundle exec rake sig
|
|
1141
|
+
```
|
|
1142
|
+
|
|
935
1143
|
### Running Tests
|
|
936
1144
|
|
|
937
1145
|
```bash
|
|
@@ -1019,7 +1227,7 @@ We welcome contributions to the BundleUp Ruby SDK! Here's how you can help:
|
|
|
1019
1227
|
This gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
1020
1228
|
|
|
1021
1229
|
```
|
|
1022
|
-
Copyright (c)
|
|
1230
|
+
Copyright (c) 2026 BundleUp
|
|
1023
1231
|
|
|
1024
1232
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1025
1233
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1040,39 +1248,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
1040
1248
|
SOFTWARE.
|
|
1041
1249
|
```
|
|
1042
1250
|
|
|
1043
|
-
## Support
|
|
1044
|
-
|
|
1045
|
-
Need help? We're here for you!
|
|
1046
|
-
|
|
1047
|
-
### Documentation
|
|
1048
|
-
|
|
1049
|
-
- **Official Docs**: [https://docs.bundleup.io](https://docs.bundleup.io)
|
|
1050
|
-
- **API Reference**: [https://docs.bundleup.io/api](https://docs.bundleup.io/api)
|
|
1051
|
-
- **SDK Guides**: [https://docs.bundleup.io/sdk/ruby](https://docs.bundleup.io/sdk/ruby)
|
|
1052
|
-
|
|
1053
|
-
### Community
|
|
1054
|
-
|
|
1055
|
-
- **Discord**: [https://discord.gg/bundleup](https://discord.gg/bundleup)
|
|
1056
|
-
- **GitHub Discussions**: [https://github.com/bundleup/bundleup-sdk-ruby/discussions](https://github.com/bundleup/bundleup-sdk-ruby/discussions)
|
|
1057
|
-
- **Stack Overflow**: Tag your questions with `bundleup`
|
|
1058
|
-
|
|
1059
|
-
### Direct Support
|
|
1060
|
-
|
|
1061
|
-
- **Email**: [support@bundleup.io](mailto:support@bundleup.io)
|
|
1062
|
-
- **GitHub Issues**: [https://github.com/bundleup/bundleup-sdk-ruby/issues](https://github.com/bundleup/bundleup-sdk-ruby/issues)
|
|
1063
|
-
- **Twitter**: [@bundleup_io](https://twitter.com/bundleup_io)
|
|
1064
|
-
|
|
1065
|
-
### Enterprise Support
|
|
1066
|
-
|
|
1067
|
-
For enterprise customers, we offer:
|
|
1068
|
-
|
|
1069
|
-
- Priority support with SLA
|
|
1070
|
-
- Dedicated support channel
|
|
1071
|
-
- Architecture consultation
|
|
1072
|
-
- Custom integration assistance
|
|
1073
|
-
|
|
1074
|
-
Contact [enterprise@bundleup.io](mailto:enterprise@bundleup.io) for more information.
|
|
1075
|
-
|
|
1076
1251
|
## Code of Conduct
|
|
1077
1252
|
|
|
1078
1253
|
Everyone interacting in the BundleUp project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/bundleup/bundleup-sdk-ruby/blob/main/CODE_OF_CONDUCT).
|
data/lib/bundleup/client.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module BundleUp
|
|
4
4
|
# Client for core BundleUp API resources.
|
|
5
5
|
class Client
|
|
6
6
|
attr_reader :api_key
|
|
@@ -12,15 +12,15 @@ module Bundleup
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def connections
|
|
15
|
-
@connections ||=
|
|
15
|
+
@connections ||= BundleUp::Resources::Connection.new(@api_key)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def integrations
|
|
19
|
-
@integrations ||=
|
|
19
|
+
@integrations ||= BundleUp::Resources::Integration.new(@api_key)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def webhooks
|
|
23
|
-
@webhooks ||=
|
|
23
|
+
@webhooks ||= BundleUp::Resources::Webhook.new(@api_key)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def proxy(connection_id)
|
|
@@ -28,7 +28,7 @@ module Bundleup
|
|
|
28
28
|
raise ArgumentError, 'Connection ID is required to create a Proxy instance.'
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
BundleUp::Proxy.new(@api_key, connection_id)
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def unify(connection_id)
|
|
@@ -36,7 +36,7 @@ module Bundleup
|
|
|
36
36
|
raise ArgumentError, 'Connection ID is required to create a Unify instance.'
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
BundleUp::Unify::Client.new(@api_key, connection_id)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|
data/lib/bundleup/proxy.rb
CHANGED
data/lib/bundleup/unify/base.rb
CHANGED
data/lib/bundleup/unify/chat.rb
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module BundleUp
|
|
4
4
|
module Unify
|
|
5
5
|
# Client for chat-related Unify endpoints.
|
|
6
6
|
class Chat < Base
|
|
7
|
+
# Fetches users from the connected chat provider.
|
|
8
|
+
def users(params = {})
|
|
9
|
+
response = connection.get('chat/users') do |req|
|
|
10
|
+
req.params = params
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
raise "Failed to fetch chat/users: #{response.status}" unless response.success?
|
|
14
|
+
|
|
15
|
+
response.body
|
|
16
|
+
end
|
|
17
|
+
|
|
7
18
|
# Fetches channels from the connected chat provider.
|
|
8
19
|
def channels(params = {})
|
|
9
20
|
response = connection.get('chat/channels') do |req|
|
|
@@ -14,6 +25,19 @@ module Bundleup
|
|
|
14
25
|
|
|
15
26
|
response.body
|
|
16
27
|
end
|
|
28
|
+
|
|
29
|
+
# Sends a message to a channel on the connected chat provider.
|
|
30
|
+
def message(channel_id, text)
|
|
31
|
+
raise ArgumentError, 'channel_id is required to send a message.' if channel_id.nil?
|
|
32
|
+
|
|
33
|
+
encoded_channel_id = URI.encode_www_form_component(channel_id)
|
|
34
|
+
|
|
35
|
+
response = connection.post("chat/channels/#{encoded_channel_id}/message", { text: text }.to_json)
|
|
36
|
+
|
|
37
|
+
raise "Failed to post chat/channels/#{encoded_channel_id}/message: #{response.status}" unless response.success?
|
|
38
|
+
|
|
39
|
+
response.body
|
|
40
|
+
end
|
|
17
41
|
end
|
|
18
42
|
end
|
|
19
43
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BundleUp
|
|
4
|
+
module Unify
|
|
5
|
+
# Client for CRM-related Unify endpoints.
|
|
6
|
+
class CRM < Base
|
|
7
|
+
# Fetches companies from the connected CRM provider.
|
|
8
|
+
def companies(params = {})
|
|
9
|
+
response = connection.get('crm/companies') do |req|
|
|
10
|
+
req.params = params
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
raise "Failed to fetch crm/companies: #{response.status}" unless response.success?
|
|
14
|
+
|
|
15
|
+
response.body
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Fetches contacts from the connected CRM provider.
|
|
19
|
+
def contacts(params = {})
|
|
20
|
+
response = connection.get('crm/contacts') do |req|
|
|
21
|
+
req.params = params
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
raise "Failed to fetch crm/contacts: #{response.status}" unless response.success?
|
|
25
|
+
|
|
26
|
+
response.body
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BundleUp
|
|
4
|
+
module Unify
|
|
5
|
+
# Client for Drive-related Unify endpoints.
|
|
6
|
+
class Drive < Base
|
|
7
|
+
# Fetches files from the connected Drive provider.
|
|
8
|
+
def files(params = {})
|
|
9
|
+
response = connection.get('drive/files') do |req|
|
|
10
|
+
req.params = params
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
raise "Failed to fetch drive/files: #{response.status}" unless response.success?
|
|
14
|
+
|
|
15
|
+
response.body
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/bundleup/unify/git.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module BundleUp
|
|
4
4
|
module Unify
|
|
5
5
|
# Client for Git Unify endpoints.
|
|
6
6
|
class Git < Base
|
|
@@ -53,6 +53,19 @@ module Bundleup
|
|
|
53
53
|
|
|
54
54
|
response.body
|
|
55
55
|
end
|
|
56
|
+
|
|
57
|
+
# Fetches branches for a specific repository from the connected Git provider.
|
|
58
|
+
def branches(repo_name, params = {})
|
|
59
|
+
encoded_repo_name = URI.encode_www_form_component(repo_name)
|
|
60
|
+
|
|
61
|
+
response = connection.get("git/repos/#{encoded_repo_name}/branches") do |req|
|
|
62
|
+
req.params = params
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
raise "Failed to fetch git/repos/#{encoded_repo_name}/branches: #{response.status}" unless response.success?
|
|
66
|
+
|
|
67
|
+
response.body
|
|
68
|
+
end
|
|
56
69
|
end
|
|
57
70
|
end
|
|
58
71
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BundleUp
|
|
4
|
+
module Unify
|
|
5
|
+
# Client for ticketing Unify endpoints.
|
|
6
|
+
class Ticketing < Base
|
|
7
|
+
# Fetches tickets from the connected ticketing tool.
|
|
8
|
+
def tickets(params = {})
|
|
9
|
+
response = connection.get('ticketing/tickets') do |req|
|
|
10
|
+
req.params = params
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
raise "Failed to fetch ticketing/tickets: #{response.status}" unless response.success?
|
|
14
|
+
|
|
15
|
+
response.body
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/bundleup/unify.rb
CHANGED
|
@@ -1,15 +1,44 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module BundleUp
|
|
4
4
|
module Unify
|
|
5
5
|
# Client for Unify API endpoints.
|
|
6
6
|
class Client
|
|
7
7
|
attr_reader :api_key, :connection_id
|
|
8
8
|
|
|
9
9
|
def initialize(api_key, connection_id)
|
|
10
|
-
@
|
|
11
|
-
@chat =
|
|
12
|
-
@git =
|
|
10
|
+
@ticketing = BundleUp::Unify::Ticketing.new(api_key, connection_id)
|
|
11
|
+
@chat = BundleUp::Unify::Chat.new(api_key, connection_id)
|
|
12
|
+
@git = BundleUp::Unify::Git.new(api_key, connection_id)
|
|
13
|
+
@crm = BundleUp::Unify::CRM.new(api_key, connection_id)
|
|
14
|
+
@drive = BundleUp::Unify::Drive.new(api_key, connection_id)
|
|
15
|
+
@api_key = api_key
|
|
16
|
+
@connection_id = connection_id
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Access the Chat API for the connection.
|
|
20
|
+
def chat
|
|
21
|
+
@chat ||= BundleUp::Unify::Chat.new(api_key, connection_id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Access the Git API for the connection.
|
|
25
|
+
def git
|
|
26
|
+
@git ||= BundleUp::Unify::Git.new(api_key, connection_id)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Access the CRM API for the connection.
|
|
30
|
+
def crm
|
|
31
|
+
@crm ||= BundleUp::Unify::CRM.new(api_key, connection_id)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Access the Ticketing API for the connection.
|
|
35
|
+
def ticketing
|
|
36
|
+
@ticketing ||= BundleUp::Unify::Ticketing.new(api_key, connection_id)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Access the Drive API for the connection.
|
|
40
|
+
def drive
|
|
41
|
+
@drive ||= BundleUp::Unify::Drive.new(api_key, connection_id)
|
|
13
42
|
end
|
|
14
43
|
end
|
|
15
44
|
end
|
data/lib/bundleup/version.rb
CHANGED
data/lib/bundleup.rb
CHANGED
|
@@ -17,8 +17,10 @@ require_relative 'bundleup/resources/webhook'
|
|
|
17
17
|
require_relative 'bundleup/unify/base'
|
|
18
18
|
require_relative 'bundleup/unify/chat'
|
|
19
19
|
require_relative 'bundleup/unify/git'
|
|
20
|
-
require_relative 'bundleup/unify/
|
|
20
|
+
require_relative 'bundleup/unify/ticketing'
|
|
21
|
+
require_relative 'bundleup/unify/crm'
|
|
22
|
+
require_relative 'bundleup/unify/drive'
|
|
21
23
|
|
|
22
24
|
# Main module for the BundleUp SDK.
|
|
23
|
-
module
|
|
25
|
+
module BundleUp
|
|
24
26
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module BundleUp
|
|
2
|
+
module Unify
|
|
3
|
+
class Base
|
|
4
|
+
BASE_URL: String
|
|
5
|
+
API_VERSION: String
|
|
6
|
+
|
|
7
|
+
attr_reader api_key: String
|
|
8
|
+
attr_reader connection_id: String
|
|
9
|
+
|
|
10
|
+
def initialize: (String api_key, String connection_id) -> void
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def connection: () -> Faraday::Connection
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module BundleUp
|
|
2
|
+
module Unify
|
|
3
|
+
class Chat < Base
|
|
4
|
+
type chat_user = { id: String, name: String }
|
|
5
|
+
type chat_channel = { id: String, name: String }
|
|
6
|
+
type metadata = { next: String? }
|
|
7
|
+
|
|
8
|
+
def users: (?Hash[Symbol, untyped] params) -> { data: Array[chat_user], metadata: metadata }
|
|
9
|
+
def channels: (?Hash[Symbol, untyped] params) -> { data: Array[chat_channel], metadata: metadata }
|
|
10
|
+
def message: (String channel_id, String text) -> { data: Hash[String, untyped] }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module BundleUp
|
|
2
|
+
module Unify
|
|
3
|
+
class CRM < Base
|
|
4
|
+
type crm_company = { id: String, name: String, website: String? }
|
|
5
|
+
type crm_contact = { id: String, name: String, email: String? }
|
|
6
|
+
type metadata = { next: String? }
|
|
7
|
+
|
|
8
|
+
def companies: (?Hash[Symbol, untyped] params) -> { data: Array[crm_company], metadata: metadata }
|
|
9
|
+
def contacts: (?Hash[Symbol, untyped] params) -> { data: Array[crm_contact], metadata: metadata }
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module BundleUp
|
|
2
|
+
module Unify
|
|
3
|
+
class Drive < Base
|
|
4
|
+
type drive_file = {
|
|
5
|
+
id: String,
|
|
6
|
+
name: String,
|
|
7
|
+
mime_type: String?,
|
|
8
|
+
size: Integer?,
|
|
9
|
+
created_at: String?,
|
|
10
|
+
updated_at: String?,
|
|
11
|
+
url: String?,
|
|
12
|
+
is_folder: bool
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type metadata = { next: String? }
|
|
16
|
+
|
|
17
|
+
def files: (?Hash[Symbol, untyped] params) -> { data: Array[drive_file], metadata: metadata }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module BundleUp
|
|
2
|
+
module Unify
|
|
3
|
+
class Git < Base
|
|
4
|
+
type git_repo = {
|
|
5
|
+
id: Integer | String,
|
|
6
|
+
name: String,
|
|
7
|
+
full_name: String,
|
|
8
|
+
description: String?,
|
|
9
|
+
url: String,
|
|
10
|
+
created_at: String,
|
|
11
|
+
updated_at: String,
|
|
12
|
+
pushed_at: String
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type git_pull = {
|
|
16
|
+
id: Integer,
|
|
17
|
+
number: Integer,
|
|
18
|
+
title: String,
|
|
19
|
+
description: String?,
|
|
20
|
+
draft: bool,
|
|
21
|
+
state: String,
|
|
22
|
+
url: String,
|
|
23
|
+
user: String,
|
|
24
|
+
created_at: String,
|
|
25
|
+
updated_at: String,
|
|
26
|
+
merged_at: String?
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type git_tag = { name: String, commit_sha: String }
|
|
30
|
+
|
|
31
|
+
type git_release = {
|
|
32
|
+
id: Integer,
|
|
33
|
+
name: String,
|
|
34
|
+
tag_name: String,
|
|
35
|
+
description: String,
|
|
36
|
+
prerelease: bool,
|
|
37
|
+
url: String,
|
|
38
|
+
created_at: String,
|
|
39
|
+
released_at: String
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type git_branch = { name: String, commit_sha: String, protected: bool }
|
|
43
|
+
|
|
44
|
+
type metadata = { next: String? }
|
|
45
|
+
|
|
46
|
+
def repos: (?Hash[Symbol, untyped] params) -> { data: Array[git_repo], metadata: metadata }
|
|
47
|
+
def pulls: (String repo_name, ?Hash[Symbol, untyped] params) -> { data: Array[git_pull], metadata: metadata }
|
|
48
|
+
def tags: (String repo_name, ?Hash[Symbol, untyped] params) -> { data: Array[git_tag], metadata: metadata }
|
|
49
|
+
def releases: (String repo_name, ?Hash[Symbol, untyped] params) -> { data: Array[git_release], metadata: metadata }
|
|
50
|
+
def branches: (String repo_name, ?Hash[Symbol, untyped] params) -> { data: Array[git_branch], metadata: metadata }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module BundleUp
|
|
2
|
+
module Unify
|
|
3
|
+
class Ticketing < Base
|
|
4
|
+
type ticketing_ticket = {
|
|
5
|
+
id: String,
|
|
6
|
+
title: String,
|
|
7
|
+
status: String,
|
|
8
|
+
url: String,
|
|
9
|
+
description: String?,
|
|
10
|
+
created_at: String,
|
|
11
|
+
updated_at: String
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type metadata = { next: String? }
|
|
15
|
+
|
|
16
|
+
def issues: (?Hash[Symbol, untyped] params) -> { data: Array[ticketing_ticket], metadata: metadata }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module BundleUp
|
|
2
|
+
module Unify
|
|
3
|
+
class Client
|
|
4
|
+
attr_reader api_key: String
|
|
5
|
+
attr_reader connection_id: String
|
|
6
|
+
|
|
7
|
+
def initialize: (String api_key, String connection_id) -> void
|
|
8
|
+
|
|
9
|
+
def chat: () -> Chat
|
|
10
|
+
def git: () -> Git
|
|
11
|
+
def pm: () -> PM
|
|
12
|
+
def crm: () -> CRM
|
|
13
|
+
def drive: () -> Drive
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bundleup-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- BundleUp
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -38,6 +38,20 @@ dependencies:
|
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '13.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rbs
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.0'
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
56
|
name: rspec
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,6 +80,20 @@ dependencies:
|
|
|
66
80
|
- - "~>"
|
|
67
81
|
- !ruby/object:Gem::Version
|
|
68
82
|
version: '1.50'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rubocop-capybara
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "<"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '2.23'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "<"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '2.23'
|
|
69
97
|
- !ruby/object:Gem::Dependency
|
|
70
98
|
name: rubocop-rake
|
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -148,9 +176,18 @@ files:
|
|
|
148
176
|
- lib/bundleup/unify.rb
|
|
149
177
|
- lib/bundleup/unify/base.rb
|
|
150
178
|
- lib/bundleup/unify/chat.rb
|
|
179
|
+
- lib/bundleup/unify/crm.rb
|
|
180
|
+
- lib/bundleup/unify/drive.rb
|
|
151
181
|
- lib/bundleup/unify/git.rb
|
|
152
|
-
- lib/bundleup/unify/
|
|
182
|
+
- lib/bundleup/unify/ticketing.rb
|
|
153
183
|
- lib/bundleup/version.rb
|
|
184
|
+
- sig/bundleup/unify.rbs
|
|
185
|
+
- sig/bundleup/unify/base.rbs
|
|
186
|
+
- sig/bundleup/unify/chat.rbs
|
|
187
|
+
- sig/bundleup/unify/crm.rbs
|
|
188
|
+
- sig/bundleup/unify/drive.rbs
|
|
189
|
+
- sig/bundleup/unify/git.rbs
|
|
190
|
+
- sig/bundleup/unify/ticketing.rbs
|
|
154
191
|
homepage: https://github.com/bundleup/bundleup-sdk-ruby
|
|
155
192
|
licenses:
|
|
156
193
|
- MIT
|
data/lib/bundleup/unify/pm.rb
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Bundleup
|
|
4
|
-
module Unify
|
|
5
|
-
# Client for project management Unify endpoints.
|
|
6
|
-
class PM < Base
|
|
7
|
-
# Fetches issues from the connected project management tool.
|
|
8
|
-
def issues(params = {})
|
|
9
|
-
response = connection.get('pm/issues') do |req|
|
|
10
|
-
req.params = params
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
raise "Failed to fetch pm/issues: #{response.status}" unless response.success?
|
|
14
|
-
|
|
15
|
-
response.body
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|