s-3po 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +51 -0
- data/lib/s-3po/events.rb +110 -0
- data/lib/s-3po/generator.rb +36 -0
- data/lib/s-3po/parser.rb +46 -0
- data/lib/s-3po.rb +27 -0
- data/s-3po.gemspec +13 -0
- metadata +52 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3e1d759431fa3c4bc9f3f6a0a7a8b8663ca9a979
|
4
|
+
data.tar.gz: 68df6f31ed06cb70c2020955b2cc1d2cf36de9f5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3e4269f0094d557113cab59c653c2e78e1f9bcb7c072a69f37688b5e9161ea7ed44fe57cff92988da2bde318942ab931e5a5be2c90860ac005e370555419896b
|
7
|
+
data.tar.gz: 2e0300dfe5c6a8ffc6ec6e837abe692082542531efdb75c8e3e62becbfb5d1d3edb3fc10a49ca410b31fd71ab7796230bd54fd4e53a9feaffd5e48d73f33c262
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Ken J.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# S-3PO
|
2
|
+
|
3
|
+
A protocol droid made by Cybot Galactica for Slack.
|
4
|
+
|
5
|
+
This gem parses, generates, and manupilates various Slack events and messages.
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
- Ruby 2.0.0 <=
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
If you're creating integrations or bots for Slack, this may come useful. Install:
|
14
|
+
|
15
|
+
```
|
16
|
+
$ gem install subaru
|
17
|
+
```
|
18
|
+
|
19
|
+
Then use:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require 's-3po'
|
23
|
+
```
|
24
|
+
|
25
|
+
Your bot would connect to Slack via [RTM API](https://api.slack.com/rtm). Then process events like this.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
event = S3PO.parse_event(data_from_slack)
|
29
|
+
puts "#{event.type} : #{event.subtype}"
|
30
|
+
puts event.plain if event.is_simplemessage?
|
31
|
+
# => "@U123ABC: hello you!"
|
32
|
+
```
|
33
|
+
|
34
|
+
Generate a message to send to Slack.
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
json = S3PO.generate_message do |reply|
|
38
|
+
reply.channel = 'CABC123'
|
39
|
+
reply.plain = "@channel: what's up, ya all?"
|
40
|
+
end
|
41
|
+
puts json
|
42
|
+
# => "<!channel>: what's up, ya all?"
|
43
|
+
```
|
44
|
+
|
45
|
+
See [YARD Doc](http://www.rubydoc.info/github/kenjij/s-3po) for more info.
|
46
|
+
|
47
|
+
## What's Next
|
48
|
+
|
49
|
+
- Provide feedback
|
50
|
+
- Expect more updates
|
51
|
+
- Random anniversary at May 4th
|
data/lib/s-3po/events.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
module S3PO
|
2
|
+
|
3
|
+
# Base event class; a generic event class should only come from Slack.
|
4
|
+
class Event
|
5
|
+
|
6
|
+
attr_reader :object
|
7
|
+
|
8
|
+
def initialize(event = {})
|
9
|
+
fail 'Must be a Hash.' unless event.class == Hash
|
10
|
+
@object = event
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Symbol]
|
14
|
+
def type
|
15
|
+
return :response unless object[:ok].nil?
|
16
|
+
return object[:type].to_sym if object[:type]
|
17
|
+
return nil
|
18
|
+
end
|
19
|
+
|
20
|
+
# Is it a message event?
|
21
|
+
# @return [Boolean]
|
22
|
+
def is_message?
|
23
|
+
return !type.nil? && type == :message
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Symbol]
|
27
|
+
def subtype
|
28
|
+
return object[:subtype].to_sym if object[:subtype]
|
29
|
+
return nil
|
30
|
+
end
|
31
|
+
|
32
|
+
# Is it a simple message event; a straight forward text message without a subtype?
|
33
|
+
# @return [Boolean]
|
34
|
+
def is_simplemessage?
|
35
|
+
is_message? && subtype.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
def user
|
39
|
+
object[:user]
|
40
|
+
end
|
41
|
+
|
42
|
+
def channel
|
43
|
+
object[:channel]
|
44
|
+
end
|
45
|
+
|
46
|
+
def channel=(string)
|
47
|
+
fail 'Must be a String.' unless string.class == String
|
48
|
+
fail 'Invalid channel' unless /C[0-9A-Z]+/ =~ string
|
49
|
+
object[:channel] = string
|
50
|
+
end
|
51
|
+
|
52
|
+
def ts
|
53
|
+
object[:ts]
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# Message Event class comes from Slack, or you would create one to send a message.
|
60
|
+
class Message < Event
|
61
|
+
|
62
|
+
def initialize(event = {})
|
63
|
+
event[:type] = :message
|
64
|
+
super(event)
|
65
|
+
end
|
66
|
+
|
67
|
+
def text
|
68
|
+
object[:text]
|
69
|
+
end
|
70
|
+
|
71
|
+
def text=(string)
|
72
|
+
fail 'Must be a String.' unless string.class == String
|
73
|
+
object[:text] = string
|
74
|
+
@plain = nil
|
75
|
+
end
|
76
|
+
|
77
|
+
def plain
|
78
|
+
@plain ||= Parser.plain_from_text(text)
|
79
|
+
end
|
80
|
+
|
81
|
+
def plain=(string)
|
82
|
+
fail 'Must be a String.' unless string.class == String
|
83
|
+
@plain = string
|
84
|
+
object[:text] = Generator.text_from_plain(@plain)
|
85
|
+
end
|
86
|
+
|
87
|
+
def mentions
|
88
|
+
@mentions ||= Parser.mentions_from_text(text)
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
def commands
|
93
|
+
@commands ||= Parser.commands_from_text(text)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
class Response < Event
|
99
|
+
|
100
|
+
def ok
|
101
|
+
object[:ok]
|
102
|
+
end
|
103
|
+
|
104
|
+
def ok?
|
105
|
+
ok
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
|
4
|
+
module S3PO
|
5
|
+
|
6
|
+
class Generator
|
7
|
+
|
8
|
+
def self.generate_message(message, id = nil)
|
9
|
+
@id ||= 0
|
10
|
+
obj = message.object
|
11
|
+
msg = {type: 'message', channel: obj[:channel], text: obj[:text]}
|
12
|
+
msg[:id] = id ? id : @id
|
13
|
+
@id += 1 unless id
|
14
|
+
return JSON.fast_generate(msg)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.text_from_plain(plain)
|
18
|
+
text = String.new(plain)
|
19
|
+
# escape
|
20
|
+
text.gsub!('&', '&')
|
21
|
+
text.gsub!('<', '<')
|
22
|
+
text.gsub!('>', '>')
|
23
|
+
# add brackets to mentions
|
24
|
+
text.gsub!(/(@[a-z0-9][a-z0-9.\-_]*)/, '<\1>')
|
25
|
+
text.gsub!(/(@U[A-Z0-9]+)/, '<\1>')
|
26
|
+
# add brackets to channels
|
27
|
+
text.gsub!(/(#[a-z0-9\-_]+)/, '<\1>')
|
28
|
+
text.gsub!(/(#C[A-Z0-9]+)/, '<\1>')
|
29
|
+
# convert commands
|
30
|
+
text.gsub!(/<@(everyone|channel|group)>/, '<!\1>')
|
31
|
+
return text
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/lib/s-3po/parser.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
|
4
|
+
module S3PO
|
5
|
+
|
6
|
+
class Parser
|
7
|
+
|
8
|
+
def self.parse_event(event)
|
9
|
+
obj = JSON.parse(event, {symbolize_names: true})
|
10
|
+
return Response.new(obj) if obj[:type].nil?
|
11
|
+
return Message.new(obj) if obj[:type] == 'message'
|
12
|
+
return Event.new(obj)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.mentions_from_text(text)
|
16
|
+
mentions = []
|
17
|
+
text.scan(/<@([^>|]*)[^>]*>/) { |m| mentions << m[0]}
|
18
|
+
return mentions
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.plain_from_text(text)
|
22
|
+
# Copy
|
23
|
+
plain = String.new(text)
|
24
|
+
# remove labels within brackets
|
25
|
+
plain.gsub!(/<([^>|]*)[^>]*>/, '<\1>')
|
26
|
+
# process commands
|
27
|
+
plain.gsub!(/<!(everyone|channel|group)>/, '<@\1>')
|
28
|
+
plain.gsub!(/<!(.*?)>/, '<\1>')
|
29
|
+
# remove brackets
|
30
|
+
plain.gsub!(/<(.*?)>/, '\1')
|
31
|
+
# unescape
|
32
|
+
plain.gsub!('>', '>')
|
33
|
+
plain.gsub!('<', '<')
|
34
|
+
plain.gsub!('&', '&')
|
35
|
+
return plain
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.commands_from_text(text)
|
39
|
+
commands = []
|
40
|
+
text.scan(/<!([^>|]*)[^>]*>/) { |m| commands << m[0]}
|
41
|
+
return commands
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/lib/s-3po.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 's-3po/events'
|
2
|
+
require 's-3po/generator'
|
3
|
+
require 's-3po/parser'
|
4
|
+
|
5
|
+
|
6
|
+
module S3PO
|
7
|
+
|
8
|
+
# Parse Slack event into an S3PO Event object.
|
9
|
+
# @param event [String] event from Slack in JSON string
|
10
|
+
# @return [Object] an S3PO::Event object
|
11
|
+
def self.parse_event(event)
|
12
|
+
return Parser.parse_event(event)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Generate JSON message to send to Slack.
|
16
|
+
# @param message [Hash] message event object
|
17
|
+
# @param block [&block] provide a block to configure the message
|
18
|
+
# @return [String] JSON ready to send to Slack
|
19
|
+
def self.generate_message(message = {})
|
20
|
+
if block_given?
|
21
|
+
message = Message.new(message)
|
22
|
+
yield message
|
23
|
+
end
|
24
|
+
return Generator.generate_message(message)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/s-3po.gemspec
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 's-3po'
|
3
|
+
s.version = '0.1.0'
|
4
|
+
s.authors = ['Ken J.']
|
5
|
+
s.email = ['kenjij@gmail.com']
|
6
|
+
s.description = %q{Slack message formatter gem}
|
7
|
+
s.summary = %q{A Slack message "protocol droid®".}
|
8
|
+
s.homepage = 'https://github.com/kenjij/s-3po'
|
9
|
+
s.license = 'MIT'
|
10
|
+
|
11
|
+
s.files = `git ls-files`.split($/)
|
12
|
+
s.require_paths = ['lib']
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: s-3po
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ken J.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-10 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Slack message formatter gem
|
14
|
+
email:
|
15
|
+
- kenjij@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- LICENSE
|
21
|
+
- README.md
|
22
|
+
- lib/s-3po.rb
|
23
|
+
- lib/s-3po/events.rb
|
24
|
+
- lib/s-3po/generator.rb
|
25
|
+
- lib/s-3po/parser.rb
|
26
|
+
- s-3po.gemspec
|
27
|
+
homepage: https://github.com/kenjij/s-3po
|
28
|
+
licenses:
|
29
|
+
- MIT
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubyforge_project:
|
47
|
+
rubygems_version: 2.4.6
|
48
|
+
signing_key:
|
49
|
+
specification_version: 4
|
50
|
+
summary: A Slack message "protocol droid®".
|
51
|
+
test_files: []
|
52
|
+
has_rdoc:
|