Merge pull request #44 from DomainDrivenArchitecture/refactor_twitter
mastodon bug fix & refactor twitter-api
This commit is contained in:
commit
3576ca2352
4 changed files with 63 additions and 26 deletions
|
@ -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)
|
||||||
|
|
48
src/main/mastodon_bot/twitter_api.cljs
Executable file
48
src/main/mastodon_bot/twitter_api.cljs
Executable file
|
@ -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)))
|
||||||
|
|
Reference in a new issue