diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2022-11-15 17:44:56 -0500 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2022-11-15 17:44:56 -0500 |
commit | 12b25928d0ec2b18dda075b8c3b37b8a7e6f1172 (patch) | |
tree | cb61f94bff879401288d19655200b20433871155 /ebooks.cpp | |
parent | e6f5d46db4245a27ac9dba90dcbb08caf9ee8a97 (diff) | |
download | rawr-ebooks-12b25928d0ec2b18dda075b8c3b37b8a7e6f1172.tar.gz rawr-ebooks-12b25928d0ec2b18dda075b8c3b37b8a7e6f1172.tar.bz2 rawr-ebooks-12b25928d0ec2b18dda075b8c3b37b8a7e6f1172.zip |
Bot now posts to Mastodon instead of Twitter
Diffstat (limited to 'ebooks.cpp')
-rw-r--r-- | ebooks.cpp | 79 |
1 files changed, 37 insertions, 42 deletions
diff --git a/ebooks.cpp b/ebooks.cpp index 3918b78..08be38e 100644 --- a/ebooks.cpp +++ b/ebooks.cpp | |||
@@ -4,12 +4,13 @@ | |||
4 | #include "kgramstats.h" | 4 | #include "kgramstats.h" |
5 | #include <fstream> | 5 | #include <fstream> |
6 | #include <iostream> | 6 | #include <iostream> |
7 | #include <twitter.h> | 7 | #include <mastodonpp/mastodonpp.hpp> |
8 | #include <yaml-cpp/yaml.h> | 8 | #include <yaml-cpp/yaml.h> |
9 | #include <thread> | 9 | #include <thread> |
10 | #include <chrono> | 10 | #include <chrono> |
11 | #include <algorithm> | 11 | #include <algorithm> |
12 | #include <random> | 12 | #include <random> |
13 | #include "timeline.h" | ||
13 | 14 | ||
14 | const auto QUEUE_TIMEOUT = std::chrono::minutes(1); | 15 | const auto QUEUE_TIMEOUT = std::chrono::minutes(1); |
15 | const auto POLL_TIMEOUT = std::chrono::minutes(5); | 16 | const auto POLL_TIMEOUT = std::chrono::minutes(5); |
@@ -22,13 +23,13 @@ int main(int argc, char** args) | |||
22 | YAML::Node config = YAML::LoadFile("config.yml"); | 23 | YAML::Node config = YAML::LoadFile("config.yml"); |
23 | int delay = config["delay"].as<int>(); | 24 | int delay = config["delay"].as<int>(); |
24 | 25 | ||
25 | twitter::auth auth( | 26 | mastodonpp::Instance instance{ |
26 | config["consumer_key"].as<std::string>(), | 27 | config["mastodon_instance"].as<std::string>(), |
27 | config["consumer_secret"].as<std::string>(), | 28 | config["mastodon_token"].as<std::string>()}; |
28 | config["access_key"].as<std::string>(), | 29 | mastodonpp::Connection connection{instance}; |
29 | config["access_secret"].as<std::string>()); | ||
30 | 30 | ||
31 | twitter::client client(auth); | 31 | timeline mentions(mastodonpp::API::v1::notifications); |
32 | mentions.poll(connection); // just ignore the results | ||
32 | 33 | ||
33 | std::ifstream infile(config["corpus"].as<std::string>().c_str()); | 34 | std::ifstream infile(config["corpus"].as<std::string>().c_str()); |
34 | std::string corpus; | 35 | std::string corpus; |
@@ -78,7 +79,7 @@ int main(int argc, char** args) | |||
78 | return form; | 79 | return form; |
79 | }); | 80 | }); |
80 | 81 | ||
81 | std::list<std::tuple<std::string, bool, twitter::tweet_id>> postQueue; | 82 | std::list<std::tuple<std::string, bool, std::string>> postQueue; |
82 | 83 | ||
83 | auto startedTime = std::chrono::system_clock::now(); | 84 | auto startedTime = std::chrono::system_clock::now(); |
84 | 85 | ||
@@ -93,13 +94,11 @@ int main(int argc, char** args) | |||
93 | if (currentTime >= genTimer) | 94 | if (currentTime >= genTimer) |
94 | { | 95 | { |
95 | std::string doc = kgramstats.randomSentence(140, rng); | 96 | std::string doc = kgramstats.randomSentence(140, rng); |
96 | doc.resize(140); | 97 | doc.resize(500); |
97 | 98 | ||
98 | postQueue.emplace_back(std::move(doc), false, 0); | 99 | postQueue.emplace_back(std::move(doc), false, ""); |
99 | 100 | ||
100 | int genwait = std::uniform_int_distribution<int>(1, delay)(rng); | 101 | genTimer = currentTime + std::chrono::seconds(delay); |
101 | |||
102 | genTimer = currentTime + std::chrono::seconds(genwait); | ||
103 | } | 102 | } |
104 | 103 | ||
105 | if (currentTime >= pollTimer) | 104 | if (currentTime >= pollTimer) |
@@ -108,36 +107,27 @@ int main(int argc, char** args) | |||
108 | 107 | ||
109 | try | 108 | try |
110 | { | 109 | { |
111 | std::list<twitter::tweet> newTweets = | 110 | std::list<nlohmann::json> newNotifs = mentions.poll(connection); |
112 | client.getMentionsTimeline().poll(); | ||
113 | 111 | ||
114 | for (const twitter::tweet& tweet : newTweets) | 112 | for (const nlohmann::json& notif : newNotifs) |
115 | { | 113 | { |
116 | auto createdTime = | ||
117 | std::chrono::system_clock::from_time_t(tweet.getCreatedAt()); | ||
118 | |||
119 | if ( | 114 | if ( |
120 | // Ignore tweets from before the bot started up | 115 | notif["type"].get<std::string>() == "mention" |
121 | createdTime > startedTime | ||
122 | // Ignore retweets | 116 | // Ignore retweets |
123 | && !tweet.isRetweet() | 117 | && notif["status"]["reblog"].is_null()) |
124 | // Ignore tweets from yourself | ||
125 | && tweet.getAuthor() != client.getUser()) | ||
126 | { | 118 | { |
127 | std::string doc = tweet.generateReplyPrefill(client.getUser()); | 119 | std::string doc = "@" + notif["status"]["account"]["acct"].get<std::string>() + " "; |
128 | doc += kgramstats.randomSentence(140 - doc.length(), rng); | 120 | doc += kgramstats.randomSentence(500 - doc.length(), rng); |
129 | doc.resize(140); | 121 | doc.resize(500); |
130 | 122 | ||
131 | postQueue.emplace_back(std::move(doc), true, tweet.getID()); | 123 | postQueue.emplace_back(std::move(doc), true, notif["status"]["id"]); |
132 | } | 124 | } |
133 | } | 125 | } |
134 | } catch (const twitter::rate_limit_exceeded&) | 126 | } catch (const std::exception& e) |
135 | { | 127 | { |
128 | std::cout << "Twitter error while polling: " << e.what() << std::endl; | ||
136 | // Wait out the rate limit (10 minutes here and 5 below = 15). | 129 | // Wait out the rate limit (10 minutes here and 5 below = 15). |
137 | pollTimer += std::chrono::minutes(10); | 130 | pollTimer += std::chrono::minutes(10); |
138 | } catch (const twitter::twitter_error& e) | ||
139 | { | ||
140 | std::cout << "Twitter error while polling: " << e.what() << std::endl; | ||
141 | } | 131 | } |
142 | 132 | ||
143 | pollTimer += std::chrono::minutes(POLL_TIMEOUT); | 133 | pollTimer += std::chrono::minutes(POLL_TIMEOUT); |
@@ -145,21 +135,26 @@ int main(int argc, char** args) | |||
145 | 135 | ||
146 | if ((currentTime >= queueTimer) && (!postQueue.empty())) | 136 | if ((currentTime >= queueTimer) && (!postQueue.empty())) |
147 | { | 137 | { |
148 | auto post = postQueue.front(); | 138 | auto [result, isReply, replyTo] = postQueue.front(); |
149 | postQueue.pop_front(); | 139 | postQueue.pop_front(); |
150 | 140 | ||
151 | try | 141 | mastodonpp::parametermap parameters{{"status", result}}; |
142 | if (isReply) { | ||
143 | parameters["in_reply_to_id"] = replyTo; | ||
144 | } | ||
145 | |||
146 | auto answer{connection.post(mastodonpp::API::v1::statuses, parameters)}; | ||
147 | if (!answer) | ||
152 | { | 148 | { |
153 | if (std::get<1>(post)) | 149 | if (answer.curl_error_code == 0) |
154 | { | 150 | { |
155 | client.replyToTweet(std::get<0>(post), std::get<2>(post)); | 151 | std::cout << "HTTP status: " << answer.http_status << std::endl; |
156 | } else { | 152 | } |
157 | client.updateStatus(std::get<0>(post)); | 153 | else |
154 | { | ||
155 | std::cout << "libcurl error " << std::to_string(answer.curl_error_code) | ||
156 | << ": " << answer.error_message << std::endl; | ||
158 | } | 157 | } |
159 | } catch (const twitter::twitter_error& error) | ||
160 | { | ||
161 | std::cout << "Twitter error while tweeting: " << error.what() | ||
162 | << std::endl; | ||
163 | } | 158 | } |
164 | 159 | ||
165 | queueTimer = currentTime + std::chrono::minutes(QUEUE_TIMEOUT); | 160 | queueTimer = currentTime + std::chrono::minutes(QUEUE_TIMEOUT); |