Skip to content

Commit

Permalink
Direct message endpoints changes rebased (#927)
Browse files Browse the repository at this point in the history
* Update endpoint for direct_messages_received

* Update endpoint for direct_messages_sent

* Update endpoint for direct_message show

* Update endpoint for destroying direct message

* Update endpoint for creating direct message

* Fix created_at format for direct message from dm event

* Clean up

* Add limit feature for cursor

Add map method to enumerable

* Rubocop/Code Climate fixes

* Change created_at to allow it to receive a Time object

* Add missing documentation
  • Loading branch information
dancernerd32 authored and sferik committed Jun 19, 2018
1 parent 16a5499 commit 0833471
Show file tree
Hide file tree
Showing 9 changed files with 482 additions and 92 deletions.
5 changes: 4 additions & 1 deletion lib/twitter/creatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ module Creatable
#
# @return [Time]
def created_at
Time.parse(@attrs[:created_at]).utc unless @attrs[:created_at].nil?
time = @attrs[:created_at]
return if time.nil?
time = Time.parse(time) unless time.is_a?(Time)
time.utc
end
memoize :created_at

Expand Down
9 changes: 8 additions & 1 deletion lib/twitter/cursor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ class Cursor
# @param key [String, Symbol] The key to fetch the data from the response
# @param klass [Class] The class to instantiate objects in the response
# @param request [Twitter::REST::Request]
# @param limit [Integer] After reaching the limit, we stop fetching next page
# @return [Twitter::Cursor]
def initialize(key, klass, request)
def initialize(key, klass, request, limit = nil)
@key = key.to_sym
@klass = klass
@client = request.client
@request_method = request.verb
@path = request.path
@options = request.options
@collection = []
@limit = limit
self.attrs = request.perform
end

Expand All @@ -43,6 +45,11 @@ def last?
next_cursor.zero?
end

# @return [Boolean]
def reached_limit?
@limit && @limit <= attrs[@key].count
end

# @return [Hash]
def fetch_next_page
response = Twitter::REST::Request.new(@client, @request_method, @path, @options.merge(cursor: next_cursor)).perform
Expand Down
10 changes: 8 additions & 2 deletions lib/twitter/direct_message_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ class DirectMessageEvent < Twitter::Identity
object_attr_reader :DirectMessage, :direct_message

def initialize(attrs)
text = attrs[:message_create][:message_data][:text]
urls = attrs[:message_create][:message_data][:entities][:urls]
attrs = read_from_response(attrs)
text = attrs.dig(:message_create, :message_data, :text)
urls = attrs.dig(:message_create, :message_data, :entities, :urls)

text.gsub!(urls[0][:url], urls[0][:expanded_url]) if urls.any?

Expand All @@ -23,6 +24,11 @@ def initialize(attrs)

private

# @return [Hash] Normalized hash of attrs
def read_from_response(attrs)
attrs[:event].nil? ? attrs : attrs[:event]
end

def build_direct_message(attrs, text)
recipient_id = attrs[:message_create][:target][:recipient_id].to_i
sender_id = attrs[:message_create][:sender_id].to_i
Expand Down
12 changes: 11 additions & 1 deletion lib/twitter/enumerable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def each(start = 0)
Array(@collection[start..-1]).each do |element|
yield(element)
end
unless last?
unless finished?
start = [@collection.size, start].max
fetch_next_page
each(start, &Proc.new)
Expand All @@ -22,5 +22,15 @@ def each(start = 0)
def last?
true
end

# @return [Boolean]
def reached_limit?
false
end

# @return [Boolean]
def finished?
last? || reached_limit?
end
end
end
125 changes: 77 additions & 48 deletions lib/twitter/rest/direct_messages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,84 +11,112 @@ module DirectMessages
include Twitter::REST::Utils
include Twitter::Utils

# Returns the 20 most recent direct messages sent to the authenticating user
#
# @see https://dev.twitter.com/rest/reference/get/direct_messages
# Returns all Direct Message events for the authenticated user (both sent and received) within the last 30 days. Sorted in reverse-chronological order.
# @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/list-events
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
# @rate_limited Yes
# @authentication Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Array<Twitter::DirectMessage>] Direct messages sent to the authenticating user.
# @return [Array<Twitter::DirectMessageEvent>] Direct message events sent by and received by the authenticating user.
# @param options [Hash] A customizable set of options.
# @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID.
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Integer] :page Specifies the page of results to retrieve.
def direct_messages_received(options = {})
perform_get_with_objects('/1.1/direct_messages.json', options, Twitter::DirectMessage)
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 50. Default is 20
# @option options [String] :cursor Specifies the cursor position of results to retrieve.
def direct_messages_events(options = {})
limit = options.fetch(:count, 20)
perform_get_with_cursor('/1.1/direct_messages/events/list.json', options.merge!(no_default_cursor: true, count: 50, limit: limit), :events, Twitter::DirectMessageEvent)
end

