fluent-plugin-deskcom 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5641dbda7a204f52d882965061aea9a383f83730
4
+ data.tar.gz: 9170d67ca166201d7bc734efec235d927c92a017
5
+ SHA512:
6
+ metadata.gz: 9057d3893407ec129cc8cf68f6280fb329ce1578c51628085ac5c19bc61a5f2dc970c28ec47d6414fe0ca05529522fe9894e3fee4f24ce2c3363f03a0384f0aa
7
+ data.tar.gz: 3ccee42a011fa0a5c40fb3c3890c8808b0bcde0a52b971764746303757749750bccb5f061017660763553a1fccf06adc706341ab5504d50e742c17e1b70777db
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /.idea/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ *.gem
16
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-deskcom.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Toru Takahashi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,170 @@
1
+ Deskcom plugin for Fluentd
2
+ ===========================
3
+
4
+ Fluentd Input plugin to collect data from Your Deskcom.
5
+ It is useful to improve your support quality.
6
+ This plugin is still experimental.
7
+ This plugin depends on [desk library](https://github.com/chriswarren/desk)
8
+ Also, please see [Desk API v2](http://dev.desk.com/)
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'fluent-plugin-deskcom'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install fluent-plugin-deskcom
25
+
26
+ ## Usage
27
+
28
+ ### Cases Config Sample
29
+
30
+ ```ruby
31
+ <source>
32
+ type deskcom
33
+ subdomain DESKCOM_SUBDOMAIN # Required (<subdomain>.desk.com)
34
+ consumer_key DESKCOM_CONSUMER_KEY # Required
35
+ consumer_secret DESKCOM_CONSUMER_SECRET # Required
36
+ oauth_token DESKCOM_OAUTH_TOKEN # Required
37
+ oauth_token_secret DESKCOM_OAUTH_TOKEN_SECRET # Required
38
+ store_file /var/log/cases.yml # Optional (filepath)
39
+ output_format simple # Optional (simple(default))
40
+ input_api cases # Optional (cases(default) or replies)
41
+ tag deskcom.cases # Required
42
+ time_format updated_at # Optional
43
+ </source>
44
+ ```
45
+
46
+ ```ruby
47
+ {
48
+ "id": 150,
49
+ "blurb": ": "",
50
+ "priority": 4,
51
+ "external_id": null,
52
+ "locked_until": null,
53
+ "label_ids": [],
54
+ "active_at": null,
55
+ "changed_at": "2013-02-10T14:18:56Z",
56
+ "created_at": "2013-01-15T11:12:20Z",
57
+ "updated_at": "2013-02-10T14:18:56Z",
58
+ "first_opened_at": null,
59
+ "opened_at": null,
60
+ "first_resolved_at": "2013-01-27T13:54:13Z",
61
+ "resolved_at": "2013-01-27T13:54:13Z",
62
+ "status": "closed",
63
+ "description": null,
64
+ "language": null,
65
+ "received_at": "2013-01-15T11:12:20Z",
66
+ "type": "email",
67
+ "labels": [],
68
+ "subject": "Chat transcript: no operator and Japan #6642",
69
+ "custom_fields": "{\"custom1_\":null,\"custom2_\":null}"
70
+ }
71
+ ```
72
+
73
+ ### Replies Config Sample
74
+
75
+ ```ruby
76
+ <source>
77
+ type deskcom
78
+ subdomain DESKCOM_SUBDOMAIN # Required (<subdomain>.desk.com)
79
+ consumer_key DESKCOM_CONSUMER_KEY # Required
80
+ consumer_secret DESKCOM_CONSUMER_SECRET # Required
81
+ oauth_token DESKCOM_OAUTH_TOKEN # Required
82
+ oauth_token_secret DESKCOM_OAUTH_TOKEN_SECRET # Required
83
+ store_file /var/log/replies.yml # Optional (filepath)
84
+ output_format simple # Optional (simple(default))
85
+ input_api replies # Optional (cases(default) or replies)
86
+ tag deskcom.replies # Required
87
+ </source>
88
+ ```
89
+
90
+ ```ruby
91
+ {
92
+ "case_id": 1
93
+ "id": 159057281,
94
+ "created_at": "2013-01-14T22:18:14Z",
95
+ "updated_at": "2013-01-14T22:18:14Z",
96
+ "sent_at": null,
97
+ "erased_at": null,
98
+ "hidden_by": null,
99
+ "hidden_at": null,
100
+ "body": "",
101
+ "from": "Toru Takahashi <torutakahashi.ayashi@gmail.com>",
102
+ "to": "\"test user\" <test@user.co.jp>",
103
+ "cc": "",
104
+ "bcc": null,
105
+ "client_type": "apple_mail",
106
+ "direction": "in",
107
+ "status": "received",
108
+ "subject": "subject",
109
+ "hidden": false
110
+ }
111
+ ```
112
+
113
+ ### Config Sample (Deskcom -> TreasureData)
114
+
115
+ ```ruby
116
+ # fluent.conf
117
+ <source>
118
+ type deskcom
119
+ subdomain DESKCOM_SUBDOMAIN # Required (<subdomain>.desk.com)
120
+ consumer_key DESKCOM_CONSUMER_KEY # Required
121
+ consumer_secret DESKCOM_CONSUMER_SECRET # Required
122
+ oauth_token DESKCOM_OAUTH_TOKEN # Required
123
+ oauth_token_secret DESKCOM_OAUTH_TOKEN_SECRET # Required
124
+ store_file /var/log/cases.yml # Optional (filepath)
125
+ output_format simple # Optional (simple(default))
126
+ input_api cases # Optional (cases(default) or replies)
127
+ tag deskcom.cases # Required
128
+ time_column updated_at
129
+ </source>
130
+
131
+ <source>
132
+ type deskcom
133
+ subdomain DESKCOM_SUBDOMAIN # Required (<subdomain>.desk.com)
134
+ consumer_key DESKCOM_CONSUMER_KEY # Required
135
+ consumer_secret DESKCOM_CONSUMER_SECRET # Required
136
+ oauth_token DESKCOM_OAUTH_TOKEN # Required
137
+ oauth_token_secret DESKCOM_OAUTH_TOKEN_SECRET # Required
138
+ store_file /var/log/replies.yml # Optional (filepath)
139
+ output_format simple # Optional (simple(default))
140
+ input_api replies # Optional (cases(default) or replies)
141
+ tag deskcom.replies # Required
142
+ time_column created_at
143
+ </source>
144
+
145
+ <match **>
146
+ type tdlog
147
+ apikey TREASUREDATA_API_KEY
148
+
149
+ auto_create_table
150
+ buffer_path /var/log/td-agent/tdlog
151
+ </match>
152
+ ```
153
+
154
+ Please check store_file's permission to write by fluentd.
155
+
156
+ ## TO DO
157
+
158
+ - Allows over 2 input_api (Ex. input_api cases,replies)
159
+ - Add other input_api
160
+ - Add Rate Limits
161
+ - Add feature to remind last collect cases or replies when forced termination.
162
+
163
+ ## Copyright
164
+
165
+ Copyright (c) 2014 Toru Takahashi
166
+
167
+ ## License
168
+
169
+ MIT License
170
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/test_*.rb'
7
+ test.verbose = true
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "fluent-plugin-deskcom"
6
+ spec.version = "0.0.1"
7
+ spec.authors = ["Toru Takahashi"]
8
+ spec.email = ["torutakahashi.ayashi@gmail.com"]
9
+ spec.summary = %q{Input plugin to collect data from Deskcom.}
10
+ spec.description = %q{fluent Input plugin to collect data from Deskcom.}
11
+ spec.homepage = "https://github.com/toru-takahashi/fluent-plugin-deskcom"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files`.split("\n")
15
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.7"
20
+ spec.add_development_dependency "rake", "~> 10.0"
21
+ spec.add_runtime_dependency "fluentd"
22
+ spec.add_runtime_dependency "desk"
23
+ end
@@ -0,0 +1,167 @@
1
+ module Fluent
2
+ class DeskcomInput < Fluent::Input
3
+ Fluent::Plugin.register_input('deskcom', self)
4
+
5
+ # un-support yet: nest flat
6
+ OUTPUT_FORMAT_TYPE = %w(simple)
7
+ # un-support yet: brand article reply ~
8
+ INPUT_API_TYPE = %w(cases replies)
9
+ DEFAULT_PER_PAGE = 50
10
+
11
+ config_param :subdomain, :string, :default => nil
12
+ config_param :consumer_key, :string, :default => nil
13
+ config_param :consumer_secret, :string, :default => nil
14
+ config_param :oauth_token, :string, :default => nil
15
+ config_param :oauth_token_secret, :string, :default => nil
16
+ config_param :store_file, :string, :default => nil
17
+ config_param :output_format, :string, :default => 'simple'
18
+ config_param :input_api, :string, :default => 'cases'
19
+ config_param :tag, :string, :default => nil
20
+ config_param :time_column, :string, :default => nil
21
+
22
+ def initialize
23
+ super
24
+ require 'desk'
25
+ require 'yaml'
26
+ require 'pathname'
27
+ end
28
+
29
+
30
+ def configure(conf)
31
+ super
32
+ if !OUTPUT_FORMAT_TYPE.include?(@output_format)
33
+ raise Fluent::ConfigError, "output_format value undefined #{@output_format}"
34
+ end
35
+
36
+ if !INPUT_API_TYPE.include?(@input_api)
37
+ raise Fluent::ConfigError, "input_api value undefined #{@input_api}"
38
+ end
39
+
40
+ if !@consumer_key || !@consumer_secret || !@oauth_token || !@oauth_token_secret
41
+ raise Fluent::ConfigError, "missing values in consumer_key or consumer_secret or oauth_token or oauth_token_secret"
42
+ end
43
+
44
+ if !@store_file
45
+ $log.warn("stored_time_file path is missing")
46
+ end
47
+
48
+
49
+ @stored_time = load_store_file
50
+ @started_time = Time.now.to_i
51
+ @per_page = DEFAULT_PER_PAGE
52
+
53
+ Desk.configure do |config|
54
+ config.subdomain = @subdomain
55
+ config.consumer_key = @consumer_key
56
+ config.consumer_secret = @consumer_secret
57
+ config.oauth_token = @oauth_token
58
+ config.oauth_token_secret = @oauth_token_secret
59
+ end
60
+ end
61
+
62
+ def start
63
+ super
64
+ @thread = Thread.new(&method(:run))
65
+ end
66
+
67
+ def shutdown
68
+ @thread.kill
69
+ end
70
+
71
+ def run
72
+ page = 1
73
+ if @input_api == 'cases' then
74
+ begin
75
+ cases = Desk.cases(:since_updated_at => @stored_time, :page => page, :per_page => @per_page)
76
+ cases.each do |c|
77
+ get_content(c)
78
+ end
79
+ page = page + 1
80
+ end while cases.total_entries > (@per_page*page)
81
+ elsif @input_api == 'replies'
82
+ begin
83
+ cases = Desk.cases(:since_updated_at => @stored_time, :page => page, :per_page => @per_page)
84
+ cases.each do |c|
85
+ Desk.case_replies(c.id).each do |r|
86
+ r[:case_id] = c.id
87
+ get_content(r) if c.count > 0
88
+ end
89
+ end
90
+ page = page + 1
91
+ end while cases.total_entries > (@per_page*page)
92
+ end
93
+ save_store_file unless !@store_file
94
+ rescue => e
95
+ $log.error "deskcom run: #{e.message}"
96
+ end
97
+
98
+ def get_content(status)
99
+ case @output_format
100
+ when 'simple'
101
+ record = Hash.new
102
+ status.each_pair do |k,v|
103
+ # @stored_time <= store data's updated time < @started_time
104
+ if (k == 'updated_at') then
105
+ at_time = Time.parse(v).to_i
106
+ if (at_time >= @started_time) || (at_time < @stored_time) then
107
+ next
108
+ end
109
+ end
110
+
111
+ if (!@time_column.nil? && k == "#{@time_column}") then
112
+ @time_value = Time.parse(v).to_i rescue nil
113
+ end
114
+
115
+ if (k == '_links') then
116
+ next
117
+ end
118
+
119
+ if v.kind_of? Hashie::Deash then
120
+ record.store(k, v.to_json)
121
+ else
122
+ record.store(k, v)
123
+ end
124
+ end
125
+ end
126
+
127
+ if !@time_value.nil? then
128
+ Engine.emit(@tag, @time_value, record)
129
+ else
130
+ Engine.emit(@tag, @started_time, record)
131
+ end
132
+ rescue => e
133
+ $log.error "deskcom get_content: #{e.message}"
134
+ end
135
+
136
+ # => int
137
+ def load_store_file
138
+ begin
139
+ f = Pathname.new(@store_file)
140
+ stored_time = 0
141
+ f.open('r') do |f|
142
+ stored = YAML.load_file(f)
143
+ stored_time = stored[:time].to_i
144
+ end
145
+ $log.info "deskcom: Load #{@store_file}: #{@stored_time}"
146
+ rescue => e
147
+ $log.warn "deskcom: Can't load store_file #{e.message}"
148
+ return 0
149
+ end
150
+ return stored_time
151
+ end
152
+
153
+ def save_store_file
154
+ begin
155
+ f = Pathname.new(@store_file)
156
+ f.open('w') do |f|
157
+ data = {:time => @started_time}
158
+ YAML.dump(data, f)
159
+ end
160
+ $log.info "deskcom: Save started_time: #{@started_time} to #{@store_file}"
161
+ rescue => e
162
+ $log.warn "deskcom: Can't save store_file #{e.message}"
163
+ end
164
+ end
165
+
166
+ end
167
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'fluent/test'
15
+ unless ENV.has_key?('VERBOSE')
16
+ nulllogger = Object.new
17
+ nulllogger.instance_eval {|obj|
18
+ def method_missing(method, *args)
19
+ # pass
20
+ end
21
+ }
22
+ $log = nulllogger
23
+ end
24
+
25
+ require 'fluent/plugin/in_deskcom'
26
+
27
+ class Test::Unit::TestCase
28
+ end
@@ -0,0 +1,41 @@
1
+ require 'helper'
2
+
3
+ class DeskcomInputTest < Test::Unit::TestCase
4
+ def setup
5
+ Fluent::Test.setup
6
+ end
7
+
8
+ CONFIG = %[
9
+ subdomain SUBDOMAIN
10
+ consumer_key CONSUMER_KEY
11
+ consumer_secret CONSUMER_SECRET
12
+ oauth_token OAUTH_TOKEN
13
+ oauth_token_secret OAUTH_TOKEN_SECRET
14
+ store_file /tmp/pos.yml
15
+ output_format simple
16
+ input_api cases
17
+ tag deskcom.cases
18
+ ]
19
+
20
+ def create_driver(conf=CONFIG, tag='test', use_v1=false)
21
+ Fluent::Test::InputTestDriver.new(Fluent::DeskcomInput).configure(conf, use_v1)
22
+ end
23
+
24
+ def test_configure
25
+ d = create_driver
26
+
27
+ assert_equal 'SUBDOMAIN', d.instance.subdomain
28
+ assert_equal 'CONSUMER_KEY', d.instance.consumer_key
29
+ assert_equal 'CONSUMER_SECRET', d.instance.consumer_secret
30
+ assert_equal 'OAUTH_TOKEN', d.instance.oauth_token
31
+ assert_equal 'OAUTH_TOKEN_SECRET', d.instance.oauth_token_secret
32
+ assert_equal '/tmp/pos.yml', d.instance.store_file
33
+ assert_equal 'simple', d.instance.output_format
34
+ assert_equal 'cases', d.instance.input_api
35
+ assert_equal 'deskcom.cases', d.instance.tag
36
+ end
37
+
38
+ def test_get_content
39
+ # TO DO: write actual code
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-deskcom
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Toru Takahashi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: fluentd
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: desk
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: fluent Input plugin to collect data from Deskcom.
70
+ email:
71
+ - torutakahashi.ayashi@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - fluent-plugin-deskcom.gemspec
82
+ - lib/fluent/plugin/in_deskcom.rb
83
+ - test/helper.rb
84
+ - test/plugin/test_in_deskcom.rb
85
+ homepage: https://github.com/toru-takahashi/fluent-plugin-deskcom
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.0.14
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: Input plugin to collect data from Deskcom.
109
+ test_files:
110
+ - test/helper.rb
111
+ - test/plugin/test_in_deskcom.rb