5

Code snippet

#include "stackchat/StackChat.hpp"
#include "stackchat/chat/ChatEvent.hpp"
#include "stackchat/chat/Command.hpp"

#include <iostream>
#include <string>

// This is not the only way to define a command, for the record. Utility classes exist (or will be added when necessary),
// but the goal is to be as flexible as possible.
//
// The system does take a heavy OOP approach, largely to allow for context-based commands. I also like OOP, so that's part of it.
// Plus, it comes with the advantage of allowing stuff like MultiLevelCommand, used in a different demo.
class InterjectCommand : public stackchat::Command {
public:
    void onMessage(stackchat::Room& r, const stackchat::ChatEvent& ev, const std::vector<std::string>&) {
        r.reply(ev, "I'd like to interject for a moment. What you're referring to as chat login is, in fact, an eternal source of pain and suffering.");
    }
};

int main() {
    // This isn't a fantastic way to get the credentials, but it is an option. There are other options as well,
    // this is just the laziest approach I can think of.
    std::string email = std::getenv("STACK_EMAIL"), password = std::getenv("STACK_PASSWORD");
    if (email == "" || password == "") {
        // This is deceptively useless; missing credentials actually results in an initialisation exception (something something null string)
        throw std::runtime_error("Please provide credentials to run the demo.");
    }

    stackchat::StackChat chat({
        .email = email,
        .password = password,
        .prefix = "~", // Required for command functionality. Defaults to nothing, which will disable commands
        .userAgent = "StackChatCppDemos/git (+https://github.com/LunarWatcher/stackchat.cpp)",
    });

    chat.registerCommand("interject", std::make_shared<InterjectCommand>());

    // There are many ways to deal with chat joining, as well as announcements and config, but this is left as an exercise to the reader, because there
    // are very, very many ways to implement it, depending on what the bot is used for.
    chat.join(stackchat::StackSite::STACKOVERFLOW, 1);
    // As an aside, this isn't really the only way to do join announcements.
    // It would be possible to hook up a join listener, and check if the bot triggered the event.
    chat.sendTo(stackchat::StackSite::STACKOVERFLOW, 1, "Chat login is horrible. *angry fox noises*");

    // Only required for chatbot-first applications.
    // The main thread can, after this, be used for something completely different, such as API access.
    // You can also make your own sleep system. This function is just provided as a convenience
    chat.block();
}

Example run:

Screenshot of chat; transcription follows.

Gemmy [bot]: Chat login is horrible. angry fox noises
Zoe [me]: ~interject
Gemmy [bot]: [:reply] I'd like to interject for a moment. What you're referring to as chat login is, in fact, an eternal source of pain and suffering.

Additional demos can be found on GitHub

About

In the same chain as the C++20 API library, I need a chat library for Stuff™. Unlike the API library (where a Boost-based library is available), there are no C++ chat libraries available, at least that I'm aware of or can find here on Stackapps.

The library uses cpr for web requests, nlohmann/json for JSON parsing and deserialisation, spdlog for logging (libfmt is explicitly downloaded as well), and IXWebSocket for (shock) websockets. A general use support library I've previously made is also used. All dependencies are automagically handled thanks to FetchContent.

Note that the library is currently a work in progress, and heavily lacking in documentation, but does function. I also expect to do several revisions of the library interface, particularly as feature requirements and error handling starts being developed, so the library interface is currently considered unstable. This paragraph will be replaced with links to the documentation when stuff is fully ready.

License

MIT. See LICENSE

Source

GitHub

Platform

Theoretically Windows, MacOS, and Linux, but I've only verified that it works on Linux. May also work on any other platforms able to compile C++20 and the dependencies.

Contact

Use GitHub to report any issues. General questions can be posted on GitHub Discussions.

Integration

The recommended integration approach is with submodules (git submodule add https://github.com/LunarWatcher/stackchat.cpp). Alternatively, FetchContent can be used, but this is left as an exercise to the reader for no reason in particular :)

With submodules, integration is done with two lines of code:

add_subdirectory(stackchat.cpp)

# ...

target_link_libraries(never-gonna-bot stackchat)
9
  • Do you have Python version? :p Jun 3, 2023 at 17:42
  • @PeterKolosov I don't, but others have made a Python version. It's arguably the most extensive and well-built library as well, though largely on account of it being used in SmokeDetector Jun 3, 2023 at 17:46
  • I tried SEChat, but his is too lazy and hard... Do you know other Python Stack Exchange Chat Bots API libraries? Jun 3, 2023 at 17:51
  • 3
  • @PeterKolosov as an FYI, SOBotics has a list of available community-maintained implementations of a well-defined API for chat (just an FYI since the only two for Python are ChatExchange & SEChat. I can attest for the quality of the former, but don't know as much about the latter). Jun 3, 2023 at 19:40
  • @OlegValteriswithUkraine I should get mine added to that :P Jun 3, 2023 at 19:43
  • @ZoestandswithUkraine you should :) Ping Bhargav in SOBotics room. Jun 3, 2023 at 20:14
  • 2
    @OlegValteriswithUkraine Will do after the strike. Need to see if there's anything left in the end Jun 3, 2023 at 21:03
  • @ZoestandswithUkraine yes, there is a probability that will be not necessary, unfortunately. Jun 3, 2023 at 21:10

0

You must log in to answer this question.

Browse other questions tagged .