# Returns the 20 most recent direct messages events sent to the authenticating user
# @see https://dev.twitter.com/rest/reference/get/direct_messages/events/list
# Returns all Direct Messages for the authenticated user (both sent and received) within the last 30 days. Sorted in reverse-chronological order.
# @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/list-events
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
# @rate_limited Yes
# @authentication Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Array<Twitter::DirectMessageEvent>] Direct messages sent to and received by the authenticating user.
# @return [Array<Twitter::DirectMessage>] Direct messages sent by and received by the authenticating user.
# @param options [Hash] A customizable set of options.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 50. Default is 20
# @option options [String] :cursor Specifies the cursor position of results to retrieve.
def direct_messages_events(options = {})
perform_get_with_cursor('/1.1/direct_messages/events/list.json', options.merge!(no_default_cursor: true), :events, Twitter::DirectMessageEvent)
def direct_messages_list(options = {})
direct_messages_events(options).collect(&:direct_message)
end

# Returns the 20 most recent direct messages sent by the authenticating user
#
# @see https://dev.twitter.com/rest/reference/get/direct_messages/sent
# Returns Direct Messages received by the authenticated user within the last 30 days. Sorted in reverse-chronological order.
# @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/list-events
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
# @rate_limited Yes
# @authentication Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Array<Twitter::DirectMessage>] Direct messages received by the authenticating user.
# @param options [Hash] A customizable set of options.
# @option options [Integer] :count Specifies the number of records (sent and received dms) to retrieve. Must be less than or equal to 50. Default is 50
# this count does not directly correspond to the output, as we pull sent and received messages from twitter and only present received to the user
# @option options [String] :cursor Specifies the cursor position of results to retrieve.
def direct_messages_received(options = {})
limit = options.fetch(:count, 20)
direct_messages_list(options).select { |dm| dm.recipient_id == user_id }.first(limit)
end

# Returns Direct Messages sent by the authenticated user within the last 30 days. Sorted in reverse-chronological order.
# @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/list-events
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
# @rate_limited Yes
# @authentication Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Array<Twitter::DirectMessage>] Direct messages sent by the authenticating user.
# @param options [Hash] A customizable set of options.
# @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID.
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Integer] :page Specifies the page of results to retrieve.
# @option options [Integer] :count Specifies the number of records (sent and received dms) to retrieve. Must be less than or equal to 50. Default is 50
# this count does not directly correspond to the output, as we pull sent and received messages from twitter and only present received to the user
# @option options [String] :cursor Specifies the cursor position of results to retrieve.
def direct_messages_sent(options = {})
perform_get_with_objects('/1.1/direct_messages/sent.json', options, Twitter::DirectMessage)
limit = options.fetch(:count, 20)
direct_messages_list(options).select { |dm| dm.sender_id == user_id }.first(limit)
end

# Returns a direct message
#
# @see https://dev.twitter.com/rest/reference/get/direct_messages/show
# @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-event
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
# @rate_limited Yes
# @authentication Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Twitter::DirectMessage] The requested messages.
# @return [Twitter::DirectMessage] The requested message.
# @param id [Integer] A direct message ID.
# @param options [Hash] A customizable set of options.

def direct_message(id, options = {})
direct_message_event(id, options).direct_message
end

# Returns a direct message event
#
# @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-event
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
# @rate_limited Yes
# @authentication Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Twitter::DirectMessageEvent] The requested message.
# @param id [Integer] A direct message ID.
# @param options [Hash] A customizable set of options.
def direct_message_event(id, options = {})
options = options.dup
options[:id] = id
perform_get_with_object('/1.1/direct_messages/show.json', options, Twitter::DirectMessage)
perform_get_with_object('/1.1/direct_messages/events/show.json', options, Twitter::DirectMessageEvent)
end

# Returns direct messages specified in arguments, or, if no arguments are given, returns direct messages received by authenticating user
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
# @rate_limited Yes
# @authentication Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Array<Twitter::DirectMessage>] The requested messages.
# @overload direct_messages(options = {})
# Returns the 20 most recent direct messages sent to the authenticating user
#
# @see https://dev.twitter.com/rest/reference/get/direct_messages

