lita-tweet 0.1.0 → 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/lib/keyword_struct.rb +5 -0
- data/lib/lita/handlers/tweet.rb +109 -1
- data/lib/lita/handlers/tweet/account.rb +34 -0
- data/lib/lita/handlers/tweet/data.rb +94 -0
- data/lita-tweet.gemspec +4 -2
- metadata +35 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2075bb6c559760c56f41340005b53999d1dfa134
|
4
|
+
data.tar.gz: dd51909e34b310662c31ae91b983a2937f7a2762
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 838bd08b7db776304826b8211349c8d983c318fd95a5eb2e776b1fa096669c3481a0a6dd97cc6cb6da4ed37814c342b1e1802705c95365156b8e4aee432e227b
|
7
|
+
data.tar.gz: 87353ed0740d0b6673e24c2535b36e32608a16a4a6e5c084c24e4db00eb7e889e3c7a7e9f2a861a277f288d78506342ca8c6fa537f4a01cd4a07c662b3c98c80
|
data/lib/lita/handlers/tweet.rb
CHANGED
@@ -1,7 +1,115 @@
|
|
1
|
+
require_relative "./tweet/data"
|
2
|
+
|
1
3
|
module Lita
|
2
4
|
module Handlers
|
3
5
|
class Tweet < Handler
|
4
|
-
|
6
|
+
config :consumer_key, type: String
|
7
|
+
config :consumer_secret, type: String
|
8
|
+
config :http_url
|
9
|
+
|
10
|
+
route %r{^tweet\s(.+)}, :tweet, command: true, restrict_to: :tweeters,
|
11
|
+
help: {"tweet MESSAGE" => "Post a tweet."}
|
12
|
+
route %r{^untweet}, :untweet, command: true, restrict_to: :tweeters,
|
13
|
+
help: {"untweet" => "Delete the last tweet."}
|
14
|
+
route %r{^twitter accounts}, :accounts, command: true,
|
15
|
+
restrict_to: :tweeters, help: {
|
16
|
+
"twitter accounts" => "List accounts that can be tweeted from.",
|
17
|
+
"twitter accounts add" => "Authorize a new account for tweeting.",
|
18
|
+
"twitter accounts remove NAME" => "Remove the twitter account NAME"
|
19
|
+
}
|
20
|
+
# route %r{^twitter channels\s(.+?)\s(.+)}, :channels, command: true, help: {
|
21
|
+
# "twitter channels" => "List account to channel mappings.",
|
22
|
+
# "twitter channels NAME CHANNEL" => "Tweet as twitter account NAME when told to tweet in channel CHANNEL."
|
23
|
+
# }
|
24
|
+
|
25
|
+
TWITTER_AUTH_URL = "/twitter/auth"
|
26
|
+
TWITTER_AUTH_CALLBACK_URL = "/twitter/callback"
|
27
|
+
http.get TWITTER_AUTH_URL, :twitter_auth
|
28
|
+
http.get TWITTER_AUTH_CALLBACK_URL, :twitter_auth_callback
|
29
|
+
|
30
|
+
def tweet(response)
|
31
|
+
text = response.match_data[1]
|
32
|
+
if text.nil? || text.empty?
|
33
|
+
return response.reply("I need something to tweet!")
|
34
|
+
end
|
35
|
+
|
36
|
+
account = account_for(response)
|
37
|
+
return response.relpy(no_accounts) if account.nil?
|
38
|
+
|
39
|
+
tweet = account.tweet(text)
|
40
|
+
twitter_data.set_last_tweet(account.username, tweet.id)
|
41
|
+
response.reply(tweet.url)
|
42
|
+
end
|
43
|
+
|
44
|
+
def untweet(response)
|
45
|
+
account = account_for(response)
|
46
|
+
return response.relpy(no_accounts) if account.nil?
|
47
|
+
|
48
|
+
if account.untweet
|
49
|
+
response.reply("Removed last tweet.")
|
50
|
+
else
|
51
|
+
response.reply("Couldn't find a last tweet to remove!")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def accounts(response)
|
56
|
+
case response.args[1]
|
57
|
+
when "add"
|
58
|
+
response.reply(add_account)
|
59
|
+
when "remove"
|
60
|
+
response.reply(remove_account(response.args[2]))
|
61
|
+
else
|
62
|
+
response.reply(list_accounts)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# def channels(response)
|
67
|
+
# # do channel stuff here
|
68
|
+
# end
|
69
|
+
|
70
|
+
def twitter_auth(request, response)
|
71
|
+
callback_url = TWITTER_AUTH_CALLBACK_URL
|
72
|
+
request_token = twitter_data.create_request_token(callback_url)
|
73
|
+
response.status = 302
|
74
|
+
response.headers["Location"] = request_token.authorize_url
|
75
|
+
end
|
76
|
+
|
77
|
+
def twitter_auth_callback(request, response)
|
78
|
+
token = request.params["oauth_token"]
|
79
|
+
verifier = request.params["oauth_verifier"]
|
80
|
+
account = twitter_data.authorize_account(token, verifier)
|
81
|
+
response.body << "Done! You can now tweet from @#{account.username}."
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def list_accounts
|
87
|
+
names = twitter_data.usernames
|
88
|
+
|
89
|
+
if names.empty?
|
90
|
+
"No authorized accounts. Use `twitter accounts add` to add one."
|
91
|
+
else
|
92
|
+
usernames = names.map{|n| " - @#{n}" }.join("\n")
|
93
|
+
"Authorized Twitter accounts:\n" << usernames
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def add_account
|
98
|
+
auth_uri = twitter_data.bot_uri(TWITTER_AUTH_URL)
|
99
|
+
"Authorize your account for tweeting here:\n#{auth_uri}"
|
100
|
+
end
|
101
|
+
|
102
|
+
def remove_account(name)
|
103
|
+
twitter_data.remove_account(name)
|
104
|
+
"Removed @#{name}."
|
105
|
+
end
|
106
|
+
def account_for(response)
|
107
|
+
twitter_data.account(twitter_data.usernames.first)
|
108
|
+
end
|
109
|
+
|
110
|
+
def twitter_data
|
111
|
+
@twitter_data ||= Data.new(redis, config, robot)
|
112
|
+
end
|
5
113
|
|
6
114
|
Lita.register_handler(self)
|
7
115
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "twitter"
|
2
|
+
require "keyword_struct"
|
3
|
+
|
4
|
+
module Lita
|
5
|
+
module Handlers
|
6
|
+
class Tweet < Handler
|
7
|
+
|
8
|
+
Account = KeywordStruct.new(:username, :token, :secret, :config, :last_tweet) do
|
9
|
+
def username
|
10
|
+
@username ||= client.user.screen_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def tweet(text)
|
14
|
+
client.update(text)
|
15
|
+
end
|
16
|
+
|
17
|
+
def untweet
|
18
|
+
last_tweet ? client.destroy_status(last_tweet) : false
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def client
|
24
|
+
@client ||= ::Twitter::REST::Client.new do |c|
|
25
|
+
c.consumer_key = config.consumer_key
|
26
|
+
c.consumer_secret = config.consumer_secret
|
27
|
+
c.access_token = token
|
28
|
+
c.access_token_secret = secret
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require "oauth"
|
2
|
+
require_relative "./account"
|
3
|
+
|
4
|
+
module Lita
|
5
|
+
module Handlers
|
6
|
+
class Tweet < Handler
|
7
|
+
Data = Struct.new(:redis, :config, :robot) do
|
8
|
+
def usernames
|
9
|
+
redis.smembers("twitter_accounts")
|
10
|
+
end
|
11
|
+
|
12
|
+
def account(username)
|
13
|
+
hash = redis.hgetall("twitter_accounts:#{username}")
|
14
|
+
data = hash.each_with_object({}){|(k,v),h| h[k.to_sym] = v }
|
15
|
+
Account.new(**data.merge(config: config))
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_account(token, secret)
|
19
|
+
account = Account.new(token: token, secret: secret, config: config)
|
20
|
+
username = account.username
|
21
|
+
|
22
|
+
redis.sadd("twitter_accounts", username)
|
23
|
+
redis.hmset("twitter_accounts:#{username}",
|
24
|
+
"username", username,
|
25
|
+
"token", token,
|
26
|
+
"secret", secret
|
27
|
+
)
|
28
|
+
|
29
|
+
account
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove_account(username)
|
33
|
+
redis.del("twitter_accounts:#{username}")
|
34
|
+
redis.srem("twitter_accounts", username)
|
35
|
+
end
|
36
|
+
|
37
|
+
def set_last_tweet(username, tweet_id)
|
38
|
+
redis.hset("twitter_accounts:#{username}", "last_tweet", tweet_id)
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_last_tweet(username)
|
42
|
+
redis.hget("twitter_accounts:#{username}", "last_tweet")
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_request_token(callback_path)
|
46
|
+
request_token = consumer.get_request_token(
|
47
|
+
oauth_callback: bot_uri(callback_path).to_s)
|
48
|
+
request_hash = request_token.params
|
49
|
+
|
50
|
+
key = "request_token:#{request_hash[:oauth_token]}"
|
51
|
+
redis.hmset(key, *request_hash.to_a.flatten)
|
52
|
+
redis.expire(key, 120)
|
53
|
+
|
54
|
+
request_token
|
55
|
+
end
|
56
|
+
|
57
|
+
def authorize_account(token, verifier)
|
58
|
+
request_token = find_request_token(token)
|
59
|
+
access_token = request_token.get_access_token(oauth_verifier: verifier)
|
60
|
+
add_account(access_token.token, access_token.secret)
|
61
|
+
end
|
62
|
+
|
63
|
+
def bot_uri(path = "")
|
64
|
+
base_uri + path
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def find_request_token(oauth_token)
|
70
|
+
params = redis.hgetall("request_token:#{oauth_token}")
|
71
|
+
params.keys.each{|k| params[k.to_sym] = params[k] }
|
72
|
+
OAuth::RequestToken.from_hash(consumer, params)
|
73
|
+
end
|
74
|
+
|
75
|
+
def base_uri
|
76
|
+
@base_url ||= begin
|
77
|
+
http = robot.config.http
|
78
|
+
URI(config.http_url || "http://#{http.host}:#{http.port}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def consumer
|
83
|
+
@consumer ||= OAuth::Consumer.new(
|
84
|
+
config.consumer_key,
|
85
|
+
config.consumer_secret,
|
86
|
+
:site => 'https://api.twitter.com',
|
87
|
+
:authorize_path => '/oauth/authenticate',
|
88
|
+
:sign_in => true
|
89
|
+
)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lita-tweet.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "lita-tweet"
|
3
|
-
spec.version = "0.
|
3
|
+
spec.version = "0.3.0"
|
4
4
|
spec.authors = ["Andre Arko"]
|
5
5
|
spec.email = ["andre@arko.net"]
|
6
6
|
spec.description = "Tweeting for Lita"
|
@@ -15,8 +15,10 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.require_paths = ["lib"]
|
16
16
|
|
17
17
|
spec.add_runtime_dependency "lita", ">= 4.7"
|
18
|
+
spec.add_runtime_dependency "twitter", "~> 5.16"
|
19
|
+
spec.add_runtime_dependency "oauth", "~> 0.5.1"
|
18
20
|
|
19
|
-
spec.add_development_dependency "bundler", "~> 1.
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
20
22
|
spec.add_development_dependency "pry-byebug"
|
21
23
|
spec.add_development_dependency "rake"
|
22
24
|
spec.add_development_dependency "rack-test"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lita-tweet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andre Arko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lita
|
@@ -24,20 +24,48 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: twitter
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.16'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.16'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: oauth
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.5.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.5.1
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: bundler
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
59
|
- - "~>"
|
32
60
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
61
|
+
version: '1.12'
|
34
62
|
type: :development
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
66
|
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
68
|
+
version: '1.12'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: pry-byebug
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -135,8 +163,11 @@ files:
|
|
135
163
|
- LICENSE
|
136
164
|
- README.md
|
137
165
|
- Rakefile
|
166
|
+
- lib/keyword_struct.rb
|
138
167
|
- lib/lita-tweet.rb
|
139
168
|
- lib/lita/handlers/tweet.rb
|
169
|
+
- lib/lita/handlers/tweet/account.rb
|
170
|
+
- lib/lita/handlers/tweet/data.rb
|
140
171
|
- lita-tweet.gemspec
|
141
172
|
- locales/en.yml
|
142
173
|
- spec/lita/handlers/tweet_spec.rb
|