qiita_team_services 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +27 -0
  5. data/.travis.yml +11 -0
  6. data/CHANGELOG.md +7 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +22 -0
  9. data/README.md +5 -0
  10. data/Rakefile +26 -0
  11. data/config/locales/en.yml +31 -0
  12. data/config/locales/ja.yml +32 -0
  13. data/lib/qiita/team/services/engine.rb +6 -0
  14. data/lib/qiita/team/services/errors.rb +7 -0
  15. data/lib/qiita/team/services/events/base.rb +47 -0
  16. data/lib/qiita/team/services/events/item_became_coediting.rb +10 -0
  17. data/lib/qiita/team/services/events/item_comment_created.rb +17 -0
  18. data/lib/qiita/team/services/events/item_comment_destroyed.rb +17 -0
  19. data/lib/qiita/team/services/events/item_comment_updated.rb +17 -0
  20. data/lib/qiita/team/services/events/item_created.rb +10 -0
  21. data/lib/qiita/team/services/events/item_destroyed.rb +10 -0
  22. data/lib/qiita/team/services/events/item_updated.rb +10 -0
  23. data/lib/qiita/team/services/events/project_activated.rb +10 -0
  24. data/lib/qiita/team/services/events/project_archived.rb +10 -0
  25. data/lib/qiita/team/services/events/project_comment_created.rb +19 -0
  26. data/lib/qiita/team/services/events/project_comment_destroyed.rb +19 -0
  27. data/lib/qiita/team/services/events/project_comment_updated.rb +19 -0
  28. data/lib/qiita/team/services/events/project_created.rb +10 -0
  29. data/lib/qiita/team/services/events/project_destroyed.rb +10 -0
  30. data/lib/qiita/team/services/events/project_updated.rb +10 -0
  31. data/lib/qiita/team/services/events/team_member_added.rb +12 -0
  32. data/lib/qiita/team/services/events/team_member_removed.rb +12 -0
  33. data/lib/qiita/team/services/events.rb +28 -0
  34. data/lib/qiita/team/services/hooks/base.rb +45 -0
  35. data/lib/qiita/team/services/hooks/chatwork_v1.rb +149 -0
  36. data/lib/qiita/team/services/hooks/concerns/event_handlable.rb +49 -0
  37. data/lib/qiita/team/services/hooks/concerns/http_client.rb +74 -0
  38. data/lib/qiita/team/services/hooks/concerns/persistable.rb +64 -0
  39. data/lib/qiita/team/services/hooks/concerns/service.rb +31 -0
  40. data/lib/qiita/team/services/hooks/concerns/slack.rb +338 -0
  41. data/lib/qiita/team/services/hooks/hipchat_v1.rb +143 -0
  42. data/lib/qiita/team/services/hooks/slack_v1.rb +25 -0
  43. data/lib/qiita/team/services/hooks/slack_v2.rb +19 -0
  44. data/lib/qiita/team/services/hooks/webhook.rb +193 -0
  45. data/lib/qiita/team/services/hooks.rb +25 -0
  46. data/lib/qiita/team/services/properties/base.rb +20 -0
  47. data/lib/qiita/team/services/properties/boolean_property.rb +12 -0
  48. data/lib/qiita/team/services/properties/string_property.rb +12 -0
  49. data/lib/qiita/team/services/properties.rb +21 -0
  50. data/lib/qiita/team/services/resources/README.md +177 -0
  51. data/lib/qiita/team/services/templates/chatwork_v1.html.erb +25 -0
  52. data/lib/qiita/team/services/templates/hipchat_v1.html.erb +58 -0
  53. data/lib/qiita/team/services/templates/slack_v1.html.erb +54 -0
  54. data/lib/qiita/team/services/templates/slack_v2.html.erb +44 -0
  55. data/lib/qiita/team/services/templates/webhook.html.erb +25 -0
  56. data/lib/qiita/team/services/version.rb +3 -0
  57. data/lib/qiita_team_services.rb +34 -0
  58. data/qiita_team_services.gemspec +42 -0
  59. data/spec/hooks/chatwork_v1_spec.rb +118 -0
  60. data/spec/hooks/hipchat_v1_spec.rb +139 -0
  61. data/spec/hooks/slack_v1_spec.rb +55 -0
  62. data/spec/hooks/slack_v2_spec.rb +50 -0
  63. data/spec/hooks/webhook_spec.rb +465 -0
  64. data/spec/spec_helper.rb +17 -0
  65. data/spec/support/factories/comments.rb +21 -0
  66. data/spec/support/factories/items.rb +26 -0
  67. data/spec/support/factories/projects.rb +17 -0
  68. data/spec/support/factories/taggings.rb +9 -0
  69. data/spec/support/factories/teams.rb +9 -0
  70. data/spec/support/factories/users.rb +11 -0
  71. data/spec/support/factory_girl.rb +13 -0
  72. data/spec/support/helpers/event_helper.rb +49 -0
  73. data/spec/support/helpers/hook_helper.rb +33 -0
  74. data/spec/support/helpers/http_client_stub_helper.rb +19 -0
  75. data/spec/support/helpers/slack_hook_helper.rb +104 -0
  76. data/spec/support/matchers/match_slack_attachments_request.rb +7 -0
  77. data/spec/support/resources/base.rb +23 -0
  78. data/spec/support/resources/comment.rb +29 -0
  79. data/spec/support/resources/item.rb +53 -0
  80. data/spec/support/resources/project.rb +45 -0
  81. data/spec/support/resources/tagging.rb +15 -0
  82. data/spec/support/resources/team.rb +11 -0
  83. data/spec/support/resources/user.rb +17 -0
  84. metadata +323 -0
