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

#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;
}