mural-ruby 0.1.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 +7 -0
- data/.github/workflows/ruby.yml +28 -0
- data/.ruby-version +1 -0
- data/README.md +126 -0
- data/Rakefile +16 -0
- data/UNLICENSE +24 -0
- data/img/draw-widget.png +0 -0
- data/img/inking-widget.png +0 -0
- data/img/mind-map.png +0 -0
- data/img/smart-planner.png +0 -0
- data/lib/mural/asset.rb +26 -0
- data/lib/mural/client/authentication.rb +75 -0
- data/lib/mural/client/mural_content/files.rb +40 -0
- data/lib/mural/client/mural_content/sticky_notes.rb +30 -0
- data/lib/mural/client/mural_content/tags.rb +48 -0
- data/lib/mural/client/mural_content/widgets.rb +33 -0
- data/lib/mural/client/mural_content.rb +30 -0
- data/lib/mural/client/murals.rb +138 -0
- data/lib/mural/client/rooms.rb +92 -0
- data/lib/mural/client/search.rb +55 -0
- data/lib/mural/client/templates.rb +77 -0
- data/lib/mural/client/users/mural_users.rb +67 -0
- data/lib/mural/client/users/room_users.rb +62 -0
- data/lib/mural/client/users.rb +38 -0
- data/lib/mural/client/workspaces.rb +33 -0
- data/lib/mural/client.rb +119 -0
- data/lib/mural/codec.rb +44 -0
- data/lib/mural/create_mural_params.rb +33 -0
- data/lib/mural/create_room_params.rb +16 -0
- data/lib/mural/create_sticky_note_params.rb +37 -0
- data/lib/mural/create_tag_params.rb +45 -0
- data/lib/mural/current_user.rb +21 -0
- data/lib/mural/duplicate_mural_params.rb +14 -0
- data/lib/mural/mural_board.rb +96 -0
- data/lib/mural/mural_export.rb +16 -0
- data/lib/mural/mural_invitation.rb +16 -0
- data/lib/mural/mural_invitation_params.rb +14 -0
- data/lib/mural/mural_user.rb +30 -0
- data/lib/mural/removed_mural_user.rb +14 -0
- data/lib/mural/removed_room_user.rb +14 -0
- data/lib/mural/room.rb +63 -0
- data/lib/mural/room_folder.rb +21 -0
- data/lib/mural/room_invitation.rb +16 -0
- data/lib/mural/room_invitation_params.rb +13 -0
- data/lib/mural/room_user.rb +17 -0
- data/lib/mural/search_mural_result.rb +21 -0
- data/lib/mural/search_room_result.rb +16 -0
- data/lib/mural/search_template_result.rb +18 -0
- data/lib/mural/tag.rb +25 -0
- data/lib/mural/template.rb +24 -0
- data/lib/mural/update_mural_params.rb +23 -0
- data/lib/mural/update_room_params.rb +15 -0
- data/lib/mural/update_room_user_params.rb +16 -0
- data/lib/mural/update_sticky_note_params.rb +24 -0
- data/lib/mural/update_tag_params.rb +22 -0
- data/lib/mural/version.rb +5 -0
- data/lib/mural/widget/area.rb +53 -0
- data/lib/mural/widget/arrow.rb +139 -0
- data/lib/mural/widget/comment.rb +92 -0
- data/lib/mural/widget/create_file_params.rb +56 -0
- data/lib/mural/widget/file.rb +34 -0
- data/lib/mural/widget/icon.rb +34 -0
- data/lib/mural/widget/image.rb +77 -0
- data/lib/mural/widget/shape.rb +79 -0
- data/lib/mural/widget/sticky_note.rb +81 -0
- data/lib/mural/widget/table.rb +54 -0
- data/lib/mural/widget/table_cell.rb +50 -0
- data/lib/mural/widget/text.rb +58 -0
- data/lib/mural/widget/update_file_params.rb +50 -0
- data/lib/mural/widget.rb +158 -0
- data/lib/mural/workspace.rb +47 -0
- data/lib/mural/workspace_invitation.rb +16 -0
- data/lib/mural.rb +27 -0
- metadata +132 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class Client
|
5
|
+
class Rooms
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :@client, :get, :post, :patch, :delete
|
9
|
+
|
10
|
+
def initialize(client)
|
11
|
+
@client = client
|
12
|
+
end
|
13
|
+
|
14
|
+
# https://developers.mural.co/public/reference/createroom
|
15
|
+
def create(params)
|
16
|
+
json = post('/api/public/v1/rooms', params.encode)
|
17
|
+
|
18
|
+
Mural::Room.decode(json['value'])
|
19
|
+
end
|
20
|
+
|
21
|
+
# https://developers.mural.co/public/reference/updateroombyid
|
22
|
+
def update(room_id, params)
|
23
|
+
json = patch("/api/public/v1/rooms/#{room_id}", params.encode)
|
24
|
+
|
25
|
+
Mural::Room.decode(json['value'])
|
26
|
+
end
|
27
|
+
|
28
|
+
# https://developers.mural.co/public/reference/deleteroombyid
|
29
|
+
def destroy(room_id)
|
30
|
+
delete("/api/public/v1/rooms/#{room_id}")
|
31
|
+
end
|
32
|
+
|
33
|
+
# https://developers.mural.co/public/reference/createroomfolder
|
34
|
+
def create_folder(room_id, name:, parent_id: nil)
|
35
|
+
json = post(
|
36
|
+
"/api/public/v1/rooms/#{room_id}/folders",
|
37
|
+
{ name: name, parentId: parent_id }
|
38
|
+
)
|
39
|
+
|
40
|
+
::Mural::RoomFolder.decode(json['value'])
|
41
|
+
end
|
42
|
+
|
43
|
+
# https://developers.mural.co/public/reference/getroomfolders
|
44
|
+
def list_folders(room_id, next_page: nil)
|
45
|
+
json = get(
|
46
|
+
"/api/public/v1/rooms/#{room_id}/folders",
|
47
|
+
{ next: next_page }
|
48
|
+
)
|
49
|
+
|
50
|
+
folders = json['value'].map do |json_folder|
|
51
|
+
::Mural::RoomFolder.decode(json_folder)
|
52
|
+
end
|
53
|
+
|
54
|
+
[folders, json['next']]
|
55
|
+
end
|
56
|
+
|
57
|
+
# https://developers.mural.co/public/reference/deleteroombyid
|
58
|
+
def destroy_folder(room_id, folder_id)
|
59
|
+
delete("/api/public/v1/rooms/#{room_id}/folders/#{folder_id}")
|
60
|
+
end
|
61
|
+
|
62
|
+
# https://developers.mural.co/public/reference/getroominfobyid
|
63
|
+
def retrieve(room_id)
|
64
|
+
json = get("/api/public/v1/rooms/#{room_id}")
|
65
|
+
|
66
|
+
Mural::Room.decode(json['value'])
|
67
|
+
end
|
68
|
+
|
69
|
+
# https://developers.mural.co/public/reference/getworkspacerooms
|
70
|
+
def list(workspace_id, next_page: nil)
|
71
|
+
json = get(
|
72
|
+
"/api/public/v1/workspaces/#{workspace_id}/rooms",
|
73
|
+
{ next: next_page }
|
74
|
+
)
|
75
|
+
|
76
|
+
rooms = json['value'].map { |json_room| Mural::Room.decode(json_room) }
|
77
|
+
[rooms, json['next']]
|
78
|
+
end
|
79
|
+
|
80
|
+
# https://developers.mural.co/public/reference/getworkspaceopenrooms
|
81
|
+
def list_open(workspace_id, next_page: nil)
|
82
|
+
json = get(
|
83
|
+
"/api/public/v1/workspaces/#{workspace_id}/rooms/open",
|
84
|
+
{ next: next_page }
|
85
|
+
)
|
86
|
+
|
87
|
+
rooms = json['value'].map { |json_room| Mural::Room.decode(json_room) }
|
88
|
+
[rooms, json['next']]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class Client
|
5
|
+
class Search
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :@client, :get
|
9
|
+
|
10
|
+
def initialize(client)
|
11
|
+
@client = client
|
12
|
+
end
|
13
|
+
|
14
|
+
# https://developers.mural.co/public/reference/searchmurals
|
15
|
+
def murals(query, workspace_id:, next_page: nil, room_id: nil)
|
16
|
+
json = get(
|
17
|
+
"/api/public/v1/search/#{workspace_id}/murals",
|
18
|
+
{ next: next_page, q: query, roomId: room_id }
|
19
|
+
)
|
20
|
+
|
21
|
+
murals = json['value'].map do |hit|
|
22
|
+
Mural::SearchMuralResult.decode(hit)
|
23
|
+
end
|
24
|
+
|
25
|
+
[murals, json['next']]
|
26
|
+
end
|
27
|
+
|
28
|
+
# https://developers.mural.co/public/reference/searchrooms
|
29
|
+
def rooms(query, workspace_id:, next_page: nil)
|
30
|
+
json = get(
|
31
|
+
"/api/public/v1/search/#{workspace_id}/rooms",
|
32
|
+
{ next: next_page, q: query }
|
33
|
+
)
|
34
|
+
|
35
|
+
rooms = json['value'].map { |hit| Mural::SearchRoomResult.decode(hit) }
|
36
|
+
|
37
|
+
[rooms, json['next']]
|
38
|
+
end
|
39
|
+
|
40
|
+
# https://developers.mural.co/public/reference/searchtemplates
|
41
|
+
def templates(query, workspace_id:, next_page: nil)
|
42
|
+
json = get(
|
43
|
+
"/api/public/v1/search/#{workspace_id}/templates",
|
44
|
+
{ next: next_page, q: query }
|
45
|
+
)
|
46
|
+
|
47
|
+
templates = json['value'].map do |hit|
|
48
|
+
Mural::SearchTemplateResult.decode(hit)
|
49
|
+
end
|
50
|
+
|
51
|
+
[templates, json['next']]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class Client
|
5
|
+
class Templates
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :@client, :get, :post, :delete
|
9
|
+
|
10
|
+
def initialize(client)
|
11
|
+
@client = client
|
12
|
+
end
|
13
|
+
|
14
|
+
# https://developers.mural.co/public/reference/getdefaulttemplates
|
15
|
+
def default_templates(next_page: nil)
|
16
|
+
json = get('/api/public/v1/templates', { next: next_page })
|
17
|
+
|
18
|
+
templates = json['value'].map { |tpl| Mural::Template.decode(tpl) }
|
19
|
+
|
20
|
+
[templates, json['next']]
|
21
|
+
end
|
22
|
+
|
23
|
+
# https://developers.mural.co/public/reference/createcustomtemplate
|
24
|
+
def create_custom(title:, mural_id:, description: nil)
|
25
|
+
json = post(
|
26
|
+
'/api/public/v1/templates',
|
27
|
+
{ title: title, muralId: mural_id, description: description }
|
28
|
+
)
|
29
|
+
|
30
|
+
Mural::Template.decode(json['value'])
|
31
|
+
end
|
32
|
+
|
33
|
+
# https://developers.mural.co/public/reference/deletetemplatebyid
|
34
|
+
def destroy(template_id)
|
35
|
+
delete("/api/public/v1/templates/#{template_id}")
|
36
|
+
end
|
37
|
+
|
38
|
+
# https://developers.mural.co/public/reference/createmuralfromtemplate
|
39
|
+
def create_mural(template_id, title:, room_id:, folder_id: nil)
|
40
|
+
json = post(
|
41
|
+
"/api/public/v1/templates/#{template_id}/murals",
|
42
|
+
{ title: title, roomId: room_id, folderId: folder_id }
|
43
|
+
)
|
44
|
+
|
45
|
+
Mural::MuralBoard.decode(json['value'])
|
46
|
+
end
|
47
|
+
|
48
|
+
# https://developers.mural.co/public/reference/gettemplatesbyworkspace
|
49
|
+
def for_workspace(workspace_id, next_page: nil, without_default: true)
|
50
|
+
json = get(
|
51
|
+
"/api/public/v1/workspaces/#{workspace_id}/templates",
|
52
|
+
{ next: next_page, withoutDefault: without_default }
|
53
|
+
)
|
54
|
+
|
55
|
+
templates = json['value'].map { |tpl| Mural::Template.decode(tpl) }
|
56
|
+
|
57
|
+
[templates, json['next']]
|
58
|
+
end
|
59
|
+
|
60
|
+
# https://developers.mural.co/public/reference/getrecenttemplates
|
61
|
+
def recent_for_workspace(
|
62
|
+
workspace_id,
|
63
|
+
next_page: nil,
|
64
|
+
without_default: true
|
65
|
+
)
|
66
|
+
json = get(
|
67
|
+
"/api/public/v1/workspaces/#{workspace_id}/templates/recent",
|
68
|
+
{ next: next_page, withoutDefault: without_default }
|
69
|
+
)
|
70
|
+
|
71
|
+
templates = json['value'].map { |tpl| Mural::Template.decode(tpl) }
|
72
|
+
|
73
|
+
[templates, json['next']]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class Client
|
5
|
+
class Users
|
6
|
+
module MuralUsers
|
7
|
+
# https://developers.mural.co/public/reference/getmuralusers
|
8
|
+
def mural_users(mural_id, next_page: nil)
|
9
|
+
json = get(
|
10
|
+
"/api/public/v1/murals/#{mural_id}/users",
|
11
|
+
{ next: next_page }
|
12
|
+
)
|
13
|
+
|
14
|
+
users = json['value'].map do |json_user|
|
15
|
+
::Mural::MuralUser.decode(json_user)
|
16
|
+
end
|
17
|
+
|
18
|
+
[users, json['next']]
|
19
|
+
end
|
20
|
+
|
21
|
+
# https://developers.mural.co/public/reference/updatemuralmemberpermissions
|
22
|
+
def update_mural_user_permissions(
|
23
|
+
mural_id,
|
24
|
+
user_id,
|
25
|
+
owner: nil,
|
26
|
+
facilitator: nil
|
27
|
+
)
|
28
|
+
patch(
|
29
|
+
"/api/public/v1/murals/#{mural_id}/users/#{user_id}/permissions",
|
30
|
+
{ owner: owner, facilitator: facilitator }
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
# https://developers.mural.co/public/reference/inviteuserstomural
|
35
|
+
def invite_mural_users(
|
36
|
+
mural_id,
|
37
|
+
message: nil,
|
38
|
+
invitations: [],
|
39
|
+
send_email: false
|
40
|
+
)
|
41
|
+
json = post(
|
42
|
+
"/api/public/v1/murals/#{mural_id}/users/invite",
|
43
|
+
{
|
44
|
+
message: message,
|
45
|
+
invitations: invitations.map(&:encode),
|
46
|
+
sendEmail: send_email
|
47
|
+
}
|
48
|
+
)
|
49
|
+
|
50
|
+
json['value'].map { |result| ::Mural::MuralInvitation.decode(result) }
|
51
|
+
end
|
52
|
+
|
53
|
+
# https://developers.mural.co/public/reference/removemuralusers
|
54
|
+
def remove_mural_users(mural_id, emails: [])
|
55
|
+
json = post(
|
56
|
+
"/api/public/v1/murals/#{mural_id}/users/remove",
|
57
|
+
{ emails: emails }
|
58
|
+
)
|
59
|
+
|
60
|
+
json['value'].map do |removed_user|
|
61
|
+
Mural::RemovedMuralUser.decode(removed_user)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class Client
|
5
|
+
class Users
|
6
|
+
module RoomUsers
|
7
|
+
# https://developers.mural.co/public/reference/getroommembers
|
8
|
+
def room_users(room_id, next_page: nil)
|
9
|
+
json = get(
|
10
|
+
"/api/public/v1/rooms/#{room_id}/users",
|
11
|
+
{ next: next_page }
|
12
|
+
)
|
13
|
+
|
14
|
+
users = json['value'].map do |json_user|
|
15
|
+
::Mural::RoomUser.decode(json_user)
|
16
|
+
end
|
17
|
+
|
18
|
+
[users, json['next']]
|
19
|
+
end
|
20
|
+
|
21
|
+
# https://developers.mural.co/public/reference/updateroommemberpermissions
|
22
|
+
def update_room_user_permissions(room_id, room_users: [])
|
23
|
+
patch(
|
24
|
+
"/api/public/v1/rooms/#{room_id}/users/permissions",
|
25
|
+
{ members: room_users.map(&:encode) }
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
# https://developers.mural.co/public/reference/inviteuserstoroom
|
30
|
+
def invite_room_users(
|
31
|
+
room_id,
|
32
|
+
message: nil,
|
33
|
+
room_invitations: [],
|
34
|
+
send_email: false
|
35
|
+
)
|
36
|
+
json = post(
|
37
|
+
"/api/public/v1/rooms/#{room_id}/users/invite",
|
38
|
+
{
|
39
|
+
message: message,
|
40
|
+
invitations: room_invitations.map(&:encode),
|
41
|
+
sendEmail: send_email
|
42
|
+
}
|
43
|
+
)
|
44
|
+
|
45
|
+
json['value'].map { |result| Mural::RoomInvitation.decode(result) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# https://developers.mural.co/public/reference/removeroomusers
|
50
|
+
def remove_room_users(room_id, emails: [])
|
51
|
+
json = post(
|
52
|
+
"/api/public/v1/rooms/#{room_id}/users/remove",
|
53
|
+
{ emails: emails }
|
54
|
+
)
|
55
|
+
|
56
|
+
json['value'].map do |removed_user|
|
57
|
+
Mural::RemovedRoomUser.decode(removed_user)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class Client
|
5
|
+
class Users
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
include Users::MuralUsers
|
9
|
+
include Users::RoomUsers
|
10
|
+
|
11
|
+
def_delegators :@client, :get, :post, :patch
|
12
|
+
|
13
|
+
def initialize(client)
|
14
|
+
@client = client
|
15
|
+
end
|
16
|
+
|
17
|
+
# https://developers.mural.co/public/reference/getcurrentmember
|
18
|
+
def current_user
|
19
|
+
json = get('/api/public/v1/users/me')['value']
|
20
|
+
|
21
|
+
::Mural::CurrentUser.decode(json)
|
22
|
+
end
|
23
|
+
|
24
|
+
# https://developers.mural.co/public/reference/inviteuserstoworkspace
|
25
|
+
def invite_workspace_users(workspace_id, message: nil, emails: [])
|
26
|
+
json = post(
|
27
|
+
"/api/public/v1/workspaces/#{workspace_id}/users/invite",
|
28
|
+
{
|
29
|
+
message: message,
|
30
|
+
invitations: emails.map { |email| { email: email } }
|
31
|
+
}
|
32
|
+
)
|
33
|
+
|
34
|
+
json['value'].map { |inv| Mural::WorkspaceInvitation.decode(inv) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class Client
|
5
|
+
class Workspaces
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :@client, :get, :post, :patch
|
9
|
+
|
10
|
+
def initialize(client)
|
11
|
+
@client = client
|
12
|
+
end
|
13
|
+
|
14
|
+
# https://developers.mural.co/public/reference/getworkspaces
|
15
|
+
def list(next_page: nil)
|
16
|
+
json = get('/api/public/v1/workspaces', { next: next_page })
|
17
|
+
|
18
|
+
workspaces = json['value'].map do |json_wp|
|
19
|
+
::Mural::Workspace.decode(json_wp)
|
20
|
+
end
|
21
|
+
|
22
|
+
[workspaces, json['next']]
|
23
|
+
end
|
24
|
+
|
25
|
+
# https://developers.mural.co/public/reference/getworkspace
|
26
|
+
def retrieve(workspace_id)
|
27
|
+
json = get("/api/public/v1/workspaces/#{workspace_id}")
|
28
|
+
|
29
|
+
::Mural::Workspace.decode(json['value'])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/mural/client.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class Client
|
5
|
+
include ::Mural::Client::Authentication
|
6
|
+
|
7
|
+
ENV_VARS = {
|
8
|
+
host: 'MURAL_HOST',
|
9
|
+
client_id: 'MURAL_CLIENT_ID',
|
10
|
+
client_secret: 'MURAL_CLIENT_SECRET',
|
11
|
+
redirect_uri: 'MURAL_REDIRECT_URI',
|
12
|
+
scope: 'MURAL_SCOPE',
|
13
|
+
access_token: 'MURAL_ACCESS_TOKEN',
|
14
|
+
refresh_token: 'MURAL_REFRESH_TOKEN'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
def self.from_env
|
18
|
+
new.tap do |client|
|
19
|
+
ENV_VARS.each do |attr, env_var|
|
20
|
+
value = ENV.fetch(env_var, nil)
|
21
|
+
|
22
|
+
client.public_send(:"#{attr}=", value) unless value.nil?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
ENV_VARS.each_key do |attr|
|
28
|
+
attr_accessor(attr)
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader :mural_content, :murals, :rooms, :search, :templates, :users,
|
32
|
+
:workspaces
|
33
|
+
|
34
|
+
def initialize
|
35
|
+
@host = 'app.mural.co'
|
36
|
+
|
37
|
+
@mural_content = Mural::Client::MuralContent.new(self)
|
38
|
+
@murals = Mural::Client::Murals.new(self)
|
39
|
+
@rooms = Mural::Client::Rooms.new(self)
|
40
|
+
@search = Mural::Client::Search.new(self)
|
41
|
+
@templates = Mural::Client::Templates.new(self)
|
42
|
+
@users = Mural::Client::Users.new(self)
|
43
|
+
@workspaces = Mural::Client::Workspaces.new(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
def get(path, query = {})
|
47
|
+
uri = URI::HTTPS.build(
|
48
|
+
host: host,
|
49
|
+
path: path,
|
50
|
+
query: URI.encode_www_form(query.compact)
|
51
|
+
)
|
52
|
+
|
53
|
+
req = Net::HTTP::Get.new uri
|
54
|
+
# retryable_request(req)
|
55
|
+
retryable_request(req)
|
56
|
+
end
|
57
|
+
|
58
|
+
def post(path, body = {})
|
59
|
+
uri = URI::HTTPS.build(host: host, path: path)
|
60
|
+
req = Net::HTTP::Post.new(uri)
|
61
|
+
req['Content-Type'] = 'application/json'
|
62
|
+
req.body = body.compact.to_json
|
63
|
+
|
64
|
+
retryable_request(req)
|
65
|
+
end
|
66
|
+
|
67
|
+
def patch(path, body = {})
|
68
|
+
uri = URI::HTTPS.build(host: host, path: path)
|
69
|
+
req = Net::HTTP::Patch.new(uri)
|
70
|
+
req['Content-Type'] = 'application/json'
|
71
|
+
req.body = body.compact.to_json
|
72
|
+
|
73
|
+
retryable_request(req)
|
74
|
+
end
|
75
|
+
|
76
|
+
def delete(path)
|
77
|
+
uri = URI::HTTPS.build(host: host, path: path)
|
78
|
+
req = Net::HTTP::Delete.new(uri)
|
79
|
+
|
80
|
+
retryable_request(req)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def retryable_request(request)
|
86
|
+
res = authorized_request(request)
|
87
|
+
return if res.is_a?(Net::HTTPNoContent)
|
88
|
+
|
89
|
+
data = JSON.parse(res.body)
|
90
|
+
raise to_error(data) unless res.is_a?(Net::HTTPOK) ||
|
91
|
+
res.is_a?(Net::HTTPCreated)
|
92
|
+
|
93
|
+
data
|
94
|
+
rescue StandardError => e
|
95
|
+
raise unless e.respond_to?(:code) && e.code == 'TOKEN_EXPIRED'
|
96
|
+
|
97
|
+
refresh
|
98
|
+
retry
|
99
|
+
end
|
100
|
+
|
101
|
+
def authorized_request(request)
|
102
|
+
Net::HTTP.start(
|
103
|
+
request.uri.host,
|
104
|
+
request.uri.port,
|
105
|
+
use_ssl: request.uri.scheme == 'https'
|
106
|
+
) do |http|
|
107
|
+
request['Authorization'] = "Bearer #{access_token}"
|
108
|
+
http.request request
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_error(data)
|
113
|
+
message = data.fetch('message', 'unknown error')
|
114
|
+
code = data.fetch('code', 'unknown code')
|
115
|
+
|
116
|
+
Mural::Error.new(message, code: code, details: data['details'])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/lib/mural/codec.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
# Utility module to convert from lowerCamelCase JSON to Ruby classes with
|
5
|
+
# proper accessors (using snake_case) and vice versa when building a payload
|
6
|
+
# to Mural.
|
7
|
+
module Codec
|
8
|
+
def encode
|
9
|
+
{}.tap do |json|
|
10
|
+
self.class.attrs.each do |attr, remote_attr|
|
11
|
+
value = public_send(attr)
|
12
|
+
|
13
|
+
json[remote_attr] = value unless value.nil?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def attrs
|
20
|
+
@attrs ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def define_attributes(values)
|
24
|
+
@attrs = values.freeze
|
25
|
+
|
26
|
+
attrs.each_key { |attr| attr_accessor(attr) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def decode(json)
|
30
|
+
return if json.nil?
|
31
|
+
|
32
|
+
new.tap do |instance|
|
33
|
+
attrs.each do |attr, remote_attr|
|
34
|
+
instance.public_send(:"#{attr}=", json[remote_attr])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.included(base)
|
41
|
+
base.extend(ClassMethods)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class CreateMuralParams
|
5
|
+
include Mural::Codec
|
6
|
+
|
7
|
+
define_attributes(
|
8
|
+
title: 'title',
|
9
|
+
room_id: 'roomId', # required
|
10
|
+
# 👇 Rejected by the API (invalid "backgroundColor" property was sent)
|
11
|
+
# background_color: 'backgroundColor',
|
12
|
+
folder_id: 'folderId',
|
13
|
+
height: 'height',
|
14
|
+
infinite: 'infinite',
|
15
|
+
width: 'width',
|
16
|
+
visitors_settings: 'visitorsSettings',
|
17
|
+
timer_sound_theme: 'timerSoundTheme',
|
18
|
+
visitor_avatar_theme: 'visitorAvatarTheme'
|
19
|
+
)
|
20
|
+
|
21
|
+
def encode
|
22
|
+
super.tap do |json|
|
23
|
+
json['visitorsSettings'] = json['visitorsSettings']&.encode
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class VisitorsSettings
|
28
|
+
include Mural::Codec
|
29
|
+
|
30
|
+
define_attributes(expires_on: 'expiresOn')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class CreateRoomParams
|
5
|
+
include Mural::Codec
|
6
|
+
|
7
|
+
# https://developers.mural.co/public/reference/createroom
|
8
|
+
define_attributes(
|
9
|
+
confidential: 'confidential',
|
10
|
+
description: 'description',
|
11
|
+
name: 'name',
|
12
|
+
type: 'type',
|
13
|
+
workspace_id: 'workspaceId'
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mural
|
4
|
+
class CreateStickyNoteParams
|
5
|
+
include Mural::Codec
|
6
|
+
|
7
|
+
define_attributes(
|
8
|
+
**Mural::Widget::StickyNote.attrs.reject do |attr|
|
9
|
+
%i[
|
10
|
+
content_edited_by
|
11
|
+
content_edited_on
|
12
|
+
created_by
|
13
|
+
created_on
|
14
|
+
hide_editor
|
15
|
+
hide_owner
|
16
|
+
id
|
17
|
+
invisible
|
18
|
+
locked
|
19
|
+
locked_by_facilitator
|
20
|
+
min_lines
|
21
|
+
type
|
22
|
+
updated_by
|
23
|
+
updated_on
|
24
|
+
].include?(attr)
|
25
|
+
end
|
26
|
+
)
|
27
|
+
|
28
|
+
def encode
|
29
|
+
super.tap do |json|
|
30
|
+
json['style'] = json['style']&.encode
|
31
|
+
end.compact
|
32
|
+
end
|
33
|
+
|
34
|
+
# Exact same values, no restrictions
|
35
|
+
Style = Mural::Widget::StickyNote::Style
|
36
|
+
end
|
37
|
+
end
|