apps 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/.gitignore +4 -0
- data/README.md +103 -19
- data/bin/setup +1 -2
- data/exe/apps +0 -0
- data/lib/apps/common/schema.rb +8 -0
- data/lib/apps/common/schema/base.rb +91 -0
- data/lib/apps/common/schema/concerns.rb +10 -0
- data/lib/apps/common/schema/concerns/potential_action.rb +35 -0
- data/lib/apps/gmail/markup.rb +158 -0
- data/lib/apps/gmail/schema.rb +21 -0
- data/lib/apps/gmail/schema/action.rb +19 -0
- data/lib/apps/gmail/schema/confirm_action.rb +21 -0
- data/lib/apps/gmail/schema/email_message.rb +15 -0
- data/lib/apps/gmail/schema/event.rb +41 -0
- data/lib/apps/gmail/schema/parcel_delivery.rb +43 -0
- data/lib/apps/gmail/schema/place.rb +24 -0
- data/lib/apps/gmail/schema/postal_address.rb +22 -0
- data/lib/apps/gmail/schema/rsvp_action.rb +25 -0
- data/lib/apps/gmail/schema/save_action.rb +20 -0
- data/lib/apps/gmail/schema/track_action.rb +20 -0
- data/lib/apps/gmail/schema/view_action.rb +20 -0
- data/lib/apps/outlook/actionable_messages.rb +13 -0
- data/lib/apps/outlook/schema.rb +20 -0
- data/lib/apps/outlook/schema/action.rb +14 -0
- data/lib/apps/outlook/schema/action_card.rb +42 -0
- data/lib/apps/outlook/schema/concerns.rb +14 -0
- data/lib/apps/outlook/schema/concerns/sections.rb +27 -0
- data/lib/apps/outlook/schema/concerns/sorted_potential_action.rb +17 -0
- data/lib/apps/outlook/schema/date_input.rb +17 -0
- data/lib/apps/outlook/schema/http_post.rb +44 -0
- data/lib/apps/outlook/schema/input.rb +23 -0
- data/lib/apps/outlook/schema/invoke_add_in_command.rb +33 -0
- data/lib/apps/outlook/schema/message_card.rb +39 -0
- data/lib/apps/outlook/schema/multichoice_input.rb +32 -0
- data/lib/apps/outlook/schema/open_uri.rb +24 -0
- data/lib/apps/outlook/schema/section.rb +52 -0
- data/lib/apps/outlook/schema/text_input.rb +20 -0
- data/lib/apps/version.rb +4 -1
- data/lib/examples.rb +121 -0
- data/package.json +12 -0
- metadata +37 -16
- data/lib/apps/adapters/gmail/markup.rb +0 -42
- data/lib/apps/adapters/gmail/markup/action.rb +0 -23
- data/lib/apps/adapters/gmail/markup/base.rb +0 -37
- data/lib/apps/adapters/gmail/markup/base_context.rb +0 -23
- data/lib/apps/adapters/gmail/markup/confirm_action.rb +0 -23
- data/lib/apps/adapters/gmail/markup/email_message.rb +0 -22
- data/lib/apps/adapters/gmail/markup/event.rb +0 -40
- data/lib/apps/adapters/gmail/markup/parcel_delivery.rb +0 -47
- data/lib/apps/adapters/gmail/markup/place.rb +0 -27
- data/lib/apps/adapters/gmail/markup/postal_address.rb +0 -26
- data/lib/apps/adapters/gmail/markup/rsvp_action.rb +0 -27
- data/lib/apps/adapters/gmail/markup/save_action.rb +0 -22
- data/lib/apps/adapters/gmail/markup/track_action.rb +0 -24
- data/lib/apps/adapters/gmail/markup/view_action.rb +0 -24
@@ -0,0 +1,17 @@
|
|
1
|
+
module Apps
|
2
|
+
module Outlook
|
3
|
+
module Schema
|
4
|
+
module Concerns
|
5
|
+
module SortedPotentialActions
|
6
|
+
def serialize_actions
|
7
|
+
# OpenUri action is supposed to be last
|
8
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#openuri-action
|
9
|
+
actions.sort! { |a, b| a.class == b.class ? 0 : a.is_a?(OpenUri) ? -1 : 1 }
|
10
|
+
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'input'
|
2
|
+
|
3
|
+
module Apps
|
4
|
+
module Outlook
|
5
|
+
module Schema
|
6
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#dateinput
|
7
|
+
class DateInput < Input
|
8
|
+
|
9
|
+
attr_accessor :include_time # Boolean - whether to select time in addition to date
|
10
|
+
|
11
|
+
def serialize
|
12
|
+
super.merge("includeTime" => include_time)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative 'action'
|
2
|
+
|
3
|
+
module Apps
|
4
|
+
module Outlook
|
5
|
+
module Schema
|
6
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#httppost-action
|
7
|
+
class HttpPOST < Action
|
8
|
+
# CARD-ACTION-STATUS - include header in server HTTP POST response
|
9
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#reporting-an-actions-execution-success-or-failure
|
10
|
+
# CARD-UPDATE-IN-BODY - `true` value indicates to client to refresh content with response body
|
11
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#refresh-cards
|
12
|
+
RESPONSE_HEADERS = %w[
|
13
|
+
CARD-ACTION-STATUS
|
14
|
+
CARD-UPDATE-IN-BODY
|
15
|
+
]
|
16
|
+
MIME_TYPES = %w[
|
17
|
+
application/json
|
18
|
+
application/x-www-form-urlencoded
|
19
|
+
]
|
20
|
+
|
21
|
+
attr_accessor :target, # URL
|
22
|
+
:body, # body of the POST request
|
23
|
+
:body_content_type # MIME type of body
|
24
|
+
|
25
|
+
def headers
|
26
|
+
@headers ||= {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def serialize
|
30
|
+
super.merge(
|
31
|
+
"target" => target,
|
32
|
+
"headers" => serialize_hash(headers),
|
33
|
+
"body" => body,
|
34
|
+
"bodyContentType" => body_content_type
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_header(name, value)
|
39
|
+
headers[name] = value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Apps
|
2
|
+
module Outlook
|
3
|
+
module Schema
|
4
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#inputs
|
5
|
+
class Input < Base
|
6
|
+
|
7
|
+
attr_accessor :id, # Uniquely identifies input in a form
|
8
|
+
:required,
|
9
|
+
:title, # Placeholder text or label
|
10
|
+
:value # Initial value of input
|
11
|
+
|
12
|
+
def serialize
|
13
|
+
super.merge(
|
14
|
+
"id" => id,
|
15
|
+
"isRequired" => required,
|
16
|
+
"title" => title,
|
17
|
+
"value" => value
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'action'
|
2
|
+
|
3
|
+
module Apps
|
4
|
+
module Outlook
|
5
|
+
module Schema
|
6
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#invokeaddincommand-action
|
7
|
+
class InvokeAddInCommand < Action
|
8
|
+
|
9
|
+
attr_accessor :add_in_id, # UUID from add-in's manifest
|
10
|
+
# Specifies the ID of the add-in command button that opens
|
11
|
+
# the required taskpane. The command button ID is found in
|
12
|
+
# the id attribute of the Control element that defines the
|
13
|
+
# button in the add-in's manifest. The specified Control element
|
14
|
+
# MUST be defined inside a `MessageReadCommandSurface` extension point,
|
15
|
+
# be of type Button, and the control's Action must be of type `ShowTaskPane`.
|
16
|
+
:desktop_command_id,
|
17
|
+
# Optional. Developers may specify any valid JSON object in
|
18
|
+
# this field. The value is serialized into a string and made
|
19
|
+
# available to the add-in when the action is executed. This
|
20
|
+
# allows the action to pass initialization data to the add-in.
|
21
|
+
:initialization_context
|
22
|
+
|
23
|
+
def serialize
|
24
|
+
super.merge(
|
25
|
+
"addInId" => add_in_id,
|
26
|
+
"desktopCommandId" => desktop_command_id,
|
27
|
+
"initializationContext" => initialization_context
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'concerns/sections'
|
2
|
+
|
3
|
+
module Apps
|
4
|
+
module Outlook
|
5
|
+
module Schema
|
6
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference
|
7
|
+
class MessageCard < Base
|
8
|
+
include Schema::Concerns::Sections
|
9
|
+
include Schema::Concerns::PotentialAction
|
10
|
+
include Schema::Concerns::SortedPotentialActions
|
11
|
+
|
12
|
+
HEADER_NAMES = %w[Card-Correlation-Id Action-Request-Id]
|
13
|
+
|
14
|
+
attr_accessor :correlation_id # UUID to track actions originating in email message
|
15
|
+
attr_accessor :originator # provider ID (required for actionable emails)
|
16
|
+
attr_accessor :hide_original_body # For email only (hide email content if message card is duplicate)
|
17
|
+
attr_accessor :summary, :title,
|
18
|
+
:text # Markdown
|
19
|
+
attr_accessor :theme_color
|
20
|
+
|
21
|
+
def context
|
22
|
+
'http://schema.org/extensions'
|
23
|
+
end
|
24
|
+
|
25
|
+
def serialize
|
26
|
+
super.merge(
|
27
|
+
"summary" => summary,
|
28
|
+
"themeColor" => theme_color,
|
29
|
+
"correlationId" => correlation_id,
|
30
|
+
"originator" => originator,
|
31
|
+
"hideOriginalBody" => hide_original_body,
|
32
|
+
"title" => title,
|
33
|
+
"text" => text
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative 'input'
|
2
|
+
|
3
|
+
module Apps
|
4
|
+
module Outlook
|
5
|
+
module Schema
|
6
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#multichoiceinput
|
7
|
+
class MultichoiceInput < Input
|
8
|
+
STYLES = %w[normal expanded].freeze
|
9
|
+
|
10
|
+
attr_accessor :multiple, # Boolean - whether to allow selecting multiple choices
|
11
|
+
:style # `normal` - dropdown
|
12
|
+
# `expanded` - radio button list
|
13
|
+
|
14
|
+
def choices
|
15
|
+
@choices ||= {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def serialize
|
19
|
+
super.merge(
|
20
|
+
"isMultiSelect" => multiple,
|
21
|
+
"style" => style,
|
22
|
+
"choices" => serialize_hash(choices, key: 'display')
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_choice(name, value)
|
27
|
+
choices[name] = value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'action'
|
2
|
+
|
3
|
+
module Apps
|
4
|
+
module Outlook
|
5
|
+
module Schema
|
6
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#openuri-action
|
7
|
+
class OpenUri < Action
|
8
|
+
OPERATING_SYSTEMS = %w[default windows iOS android].freeze
|
9
|
+
|
10
|
+
def targets
|
11
|
+
@targets ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def serialize
|
15
|
+
super.merge("targets" => serialize_hash(targets, key: 'os', value: 'uri'))
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_target(url, os: 'default')
|
19
|
+
targets[os] = url
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Apps
|
2
|
+
module Outlook
|
3
|
+
module Schema
|
4
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#section-fields
|
5
|
+
class Section < Base
|
6
|
+
include Schema::Concerns::PotentialAction
|
7
|
+
include Schema::Concerns::SortedPotentialActions
|
8
|
+
|
9
|
+
attr_accessor :title,
|
10
|
+
:text # Markdown
|
11
|
+
attr_accessor :start_group # boolean, used to separate sections with divider lines
|
12
|
+
attr_accessor :activity_title, # Markdown
|
13
|
+
:activity_subtitle, :activity_text, :activity_image
|
14
|
+
attr_accessor :hero_image, # url
|
15
|
+
:hero_title
|
16
|
+
|
17
|
+
# Hash of key/value pairs displayed to call out specific points
|
18
|
+
def facts
|
19
|
+
@facts ||= {}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Photo gallery (URL => title)
|
23
|
+
def images
|
24
|
+
@images ||= {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def serialize
|
28
|
+
super.merge(
|
29
|
+
"title" => title,
|
30
|
+
"startGroup" => start_group,
|
31
|
+
"activityTitle" => activity_title,
|
32
|
+
"activitySubtitle" => activity_subtitle,
|
33
|
+
"activityText" => activity_text,
|
34
|
+
"activityImage" => activity_image,
|
35
|
+
"heroImage" => hero_image && serialize_image(hero_image => hero_title, key: 'image', value: 'title'),
|
36
|
+
"text" => text,
|
37
|
+
"facts" => serialize_hash(facts),
|
38
|
+
"images" => serialize_hash(images, key: 'image', value: 'title')
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_fact(name, value)
|
43
|
+
facts[name] = value
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_image(url, title: nil)
|
47
|
+
images[url] = title
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'input'
|
2
|
+
|
3
|
+
module Apps
|
4
|
+
module Outlook
|
5
|
+
module Schema
|
6
|
+
# See: https://docs.microsoft.com/en-us/outlook/actionable-messages/card-reference#textinput
|
7
|
+
class TextInput < Input
|
8
|
+
|
9
|
+
attr_accessor :multiline, :max_length
|
10
|
+
|
11
|
+
def serialize
|
12
|
+
super.merge(
|
13
|
+
"isMultiline" => multiline,
|
14
|
+
"maxLength" => max_length
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/apps/version.rb
CHANGED
data/lib/examples.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
|
2
|
+
def divide(char = '#')
|
3
|
+
puts ""
|
4
|
+
puts char * 72
|
5
|
+
puts ""
|
6
|
+
end
|
7
|
+
|
8
|
+
def show(caption, object)
|
9
|
+
puts caption
|
10
|
+
puts ""
|
11
|
+
|
12
|
+
if object.is_a?(String)
|
13
|
+
puts object
|
14
|
+
else
|
15
|
+
pp object
|
16
|
+
end
|
17
|
+
|
18
|
+
puts ""
|
19
|
+
end
|
20
|
+
|
21
|
+
divide
|
22
|
+
|
23
|
+
require_relative 'apps/gmail/markup'
|
24
|
+
|
25
|
+
puts "GMAIL TESTS"
|
26
|
+
|
27
|
+
# Confirm Action (takes additional keyword options)
|
28
|
+
confirm_action = Apps::Gmail::Markup.confirm_action('Button Text', 'http://example.org/confirm/endpoint')
|
29
|
+
|
30
|
+
show 'confirm_action.as_json', confirm_action.as_json
|
31
|
+
# => {"@context"=>"http://schema.org", "@type"=>"EmailMessage", "potentialAction"=>{"@type"=>"ConfirmAction", "handler"=>{"@type"=>"HttpActionHandler", "url"=>"http://example.org/confirm/endpoint"}}}
|
32
|
+
|
33
|
+
show 'confirm_action.to_json', confirm_action.to_json
|
34
|
+
# => {"@context":"http://schema.org","@type":"EmailMessage","potentialAction":{"@type":"ConfirmAction","handler":{"@type":"HttpActionHandler","url":"http://example.org/confirm/endpoint"}}}
|
35
|
+
|
36
|
+
# NOTE: `to_script` is only available on "context" objects that represent the root of the markup
|
37
|
+
# needed for embedding in emails. This is the object returned by each of the helper methods
|
38
|
+
# above for each "Action"
|
39
|
+
show 'confirm_action.to_script', confirm_action.to_script
|
40
|
+
# =>
|
41
|
+
# <script type="application/ld+json">
|
42
|
+
# {
|
43
|
+
# "@context": "http://schema.org",
|
44
|
+
# "@type": "EmailMessage",
|
45
|
+
# "potentialAction": {
|
46
|
+
# "@type": "ConfirmAction",
|
47
|
+
# "handler": {
|
48
|
+
# "@type": "HttpActionHandler",
|
49
|
+
# "url": "http://example.org/confirm/endpoint"
|
50
|
+
# }
|
51
|
+
# }
|
52
|
+
# }
|
53
|
+
# </script>
|
54
|
+
|
55
|
+
# Save Action (takes additional keyword options)
|
56
|
+
save_action = Apps::Gmail::Markup.save_action('Button Text', 'http://example.org/save/endpoint')
|
57
|
+
|
58
|
+
show 'save_action', save_action.to_script
|
59
|
+
|
60
|
+
# RSVP Action (takes additional keyword options)
|
61
|
+
rsvp_action = Apps::Gmail::Markup.rsvp_action('Event Name',
|
62
|
+
yes_url: 'http://example.org/yes/endpoint',
|
63
|
+
no_url: 'http://example.org/no/endpoint',
|
64
|
+
maybe_url: 'http://example.org/maybe/endpoint'
|
65
|
+
)
|
66
|
+
|
67
|
+
show 'rsvp_action', rsvp_action.to_script
|
68
|
+
|
69
|
+
# View Action (takes additional keyword options)
|
70
|
+
view_action = Apps::Gmail::Markup.view_action('Button Text', 'http://example.org/save/endpoint')
|
71
|
+
|
72
|
+
show 'view_action', view_action.to_script
|
73
|
+
|
74
|
+
# Track Action (takes additional keyword options)
|
75
|
+
track_action = Apps::Gmail::Markup.track_action('Button Text', 'http://example.org/save/endpoint')
|
76
|
+
|
77
|
+
show 'track_action', track_action.to_script
|
78
|
+
|
79
|
+
divide
|
80
|
+
|
81
|
+
require_relative 'apps/outlook/actionable_messages'
|
82
|
+
|
83
|
+
puts "OUTLOOK TESTS"
|
84
|
+
|
85
|
+
message_card = Apps::Outlook::ActionableMessages.message_card('Summary text', 'Title text')
|
86
|
+
|
87
|
+
section = message_card.add_section('Section title', start_group: true, activity_image: 'http://img')
|
88
|
+
section.add_fact('Username', 'joelvh')
|
89
|
+
section.actions << Apps::Outlook::Schema::OpenUri.new(name: 'Section open uri action').tap { |s| s.add_target('http://target/section')}
|
90
|
+
|
91
|
+
show "section.actions", section.actions
|
92
|
+
|
93
|
+
pp message_card.serialize
|
94
|
+
|
95
|
+
section2 = message_card.add_section('Section 2 title', start_group: false, activity_image: 'http://img2')
|
96
|
+
section2.add_image('http://gallery1')
|
97
|
+
section2.add_image('http://gallery2', title: 'Gallery 2 caption')
|
98
|
+
|
99
|
+
message_card.actions << Apps::Outlook::Schema::OpenUri.new(name: 'Card open uri action')
|
100
|
+
|
101
|
+
action_card = Apps::Outlook::Schema::ActionCard.new(name: 'Action card form')
|
102
|
+
|
103
|
+
action_card.inputs << Apps::Outlook::Schema::DateInput.new(id: 'due_date', title: 'Due Date', value: '2008-01-01')
|
104
|
+
action_card.inputs << Apps::Outlook::Schema::TextInput.new(id: 'username', title: 'Username', value: 'fakeuser')
|
105
|
+
action_card.inputs << Apps::Outlook::Schema::MultichoiceInput.new(id: 'rating', title: 'Rating', value: '3').tap do |multi|
|
106
|
+
multi.add_choice('1 Star', '1')
|
107
|
+
multi.add_choice('3 Star', '3')
|
108
|
+
multi.add_choice('5 Star', '5')
|
109
|
+
end
|
110
|
+
|
111
|
+
section2.actions << action_card
|
112
|
+
|
113
|
+
show "message_card.actions", message_card.actions
|
114
|
+
|
115
|
+
pp message_card.serialize
|
116
|
+
|
117
|
+
divide('-')
|
118
|
+
|
119
|
+
puts message_card.to_script
|
120
|
+
|
121
|
+
divide
|
data/package.json
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"name": "apps",
|
3
|
+
"version": "0.3.0",
|
4
|
+
"description": "Easily integrate with multiple platform apps/add-ins/add-ons marketplaces.",
|
5
|
+
"main": "index.js",
|
6
|
+
"repository": "https://github.com/joelvh/apps",
|
7
|
+
"author": "Joel Van Horn <joel@joelvanhorn.com>",
|
8
|
+
"license": "MIT",
|
9
|
+
"dependencies": {
|
10
|
+
"generator-office": "^1.1.7"
|
11
|
+
}
|
12
|
+
}
|