Skip to content

Commit 94a39c3

Browse files
authored
Add post and delete Tweet + enabling OAuth to authenticate requests (#6) - @rofreg
Adds the the feature to post and delete tweets, and authenticate requests with OAuth - thanks to @rofreg !
1 parent 678b3a0 commit 94a39c3

5 files changed

Lines changed: 92 additions & 41 deletions

File tree

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
BEARER_TOKEN=<your-bearer-token>
2+
CONSUMER_KEY=<your-consumer-key>
3+
CONSUMER_SECRET=<your-consumer-secret>
4+
ACCESS_TOKEN=<your-access-token>
5+
ACCESS_TOKEN_SECRET=<your-access-token-secret>

lib/tweetkit/auth.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
module Tweetkit
22
module Auth
3-
def basic_auth?
4-
!!(@login && @password)
5-
end
6-
73
def token_auth?
8-
!!(@access_token && @access_token_secret)
4+
!!(@consumer_key && @consumer_secret && @access_token && @access_token_secret)
95
end
106

117
def bearer_auth?

lib/tweetkit/client/tweets.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ def search(query = '', type: :tweet, **options, &block)
2121
search.evaluate(&block) if block_given?
2222
get 'tweets/search/recent', **options.merge!({ query: search.current_query })
2323
end
24+
25+
def post_tweet(**options)
26+
post "tweets", **options
27+
end
28+
29+
def delete_tweet(id)
30+
delete "tweets/#{id}"
31+
end
2432
end
2533
end
2634
end

lib/tweetkit/connection.rb

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,38 +16,50 @@ def get(endpoint, **options)
1616
request :get, endpoint, parse_query_and_convenience_headers(options)
1717
end
1818

19+
def post(endpoint, **options)
20+
request :post, endpoint, parse_query_and_convenience_headers(options)
21+
end
22+
23+
def put(endpoint, **options)
24+
request :put, endpoint, parse_query_and_convenience_headers(options)
25+
end
26+
27+
def delete(endpoint, **options)
28+
request :delete, endpoint, parse_query_and_convenience_headers(options)
29+
end
30+
1931
def request(method, endpoint, data, **options)
20-
auth_type = options.delete(:auth_type)
2132
url = URI.parse("#{BASE_URL}#{endpoint}")
2233
@previous_url = url
2334
@previous_query = data
2435

25-
if method == :get
26-
connection = Faraday.new(params: data) do |conn|
27-
if auth_type == 'oauth1'
28-
conn.request :oauth, consumer_key: @consumer_key, consumer_secret: @consumer_secret
29-
else
30-
conn.request :authorization, 'Bearer', @bearer_token
31-
end
32-
end
33-
response = connection.get(url)
34-
else
35-
connection = Faraday.new do |f|
36+
connection = Faraday.new do |conn|
37+
if token_auth?
38+
conn.request :oauth, consumer_key: @consumer_key, consumer_secret: @consumer_secret,
39+
token: @access_token, token_secret: @access_token_secret
40+
elsif bearer_auth?
41+
conn.request :authorization, 'Bearer', @bearer_token
42+
else
43+
raise NotImplementedError, 'No known authentication types were configured'
3644
end
37-
response = connection.post(url)
3845
end
46+
47+
response = case method
48+
when :get
49+
connection.get(url, data)
50+
when :post
51+
connection.post(url, data.to_json, 'Content-Type' => 'application/json')
52+
when :put
53+
connection.put(url, data.to_json, 'Content-Type' => 'application/json')
54+
when :delete
55+
connection.delete(url, data.to_json, 'Content-Type' => 'application/json')
56+
end
57+
3958
Tweetkit::Response::Tweets.new response, connection: connection, twitter_request: { previous_url: @previous_url, previous_query: @previous_query }
4059
rescue StandardError => e
4160
raise e
4261
end
4362

44-
def auth_token(type = 'bearer')
45-
case type
46-
when 'bearer'
47-
@bearer_token
48-
end
49-
end
50-
5163
def build_fields(options)
5264
fields = {}
5365
fields_ = options.delete(:fields)

spec/client/tweets_spec.rb

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,62 @@
11
require_relative '../spec_helper'
22

33
describe Tweetkit::Client::Tweets do
4-
before(:each) do
5-
@client = Tweetkit::Client.new(bearer_token: ENV['BEARER_TOKEN'])
6-
end
4+
client_types = {
5+
bearer_token: Tweetkit::Client.new(bearer_token: ENV['BEARER_TOKEN']),
6+
access_token: Tweetkit::Client.new(
7+
consumer_key: ENV['CONSUMER_KEY'],
8+
consumer_secret: ENV['CONSUMER_SECRET'],
9+
access_token: ENV['ACCESS_TOKEN'],
10+
access_token_secret: ENV['ACCESS_TOKEN_SECRET'],
11+
),
12+
}
13+
14+
client_types.each do |client_type, client|
15+
context "with #{client_type} client" do
16+
describe '.tweet' do
17+
it 'accepts an ID and gets a tweet' do
18+
response = client.tweet(1228393702244134912)
19+
20+
expect(response.tweet.text).not_to be_empty
21+
end
22+
end
23+
24+
describe '.tweets' do
25+
it 'accepts an array of IDs and gets the tweets' do
26+
response = client.tweets([1228393702244134912, 1227640996038684673])
27+
28+
expect(response.tweets.size).to eq(2)
29+
expect(response.tweets.first.text).not_to be_empty
30+
end
731

8-
describe '.tweet' do
9-
it 'accepts an ID and gets a tweet' do
10-
response = @client.tweet(1228393702244134912)
32+
it 'accepts comma-separated string of IDs and gets the tweets' do
33+
response = client.tweets([1228393702244134912, 1227640996038684673])
1134

12-
expect(response.tweet.text).not_to be_empty
35+
expect(response.tweets.size).to eq(2)
36+
expect(response.tweets.first.text).not_to be_empty
37+
end
38+
end
1339
end
1440
end
1541

16-
describe '.tweets' do
17-
it 'accepts an array of IDs and gets the tweets' do
18-
response = @client.tweets([1228393702244134912, 1227640996038684673])
42+
context 'when user context is required' do
43+
let(:client) { client_types[:access_token] }
1944

20-
expect(response.tweets.size).to eq(2)
21-
expect(response.tweets.first.text).not_to be_empty
45+
describe '.post_tweet' do
46+
it 'posts text' do
47+
response = client.post_tweet(text: 'Hello world')
48+
expect(response.tweet.text).not_to be_empty
49+
end
2250
end
2351

24-
it 'accepts comma-separated string of IDs and gets the tweets' do
25-
response = @client.tweets([1228393702244134912, 1227640996038684673])
52+
describe '.delete_tweet' do
53+
it 'deletes a tweet' do
54+
create_response = client.post_tweet(text: 'Hello world')
55+
tweet_id = create_response.tweet.id.to_i
56+
delete_response = client.delete_tweet(tweet_id)
2657

27-
expect(response.tweets.size).to eq(2)
28-
expect(response.tweets.first.text).not_to be_empty
58+
expect(delete_response.response.dig('data', 'deleted')).to be(true)
59+
end
2960
end
3061
end
3162
end

0 commit comments

Comments
 (0)