apps 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/README.md +103 -19
  4. data/bin/setup +1 -2
  5. data/exe/apps +0 -0
  6. data/lib/apps/common/schema.rb +8 -0
  7. data/lib/apps/common/schema/base.rb +91 -0
  8. data/lib/apps/common/schema/concerns.rb +10 -0
  9. data/lib/apps/common/schema/concerns/potential_action.rb +35 -0
  10. data/lib/apps/gmail/markup.rb +158 -0
  11. data/lib/apps/gmail/schema.rb +21 -0
  12. data/lib/apps/gmail/schema/action.rb +19 -0
  13. data/lib/apps/gmail/schema/confirm_action.rb +21 -0
  14. data/lib/apps/gmail/schema/email_message.rb +15 -0
  15. data/lib/apps/gmail/schema/event.rb +41 -0
  16. data/lib/apps/gmail/schema/parcel_delivery.rb +43 -0
  17. data/lib/apps/gmail/schema/place.rb +24 -0
  18. data/lib/apps/gmail/schema/postal_address.rb +22 -0
  19. data/lib/apps/gmail/schema/rsvp_action.rb +25 -0
  20. data/lib/apps/gmail/schema/save_action.rb +20 -0
  21. data/lib/apps/gmail/schema/track_action.rb +20 -0
  22. data/lib/apps/gmail/schema/view_action.rb +20 -0
  23. data/lib/apps/outlook/actionable_messages.rb +13 -0
  24. data/lib/apps/outlook/schema.rb +20 -0
  25. data/lib/apps/outlook/schema/action.rb +14 -0
  26. data/lib/apps/outlook/schema/action_card.rb +42 -0
  27. data/lib/apps/outlook/schema/concerns.rb +14 -0
  28. data/lib/apps/outlook/schema/concerns/sections.rb +27 -0
  29. data/lib/apps/outlook/schema/concerns/sorted_potential_action.rb +17 -0
  30. data/lib/apps/outlook/schema/date_input.rb +17 -0
  31. data/lib/apps/outlook/schema/http_post.rb +44 -0
  32. data/lib/apps/outlook/schema/input.rb +23 -0
  33. data/lib/apps/outlook/schema/invoke_add_in_command.rb +33 -0
  34. data/lib/apps/outlook/schema/message_card.rb +39 -0
  35. data/lib/apps/outlook/schema/multichoice_input.rb +32 -0
  36. data/lib/apps/outlook/schema/open_uri.rb +24 -0
  37. data/lib/apps/outlook/schema/section.rb +52 -0
  38. data/lib/apps/outlook/schema/text_input.rb +20 -0
  39. data/lib/apps/version.rb +4 -1
  40. data/lib/examples.rb +121 -0
  41. data/package.json +12 -0
  42. metadata +37 -16
  43. data/lib/apps/adapters/gmail/markup.rb +0 -42
  44. data/lib/apps/adapters/gmail/markup/action.rb +0 -23
  45. data/lib/apps/adapters/gmail/markup/base.rb +0 -37
  46. data/lib/apps/adapters/gmail/markup/base_context.rb +0 -23
  47. data/lib/apps/adapters/gmail/markup/confirm_action.rb +0 -23
  48. data/lib/apps/adapters/gmail/markup/email_message.rb +0 -22
  49. data/lib/apps/adapters/gmail/markup/event.rb +0 -40
  50. data/lib/apps/adapters/gmail/markup/parcel_delivery.rb +0 -47
  51. data/lib/apps/adapters/gmail/markup/place.rb +0 -27
  52. data/lib/apps/adapters/gmail/markup/postal_address.rb +0 -26
  53. data/lib/apps/adapters/gmail/markup/rsvp_action.rb +0 -27
  54. data/lib/apps/adapters/gmail/markup/save_action.rb +0 -22
  55. data/lib/apps/adapters/gmail/markup/track_action.rb +0 -24
  56. 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
@@ -1,3 +1,6 @@
1
+ require 'json'
2
+
1
3
  module Apps
2
- VERSION = '0.2.1'
4
+ PACKAGE_PATH ||= File.expand_path('../../package.json', File.dirname(__FILE__))
5
+ VERSION ||= JSON.parse(File.read(PACKAGE_PATH)).fetch('version')
3
6
  end
@@ -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
@@ -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
+ }