# frozen_string_literal: true # A simple Twitter API client that can authenticate to Twitter and fetch tweets by ID. # @see https://developer.twitter.com/en/docs/getting-started class TwitterApiClient extend Memoist attr_reader :api_key, :api_secret, :http # Create a Twitter API client # @param api_key [String] the Twitter API key # @param api_secret [String] the Twitter API secret def initialize(api_key, api_secret, http: Danbooru::Http.new) @api_key, @api_secret, @http = api_key, api_secret, http end # Authenticate to Twitter with an API key and secret and receive a bearer token in response. # @param token_expiry [Integer] the number of seconds to cache the token # @return [String] the Twitter bearer token # @see https://developer.twitter.com/en/docs/authentication/api-reference/token def bearer_token(token_expiry = 24.hours) response = http.basic_auth(user: api_key, pass: api_secret).cache(token_expiry).post("https://api.twitter.com/oauth2/token", form: { grant_type: :client_credentials }) response.parse["access_token"] end # @return [Danbooru::Http] the HTTP client to connect to Twitter with def client http.auth("Bearer #{bearer_token}") end # Fetch a tweet by id. # @param id [Integer] the Twitter tweet id # @param cache [Integer] the number of seconds to cache the response # @return [Object] the tweet # @see https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-show-id def status(id, cache: 1.minute) response = client.cache(cache).get("https://api.twitter.com/1.1/statuses/show.json?id=#{id}&tweet_mode=extended") response.parse.with_indifferent_access end memoize :bearer_token, :client end