# @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/list-events
# @param options [Hash] A customizable set of options.
# @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID.
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Integer] :page Specifies the page of results to retrieve.
# @option options [Integer] :count Specifies the number of records (sent and received dms) to retrieve. Must be less than or equal to 50. Default is 50
# this count does not directly correspond to the output, as we pull sent and received messages from twitter and only present received to the user
# @option options [String] :cursor Specifies the cursor position of results to retrieve.
# @overload direct_messages(*ids)
# Returns direct messages
#
Expand All @@ -113,36 +141,31 @@ def direct_messages(*args)

# Destroys direct messages
#
# @see https://dev.twitter.com/rest/reference/post/direct_messages/destroy
# @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/delete-message-event
# @note This method requires an access token with RWD (read, write & direct message) permissions. Consult The Application Permission Model for more information.
# @rate_limited No
# @rate_limited Yes
# @authentication Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Array<Twitter::DirectMessage>] Deleted direct message.
# @return [nil] Response body from Twitter is nil if successful
# @overload destroy_direct_message(*ids)
# @param ids [Enumerable<Integer>] A collection of direct message IDs.
# @overload destroy_direct_message(*ids, options)
# @param ids [Enumerable<Integer>] A collection of direct message IDs.
# @param options [Hash] A customizable set of options.
def destroy_direct_message(*args)
parallel_objects_from_response(Twitter::DirectMessage, :post, '/1.1/direct_messages/destroy.json', args)
def destroy_direct_message(*ids)
perform_requests(:delete, '/1.1/direct_messages/events/destroy.json', ids)
end

# Sends a new direct message to the specified user from the authenticating user
#
# @see https://dev.twitter.com/rest/reference/post/direct_messages/new
# @rate_limited No
# @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event
# @rate_limited Yes
# @authentication Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @return [Twitter::DirectMessage] The sent message.
# @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, URI, or object.
# @param user [Integer, String, Twitter::User] A Twitter user ID
# @param text [String] The text of your direct message, up to 10,000 characters.
# @param options [Hash] A customizable set of options.
def create_direct_message(user, text, options = {})
options = options.dup
merge_user!(options, user)
options[:text] = text
perform_post_with_object('/1.1/direct_messages/new.json', options, Twitter::DirectMessage)
def create_direct_message(user_id, text, options = {})
event = perform_request_with_object(:json_post, '/1.1/direct_messages/events/new.json', format_json_options(user_id, text, options), Twitter::DirectMessageEvent)
event.direct_message
end
alias d create_direct_message
alias m create_direct_message
Expand All @@ -168,6 +191,12 @@ def create_direct_message_event(*args)
response = Twitter::REST::Request.new(self, :json_post, '/1.1/direct_messages/events/new.json', options).perform
Twitter::DirectMessageEvent.new(response[:event])
end

private

def format_json_options(user_id, text, options)
{'event': {'type': 'message_create', 'message_create': {'target': {'recipient_id': user_id}, 'message_data': {'text': text}.merge(options)}}}
end
end
end
end
2 changes: 1 addition & 1 deletion lib/twitter/rest/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def initialize(client, request_method, path, options = {})
set_multipart_options!(request_method, options)
@path = uri.path
@options = options
@options_key = {get: :params, json_post: :json}[request_method] || :form
@options_key = {get: :params, json_post: :json, delete: :params}[request_method] || :form
end

# @return [Array, Hash]
Expand Down
14 changes: 13 additions & 1 deletion lib/twitter/rest/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,15 @@ def perform_request_with_objects(request_method, path, options, klass)
# @param collection_name [Symbol]
# @param klass [Class]
def perform_get_with_cursor(path, options, collection_name, klass = nil)
limit = options.delete(:limit)
if options[:no_default_cursor]
options.delete(:no_default_cursor)
else
merge_default_cursor!(options)
end

request = Twitter::REST::Request.new(self, :get, path, options)
Twitter::Cursor.new(collection_name.to_sym, klass, request)
Twitter::Cursor.new(collection_name.to_sym, klass, request, limit)
end

# @param request_method [Symbol]
Expand Down Expand Up @@ -156,6 +157,17 @@ def parallel_objects_from_response(klass, request_method, path, args)
end
end

# @param request_method [Symbol]
# @param path [String]
# @param ids [Array]
# @return nil
def perform_requests(request_method, path, ids)
ids.each do |id|
perform_request(request_method, path, id: id)
end
nil
end

# @param collection_name [Symbol]
# @param klass [Class]
# @param path [String]
Expand Down
Loading

0 comments on commit 0833471

Please sign in to comment.