@@ -0,0 +1,143 @@
1
+ require "hipchat"
2
+
3
+ require "qiita/team/services/hooks/base"
4
+
5
+ module Qiita::Team::Services
6
+ module Hooks
7
+ class HipchatV1 < Base
8
+ AVAILABLE_COLORS = %w(yellow red green purple random).freeze
9
+
10
+ define_property :color, default: "yellow"
11
+ define_property :from, default: "Qiita:Team"
12
+ define_property :room
13
+ define_property :token
14
+ define_property :with_notification, default: false, type: :boolean
15
+
16
+ validates :color, inclusion: AVAILABLE_COLORS
17
+ validates :from, presence: true
18
+ validates :room, presence: true
19
+ validates :token, presence: true
20
+ validates :with_notification, inclusion: [true, false]
21
+
22
+ # @note Override {Services::Base.service_name}.
23
+ def self.service_name
24
+ "HipChat"
25
+ end
26
+
27
+ # @return [void]
28
+ def ping
29
+ send_message "Test message sent from Qiita:Team"
30
+ rescue DeliveryError
31
+ nil
32
+ end
33
+
34
+ # @param event [Qiita::Team::Services::Events::ItemCreated]
35
+ # @return [void]
36
+ # @raise [Qiita::Team::Services::DeliveryError]
37
+ def item_created(event)
38
+ send_message "#{user_link(event.user)} created #{item_link(event.item)}."
39
+ end
40
+
41
+ # @param event [Qiita::Team::Services::Events::ItemUpdated]
42
+ # @return [void]
43
+ # @raise [Qiita::Team::Services::DeliveryError]
44
+ def item_updated(event)
45
+ send_message "#{user_link(event.user)} updated #{item_link(event.item)}."
46
+ end
47
+
48
+ # @param event [Qiita::Team::Services::Events::ItemBecameCoediting]
49
+ # @return [void]
50
+ # @raise [Qiita::Team::Services::DeliveryError]
51
+ def item_became_coediting(event)
52
+ send_message "#{user_link(event.user)} changed #{item_link(event.item)} to coedit mode."
53
+ end
54
+
55
+ # @param event [Qiita::Team::Services::Events::ItemCommentCreated]
56
+ # @return [void]
57
+ # @raise [Qiita::Team::Services::DeliveryError]
58
+ def item_comment_created(event)
59
+ send_message <<-EOM.strip_heredoc
60
+ #{user_link(event.user)} commented on #{item_link(event.item)}.
61
+ <pre>#{event.comment.body.truncate(100)}</pre>
62
+ EOM
63
+ end
64
+
65
+ # @param event [Qiita::Team::Services::Events::ProjectCommentCreated]
66
+ # @return [void]
67
+ # @raise [Qiita::Team::Services::DeliveryError]
68
+ def project_comment_created(event)
69
+ send_message <<-EOM.strip_heredoc
70
+ #{user_link(event.user)} commented on #{project_link(event.project)}.
71
+ <pre>#{event.comment.body.truncate(100)}</pre>
72
+ EOM
73
+ end
74
+
75
+ # @param event [Qiita::Team::Services::Events::MemberAdded]
76
+ # @return [void]
77
+ # @raise [Qiita::Team::Services::DeliveryError]
78
+ def team_member_added(event)
79
+ send_message("#{user_link(event.member)} was added to #{event.team.name} team.")
80
+ end
81
+
82
+ # @param event [Qiita::Team::Services::Events::ProjectCreated]
83
+ # @return [void]
84
+ # @raise [Qiita::Team::Services::DeliveryError]
85
+ def project_created(event)
86
+ send_message("#{user_link(event.user)} created #{project_link(event.project)} project.")
87
+ end
88
+
89
+ # @param event [Qiita::Team::Services::Events::ProjectUpdated]
90
+ # @return [void]
91
+ # @raise [Qiita::Team::Services::DeliveryError]
92
+ def project_updated(event)
93
+ send_message("#{user_link(event.user)} updated #{project_link(event.project)} project.")
94
+ end
95
+
96
+ # @param event [Qiita::Team::Services::Events::ProjectActivated]
97
+ # @return [void]
98
+ # @raise [Qiita::Team::Services::DeliveryError]
99
+ def project_activated(event)
100
+ send_message("#{user_link(event.user)} activated #{project_link(event.project)} project.")
101
+ end
102
+
103
+ # @param event [Qiita::Team::Services::Events::ProjectArchived]
104
+ # @return [void]
105
+ # @raise [Qiita::Team::Services::DeliveryError]
106
+ def project_archived(event)
107
+ send_message("#{user_link(event.user)} archived #{event.project.name} project.")
108
+ end
109
+
110
+ private
111
+
112
+ # @param message [String]
113
+ def send_message(message)
114
+ client.send(from, message, color: color, notify: with_notification)
115
+ rescue HipChat::UnknownRoom, HipChat::Unauthorized, HipChat::UnknownResponseCode
116
+ raise DeliveryError
117
+ end
118
+
119
+ # @return [HipChat::Client] configured with API v1.
120
+ def client
121
+ @client ||= HipChat::Client.new(token)[room]
122
+ end
123
+
124
+ # @param user [Qiita::Team::Services::Resources::User]
125
+ # @return [String]
126
+ def user_link(user)
127
+ "<a href='#{user.url}'>#{user.name}</a>"
128
+ end
129
+
130
+ # @param item [Qiita::Team::Services::Resources::Item]
131
+ # @return [String]
132
+ def item_link(item)
133
+ "<a href='#{item.url}'>#{item.title}</a>"
134
+ end
135
+
136
+ # @param project [Qiita::Team::Services::Resources::Project]
137
+ # @return [String]
138
+ def project_link(project)
139
+ "<a href='#{project.url}'>#{project.name}</a>"
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,25 @@
1
+ require "qiita/team/services/hooks/base"
2
+ require "qiita/team/services/hooks/concerns/slack"
3
+
4
+ module Qiita::Team::Services
5
+ module Hooks
6
+ class SlackV1 < Base
7
+ deprecated
8
+
9
+ include Concerns::Slack
10
+
11
+ define_property :teamname
12
+ define_property :integration_token
13
+
14
+ validates :teamname, presence: true
15
+ validates :integration_token, presence: true
16
+
17
+ private
18
+
19
+ # @note Implement Concerns::HttpClient#url.
20
+ def url
21
+ "https://#{teamname}.slack.com/services/hooks/incoming-webhook?token=#{integration_token}"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ require "qiita/team/services/hooks/base"
2
+ require "qiita/team/services/hooks/concerns/slack"
3
+
4
+ module Qiita::Team::Services
5
+ module Hooks
6
+ class SlackV2 < Base
7
+ include Concerns::Slack
8
+
9
+ define_property :webhook_url
10
+
11
+ validates :webhook_url, presence: true
12
+
13
+ private
14
+
15
+ # @note Implement Concerns::HttpClient#url.
16
+ alias_method :url, :webhook_url
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,193 @@
1
+ require "securerandom"
2
+
3
+ require "qiita/team/services/hooks/base"
4
+
5
+ module Qiita::Team::Services
6
+ module Hooks
7
+ class Webhook < Base
8
+ include Concerns::HttpClient
9
+
10
+ define_property :url
11
+ define_property :token
12
+
13
+ validates :token, format: %r{\A[A-Za-z0-9+/=]{20,40}\z}
14
+ validates :url, presence: true
15
+
16
+ # @note Override {Qiita::Team::Services::Hooks::Base.service_name}.
17
+ def self.service_name
18
+ "Webhook"
19
+ end
20
+
21
+ # @return [String]
22
+ def self.generate_token
23
+ SecureRandom.base64(20)
24
+ end
25
+
26
+ # @param hash [Hash{String => Object}]
27
+ def initialize(hash)
28
+ unless hash.key?("token")
29
+ hash = hash.dup.merge("token" => self.class.generate_token)
30
+ end
31
+ super(hash)
32
+ end
33
+
34
+ def ping
35
+ send_hook(
36
+ action: "requested",
37
+ message: "ping",
38
+ model: "ping",
39
+ )
40
+ end
41
+
42
+ # @param event [Qiita::Team::Services::Events::ItemCreated]
43
+ def item_created(event)
44
+ send_hook(
45
+ action: "created",
46
+ model: "item",
47
+ item: event.resource,
48
+ user: event.user,
49
+ )
50
+ end
51
+
52
+ # @param event [Qiita::Team::Services::Events::ItemUpdated]
53
+ def item_updated(event)
54
+ send_hook(
55
+ action: "updated",
56
+ model: "item",
57
+ message: event.resource.message,
58
+ item: event.resource,
59
+ user: event.user,
60
+ )
61
+ end
62
+
63
+ # @param event [Qiita::Team::Services::Events::ItemDestroyed]
64
+ def item_destroyed(event)
65
+ send_hook(
66
+ action: "destroyed",
67
+ model: "item",
68
+ item: event.resource,
69
+ )
70
+ end
71
+
72
+ # @param event [Qiita::Team::Services::Events::ItemCommentCreated]
73
+ def item_comment_created(event)
74
+ send_hook(
75
+ action: "created",
76
+ model: "comment",
77
+ comment: event.resource,
78
+ item: event.item,
79
+ )
80
+ end
81
+
82
+ # @param event [Qiita::Team::Services::Events::ItemCommentUpdated]
83
+ def item_comment_updated(event)
84
+ send_hook(
85
+ action: "updated",
86
+ model: "comment",
87
+ comment: event.resource,
88
+ item: event.item,
89
+ )
90
+ end
91
+
92
+ # @param event [Qiita::Team::Services::Events::ItemCommentDestroyed]
93
+ def item_comment_destroyed(event)
94
+ send_hook(
95
+ action: "destroyed",
96
+ model: "comment",
97
+ comment: event.resource,
98
+ item: event.item,
99
+ )
100
+ end
101
+
102
+ # @param event [Qiita::Team::Services::Events::ProjectCommentCreated]
103
+ def project_comment_created(event)
104
+ send_hook(
105
+ action: "created",
106
+ model: "comment",
107
+ comment: event.resource,
108
+ item: event.project,
109
+ )
110
+ end
111
+
112
+ # @param event [Qiita::Team::Services::Events::ProjectCommentUpdated]
113
+ def project_comment_updated(event)
114
+ send_hook(
115
+ action: "updated",
116
+ model: "comment",
117
+ comment: event.resource,
118
+ item: event.project,
119
+ )
120
+ end
121
+
122
+ # @param event [Qiita::Team::Services::Events::ProjectCommentDestroyed]
123
+ def project_comment_destroyed(event)
124
+ send_hook(
125
+ action: "destroyed",
126
+ model: "comment",
127
+ comment: event.resource,
128
+ item: event.project,
129
+ )
130
+ end
131
+
132
+ # @param event [Qiita::Team::Services::Events::TeamMemberAdded]
133
+ def team_member_added(event)
134
+ send_hook(
135
+ action: "added",
136
+ model: "member",
137
+ user: event.resource,
138
+ )
139
+ end
140
+
141
+ # @param event [Qiita::Team::Services::Events::TeamMemberRemoved]
142
+ def team_member_removed(event)
143
+ send_hook(
144
+ action: "removed",
145
+ model: "member",
146
+ user: event.resource,
147
+ )
148
+ end
149
+
150
+ # @param event [Qiita::Team::Services::Events::ProjectCreated]
151
+ def project_created(event)
152
+ send_hook(
153
+ action: "created",
154
+ model: "project",
155
+ project: event.resource,
156
+ user: event.user,
157
+ )
158
+ end
159
+
160
+ # @param event [Qiita::Team::Services::Events::ProjectUpdated]
161
+ def project_updated(event)
162
+ send_hook(
163
+ action: "updated",
164
+ model: "project",
165
+ message: event.resource.message,
166
+ project: event.resource,
167
+ user: event.user,
168
+ )
169
+ end
170
+
171
+ # @param event [Qiita::Team::Services::Events::ProjectDestroyed]
172
+ def project_destroyed(event)
173
+ send_hook(
174
+ action: "destroyed",
175
+ model: "project",
176
+ project: event.resource,
177
+ )
178
+ end
179
+
180
+ private
181
+
182
+ def send_hook(properties)
183
+ http_post(
184
+ properties.as_json,
185
+ {
186
+ "X-Qiita-Event-Model" => properties[:model],
187
+ "X-Qiita-Token" => token,
188
+ }.reject { |_key, value| value.nil? },
189
+ )
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,25 @@
1
+ module Qiita::Team::Services
2
+ module Hooks
3
+ class << self
4
+ # @return [Array<Qiita::Team::Services::Hooks::Base>]
5
+ def all_hooks
6
+ @all_hooks ||= []
7
+ end
8
+
9
+ # @return [Array<Qiita::Team::Services::Hooks::Base>]
10
+ def active_hooks
11
+ all_hooks.reject(&:deprecated?)
12
+ end
13
+
14
+ # @return [Array<Qiita::Team::Services::Hooks::Base>]
15
+ def deprecated_hooks
16
+ all_hooks.select(&:deprecated?)
17
+ end
18
+
19
+ # @return [Array<String>]
20
+ def all_hook_types
21
+ all_hooks.map(&:hook_type)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ require "qiita/team/services/properties"
2
+
3
+ module Qiita::Team::Services
4
+ module Properties
5
+ # @abstract
6
+ class Base
7
+ # @return [String]
8
+ attr_reader :name
9
+
10
+ def initialize(name, default)
11
+ @name = name
12
+ @default = default
13
+ end
14
+
15
+ def default
16
+ fail NotImplementedError
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ require "qiita/team/services/properties/base"
2
+
3
+ module Qiita::Team::Services
4
+ module Properties
5
+ class BooleanProperty < Base
6
+ # @note Implement {Base#default}.
7
+ def default
8
+ @default.nil? ? true : @default
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require "qiita/team/services/properties/base"
2
+
3
+ module Qiita::Team::Services
4
+ module Properties
5
+ class StringProperty < Base
6
+ # @note Implement {Base#default}.
7
+ def default
8
+ @default.nil? ? "" : @default
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ module Qiita::Team::Services
2
+ module Properties
3
+ class << self
4
+ # @param name [Symbol]
5
+ # @param type [Symbol] :string or :boolean.
6
+ # @param default [String, true, false, nil]
7
+ def create(name, type, default)
8
+ # NOTE: Property name must be a string instance to serialize and
9
+ # deserialize correctly.
10
+ case type
11
+ when :string
12
+ StringProperty.new(name.to_s, default)
13
+ when :boolean
14
+ BooleanProperty.new(name.to_s, default)
15
+ else
16
+ ArgumentError
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,177 @@
1
+ # Qiita::Team::Services::Resources
2
+
3
+ There are several resources in `Qiita::Team::Services::Resources` module.
4
+ They are defined in Qiita core.
5
+
6
+ - [Team](#team)
7
+ - [User](#team)
8
+ - [Item](#item)
9
+ - [Project](#project)
10
+ - [Comment](#comment)
11
+ - [Tagging](#tagging)
12
+
13
+ ## Team
14
+
15
+ method | type | description
16
+ --------|--------|----------------
17
+ `#id` | String | Unique team id.
18
+ `#name` | String | Team name.
19
+ `#url` | String | Team root url.
20
+
21
+ ### Example
22
+
23
+ ```rb
24
+ team.id
25
+ #=> "increments"
26
+ team.name
27
+ #=> "Increments inc."
28
+ team.url
29
+ #=> "https://increments.qiita.com"
30
+ ```
31
+
32
+ ## User
33
+
34
+ method | type | description
35
+ ---------------------|--------|---------------------
36
+ `#id` | String | Unique user id.
37
+ `#url_name` | String | Qiita ID.
38
+ `#name` | String | Human readable name.
39
+ `#profile_image_url` | String | User icon url.
40
+ `#url` | String | Url to the user page.
41
+
42
+ ### Example
43
+
44
+ ```rb
45
+ user.id
46
+ #=> 1
47
+ user.url_name
48
+ #=> "qiitan"
49
+ user.name
50
+ #=> "Mr. Qiitan"
51
+ user.profile_image_url
52
+ #=> "https://example.com"
53
+ user.url
54
+ #=> "https://increments.qiita.com/qiitan"
55
+ ```
56
+
57
+ ## Item
58
+
59
+ method | type | description
60
+ -----------------|-------------------------------------------------|------------------------------------------
61
+ `#id` | String | Unique id.
62
+ `#title` | String | Item title.
63
+ `#body` | String | Item body in Markdown.
64
+ `#rendered_body` | String | Item body in HTML.
65
+ `#url` | String | Item resource url.
66
+ `#coediting?` | Boolean | A flag whether this item is co-edit mode.
67
+ `#user` | User | User who created this item.
68
+ `#tags` | Array<Qiita::Team::Services::Resouces::Tagging> | Array of tag names.
69
+ `#created_at` | Time | Time when this item was created.
70
+ `#updated_at` | Time | Time when this item was last updated.
71
+
72
+ ### Example
73
+
74
+ ```rb
75
+ item.id
76
+ #=> "4bd431809afb1bb99e4f"
77
+ item.title
78
+ #=> "Example title"
79
+ item.body
80
+ #=> "# Example"
81
+ item.rendered_body
82
+ #=> "<h1>Example</h1>
83
+ item.url
84
+ #=> "https://increments.qiita.com/qiitan/items/4bd431809afb1bb99e4f"
85
+ item.coediting?
86
+ #=> false
87
+ item.user
88
+ #=> <Qiita::Team::Services::Resouces::User>
89
+ item.tags
90
+ #=> [<Qiita::Team::Services::Resouces::Tagging>]
91
+ item.created_at
92
+ #=> 2000-01-01T00:00:00+00:00
93
+ item.updated_at
94
+ #=> 2000-01-01T00:00:00+00:00
95
+ ```
96
+
97
+ ## Project
98
+
99
+ method | type | description
100
+ -----------------|----------|-------------------------------------
101
+ `#id` | Fixnum | Project unique id.
102
+ `#name` | String | Project name.
103
+ `#body` | String | Project body in Markdown.
104
+ `#rendered_body` | String | Project body in HTML.
105
+ `#url` | String | Project resource url.
106
+ `#archived?` | Boolean | A flag whether this project has been archived.
107
+ `#created_at` | Time | Time when this project was created.
108
+ `#updated_at` | Time | Time when this project was last updated.
109
+
110
+ ### Example
111
+
112
+ ```rb
113
+ project.id
114
+ #=> 1
115
+ project.name
116
+ #=> "Example project"
117
+ project.body
118
+ #=> "# Example"
119
+ project.rendered_body
120
+ #=> "<h1>Example</h1>"
121
+ project.url
122
+ #=> "https://increments.qiita.com/projects/1"
123
+ project.archived?
124
+ #=> false
125
+ project.created_at
126
+ #=> 2000-01-01T00:00:00+00:00
127
+ project.updated_at
128
+ #=> 2000-01-01T00:00:00+00:00
129
+ ```
130
+
131
+ ## Comment
132
+
133
+ method | type | description
134
+ -----------------|---------------|----------------------------------------
135
+ `#id` | String | Comment unique id.
136
+ `#body` | String | Comment body in Markdown.
137
+ `#rendered_body` | String | Comment body in HTML.
138
+ `#url` | String | Comment resource url.
139
+ `#item` | Item, Project | Commented item or project.
140
+ `#created_at` | Time | Time when this comment was created.
141
+
142
+ ### Example
143
+
144
+ ```rb
145
+ comment.id
146
+ #=> "3391f50c35f953abfc4f"
147
+ comment.body
148
+ #=> "# Example"
149
+ comment.rendered_body
150
+ #=> "<h1>Example</h1>
151
+ comment.url
152
+ #=> "https://increments.qiita.com/qiitan/items/4bd431809afb1bb99e4f#comment-3391f50c35f953abfc4f
153
+ comment.item
154
+ #=> <Qiita::Team::Services::Resouces::Item>
155
+ comment.created_at
156
+ #=> 2000-01-01T00:00:00+00:00
157
+ ```
158
+
159
+ ## Tagging
160
+
161
+ method | type | description
162
+ -----------------|---------------|----------------------------------------
163
+ `#name` | String | Human tag name.
164
+ `#url_name` | String | Tag name for URL.
165
+ `#versions` | Array<String> | Version strings.
166
+
167
+ ### Example
168
+
169
+ ```rb
170
+
171
+ tagging.name
172
+ #=> "Ruby"
173
+ tagging.url_name
174
+ #=> "ruby"
175
+ tagging.versions
176
+ #=> ["2.2.1"]
177
+ ``
@@ -0,0 +1,25 @@
1
+ <div class="form-group">
2
+ <%= label :hook, "properties_token", "#{hook.class.human_attribute_name(:token)} *", class: "control-label" %>
3
+ <%= text_field_tag "hook[properties][token]", hook.token, class: "form-control" %>
4
+ <% if hook.errors.key?(:token) %>
5
+ <br/>
6
+ <div class="alert alert-warning">
7
+ <% hook.errors.full_messages_for(:token).each do |message| %>
8
+ <p><%= message %></p>
9
+ <% end %>
10
+ </div>
11
+ <% end %>
12
+ </div>
13
+
14
+ <div class="form-group">
15
+ <%= label :hook, "properties_room_id", "#{hook.class.human_attribute_name(:room_id)} *", class: "control-label" %>
16
+ <%= text_field_tag "hook[properties][room_id]", hook.room_id, class: "form-control" %>
17
+ <% if hook.errors.key?(:room_id) %>
18
+ <br/>
19
+ <div class="alert alert-warning">
20
+ <% hook.errors.full_messages_for(:room_id).each do |message| %>
21
+ <p><%= message %></p>
22
+ <% end %>
23
+ </div>
24
+ <% end %>
25
+ </div>