Merge pull request #44 from DomainDrivenArchitecture/refactor_twitter

mastodon bug fix & refactor twitter-api
master
Dmitri Sotnikov 4 years ago committed by GitHub
commit 3576ca2352
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,7 +3,7 @@
:dependencies [[orchestra "2018.12.06-2"]] :dependencies [[orchestra "2018.12.06-2"]]
:builds {:dev {:target :node-library :builds {:dev {:target :node-library
:output-to "target/lib-mastodon-bot.js" :output-to "target/lib-mastodon-bot.js"
:exports {:infra mastodon-bot.infra/js->edn} :exports {:infra mastodon-bot.core/-main}
:repl-pprint true :repl-pprint true
} }
:app {:target :node-script :app {:target :node-script

@ -9,12 +9,12 @@
[clojure.string :as string] [clojure.string :as string]
["rss-parser" :as rss] ["rss-parser" :as rss]
["tumblr" :as tumblr] ["tumblr" :as tumblr]
["twitter" :as twitter]
[mastodon-bot.infra :as infra] [mastodon-bot.infra :as infra]
[mastodon-bot.mastodon-api :as masto])) [mastodon-bot.mastodon-api :as masto]
[mastodon-bot.twitter-api :as twitter]))
(s/def ::mastodon-config masto/mastodon-config?) (s/def ::mastodon-config masto/mastodon-config?)
(s/def ::twitter map?) (s/def ::twitter twitter/twitter-config?)
(s/def ::tumblr map?) (s/def ::tumblr map?)
(s/def ::rss map?) (s/def ::rss map?)
@ -25,6 +25,10 @@
[config config?] [config config?]
(:mastodon-config config)) (:mastodon-config config))
(defn-spec twitter-config ::twitter
[config config?]
(:twitter config))
(def config (infra/load-config)) (def config (infra/load-config))
(defn trim-text [text] (defn trim-text [text]
@ -96,9 +100,6 @@
(mastodon-config config) (mastodon-config config)
last-post-time))))) last-post-time)))))
(defn strip-utm [news-link]
(first (string/split news-link #"\?utm")))
(defn parse-feed [last-post-time parser [title url]] (defn parse-feed [last-post-time parser [title url]]
(-> (.parseURL parser url) (-> (.parseURL parser url)
(.then #(masto/post-items (.then #(masto/post-items
@ -106,14 +107,7 @@
last-post-time last-post-time
(for [{:keys [title isoDate pubDate content link]} (-> % infra/js->edn :items)] (for [{:keys [title isoDate pubDate content link]} (-> % infra/js->edn :items)]
{:created-at (js/Date. (or isoDate pubDate)) {:created-at (js/Date. (or isoDate pubDate))
:text (str (trim-text title) "\n\n" (strip-utm link))}))))) :text (str (trim-text title) "\n\n" (twitter/strip-utm link))})))))
(defn twitter-client [access-keys]
(try
(twitter. (clj->js access-keys))
(catch js/Error e
(infra/exit-with-error
(str "failed to connect to Twitter: " (.-message e))))))
(defn tumblr-client [access-keys account] (defn tumblr-client [access-keys account]
(try (try
@ -129,16 +123,12 @@
(let [last-post-time (-> timeline first :created_at (js/Date.))] (let [last-post-time (-> timeline first :created_at (js/Date.))]
;;post from Twitter ;;post from Twitter
(when-let [twitter-config (:twitter config)] (when-let [twitter-config (:twitter config)]
(let [{:keys [access-keys accounts include-replies? include-rts?]} twitter-config (let [{:keys [accounts]} twitter-config]
client (twitter-client access-keys)]
(doseq [account accounts] (doseq [account accounts]
(.get client (twitter/user-timeline
"statuses/user_timeline" twitter-config
#js {:screen_name account account
:tweet_mode "extended" (post-tweets last-post-time)))))
:include_rts (boolean include-rts?)
:exclude_replies (not (boolean include-replies?))}
(post-tweets last-post-time)))))
;;post from Tumblr ;;post from Tumblr
(when-let [{:keys [access-keys accounts limit]} (:tumblr config)] (when-let [{:keys [access-keys accounts limit]} (:tumblr config)]
(doseq [account accounts] (doseq [account accounts]

@ -9,7 +9,6 @@
["request" :as request] ["request" :as request]
["mastodon-api" :as mastodon])) ["mastodon-api" :as mastodon]))
; Todo: think about how namespaced keywords & clj->js can play nicely together
(s/def ::access_token string?) (s/def ::access_token string?)
(s/def ::api_url string?) (s/def ::api_url string?)
(s/def ::account-id string?) (s/def ::account-id string?)
@ -163,7 +162,7 @@
items any?] items any?]
(doseq [{:keys [text media-links]} (doseq [{:keys [text media-links]}
(->> items (->> items
(remove #((blocked-content? mastodon-config (:text %)))) (remove #(blocked-content? mastodon-config (:text %)))
(filter #(> (:created-at %) last-post-time)))] (filter #(> (:created-at %) last-post-time)))]
(if media-links (if media-links
(post-status-with-images mastodon-config text media-links) (post-status-with-images mastodon-config text media-links)

@ -0,0 +1,48 @@
(ns mastodon-bot.twitter-api
(:require
[clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as st]
[orchestra.core :refer-macros [defn-spec]]
[clojure.string :as string]
["twitter" :as twitter]
[mastodon-bot.infra :as infra]
))
(s/def ::consumer_key string?)
(s/def ::consumer_secret string?)
(s/def ::access_token_key string?)
(s/def ::access_token_secret string?)
(s/def ::access-keys (s/keys :req-un [::consumer_key ::consumer_secret ::access_token_key
::access_token_secret]))
(s/def ::include-rts? boolean?)
(s/def ::include-replies? boolean?)
(s/def ::account string?)
(s/def ::accounts (s/* ::account))
(def twitter-config? (s/keys :req-un [::access-keys ::include-rts? ::include-replies?]))
(defn strip-utm [news-link]
(first (string/split news-link #"\?utm")))
(defn-spec twitter-client any?
[twitter-config twitter-config?]
(let [{:keys [access-keys]} twitter-config]
(try
(twitter. (clj->js access-keys))
(catch js/Error e
(infra/exit-with-error
(str "failed to connect to Twitter: " (.-message e)))))))
(defn-spec user-timeline any?
[twitter-config twitter-config?
account ::account
callback fn?]
(let [{:keys [include-rts? include-replies?]} twitter-config]
(.get (twitter-client twitter-config)
"statuses/user_timeline"
#js {:screen_name account
:tweet_mode "extended"
:include_rts (boolean include-rts?)
:exclude_replies (not (boolean include-replies?))}
callback)))