#include #include #include #include #include #include #include using json = nlohmann::json; struct config { std::string lfm_api_key; std::string dsc_app_id; std::string lfm_user; }; struct current_status { bool playing; std::string artist; std::string track; }; // https://stackoverflow.com/a/2072890/1243281 inline bool ends_with(std::string const & value, std::string const & ending) { if (ending.size() > value.size()) return false; return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); } void init(config cfg) { DiscordEventHandlers handlers; memset(&handlers, 0, sizeof(handlers)); Discord_Initialize(cfg.dsc_app_id.c_str(), &handlers, 1, NULL); } void update(current_status status) { DiscordRichPresence discordPresence; memset(&discordPresence, 0, sizeof(discordPresence)); discordPresence.largeImageKey = "default"; if (status.playing) { discordPresence.state = status.artist.c_str(); discordPresence.details = status.track.c_str(); } else { discordPresence.state = "Idle"; } Discord_UpdatePresence(&discordPresence); } current_status get_lfm_data(config cfg) { std::string url = "/2.0/?method=user.getrecenttracks&user=" + cfg.lfm_user + "&api_key=" + cfg.lfm_api_key + "&format=json"; httplib::Client cli("ws.audioscrobbler.com", 80); auto res = cli.get(url.c_str()); if (res && res->status == 200) { json j = json::parse(res->body); json t = j["recenttracks"]["track"][0]; if (t.find("@attr") != t.end() && t["@attr"].find("nowplaying") != t["@attr"].end() && t["@attr"]["nowplaying"] == "true") { return { true, t["artist"]["#text"], t["name"] }; } } return { false, "", "" }; } config load_config() { std::ifstream t("config.json"); std::stringstream buffer; buffer << t.rdbuf(); json cfg = json::parse(buffer); return { cfg["lfm_api_key"], cfg["dsc_app_id"], cfg["lfm_user"] }; } int main(int argc, char* argv[]) { config cfg = load_config(); init(cfg); while (true) { current_status c = get_lfm_data(cfg); update(c); std::this_thread::sleep_for(std::chrono::seconds(30)); } Discord_Shutdown(); return 0; }