You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
5.6 KiB
184 lines
5.6 KiB
#include <csignal> |
|
#include <cstdio> |
|
#include <cstdlib> |
|
#include <exception> |
|
#include <istream> |
|
#include <sstream> |
|
#include <stdexcept> |
|
#include <string> |
|
|
|
#include <spdlog/spdlog.h> |
|
#include <tgbot/tgbot.h> |
|
#include <nlohmann/json.hpp> |
|
|
|
#include "util.h" |
|
#include "spotify.h" |
|
#include "songdb.h" |
|
|
|
using namespace TgBot; |
|
using json = nlohmann::json; |
|
|
|
int main() { |
|
spdlog::set_level(spdlog::level::info); // Set global log level to debug |
|
spdlog::enable_backtrace(32); |
|
|
|
char *teletok = getenv("TELEGRAM_TOKEN"); |
|
|
|
// needed if file not exist |
|
char *spotid = getenv("SPOTIFY_ID"); |
|
char *spotsecret = getenv("SPOTIFY_SECRET"); |
|
char *spotaccess_token = getenv("SPOTIFY_TOKEN"); |
|
|
|
if (!teletok) { |
|
std::cout << "Need to set environment variable TELEGRAM_TOKEN" << std::endl; |
|
exit(1); |
|
} |
|
|
|
if (!spotaccess_token) { |
|
if (!spotid) { |
|
std::cout << "Need to set environment variable SPOTIFY_ID or SPOTIFY_TOKEN" << std::endl; |
|
exit(1); |
|
} |
|
if (!spotsecret) { |
|
std::cout << "Need to set environment variable SPOTIFY_SECRET of SPOTIFY_TOKEN" << std::endl; |
|
exit(1); |
|
} |
|
} |
|
|
|
spotify *s; |
|
if (spotaccess_token) |
|
s = new spotify(spotaccess_token); |
|
else |
|
s = new spotify(spotid, spotsecret); |
|
|
|
signal(SIGINT, [](int s) { |
|
spdlog::info("Shutting down..."); |
|
exit(0); |
|
}); |
|
|
|
songdb data {"test.db"}; |
|
std::string teletoken {teletok}; |
|
Bot bot(teletoken); |
|
|
|
InlineKeyboardMarkup::Ptr keyboard(new InlineKeyboardMarkup); |
|
std::vector<InlineKeyboardButton::Ptr> row0; |
|
|
|
for(int i = 0; i <= 4; i++) { |
|
InlineKeyboardButton::Ptr btn(new InlineKeyboardButton); |
|
btn->text = std::to_string(i); |
|
btn->callbackData= std::to_string(i); |
|
row0.push_back(btn); |
|
} |
|
|
|
keyboard->inlineKeyboard.push_back(row0); |
|
|
|
bot.getEvents().onCallbackQuery([&bot, &keyboard, &data](CallbackQuery::Ptr query) { |
|
if ((query->data == "1") || (query->data == "2") || (query->data == "3") || (query->data == "4") || (query->data == "0")) { |
|
std::istringstream is {query->data}; |
|
int value; |
|
is >> value; |
|
|
|
std::string songidflag = "songid:"; |
|
auto a = query->message->text.find(songidflag); |
|
auto b = query->message->text.find("\n", a); |
|
|
|
if (a == std::string::npos || b == std::string::npos) { |
|
spdlog::error("Parse songid"); |
|
spdlog::dump_backtrace(); |
|
return; |
|
} |
|
a += songidflag.length(); |
|
|
|
std::istringstream is2 {query->message->text.substr(a, b - a)}; |
|
int64_t songid; |
|
is2 >> songid; |
|
auto song = data.get_song(songid); |
|
if (!song) { |
|
spdlog::error ("bad song id"); |
|
} |
|
|
|
data.insert_vote(query->from->id, query->message->chat->id, value, songid); |
|
} |
|
}); |
|
|
|
bot.getEvents().onCommand("add", [&bot, &keyboard, &data, s](Message::Ptr message) { |
|
std::string title; |
|
std::string artist; |
|
int songid; |
|
|
|
if (message->text.find("spotify.com") != std::string::npos) { |
|
std::string link = util::trim_whitespace(message->text.substr(message->text.find("add") + 3)); |
|
auto resp = s->track_id_from_link(link); |
|
if (!resp) { |
|
bot.getApi().sendMessage(message->chat->id, "Sorry, I don't understand that link."); |
|
return; |
|
} |
|
|
|
auto spot_resp = s->get_track(*resp); |
|
|
|
if (!spot_resp) { |
|
bot.getApi().sendMessage(message->chat->id, "Sorry, I cannot find that track in spotify."); |
|
return; |
|
} |
|
|
|
json track_data = *spot_resp; |
|
|
|
title = track_data["name"]; |
|
artist = track_data["artists"][0]["name"]; |
|
auto song = data.insert_song(title, artist, *resp); |
|
songid = song->id; |
|
} else { |
|
title = util::trim_whitespace(message->text.substr(message->text.find("add") + 3)); |
|
artist = ""; |
|
auto song = data.insert_song(title, artist, {}); |
|
songid = song->id; |
|
} |
|
|
|
std::string response = "Added song: " + title; |
|
if (artist != "") |
|
response += ", by " + artist; |
|
|
|
response += "\n\n"; |
|
std::ostringstream os; |
|
os << songid; |
|
|
|
response += "songid:" + os.str() + "\n\r\n\r"; |
|
response += "Everyone, please rate how well you know this song /5"; |
|
|
|
bot.getApi().sendMessage(message->chat->id, response, false, 0, keyboard, "Markdown"); |
|
}); |
|
|
|
bot.getEvents().onCommand("vote", [&bot](Message::Ptr message) { |
|
bot.getApi().sendMessage(message->chat->id, "Hi!"); |
|
}); |
|
|
|
|
|
bot.getEvents().onCommand("start", [&bot, &data](Message::Ptr message) { |
|
bot.getApi().sendMessage(message->chat->id, "Hi!"); |
|
}); |
|
|
|
bot.getEvents().onCommand("list", [&bot, &data](Message::Ptr message) { |
|
try { |
|
std::string response = data.get_top_5_songs(message->chat->id); |
|
bot.getApi().sendMessage(message->chat->id, response); |
|
} catch (std::exception const &e) { |
|
spdlog::error("exp: {}", e.what()); |
|
spdlog::dump_backtrace(); |
|
} |
|
}); |
|
|
|
try { |
|
printf("Bot username: %s\n", bot.getApi().getMe()->username.c_str()); |
|
bot.getApi().deleteWebhook(); |
|
TgLongPoll longPoll(bot); |
|
while (true) { |
|
printf("Long poll started\n"); |
|
longPoll.start(); |
|
} |
|
} catch (std::exception& e) { |
|
printf("error: %s\n", e.what()); |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
|