Skip to content

Clients

Simon Olofsson edited this page Dec 6, 2022 · 18 revisions

Pyttman version >= 1.2.1

Client support and API

Pyttman enables you as a developer to write a digital assistant / chatbot without re-inventing the wheel every time you want to extend its functionality or develop another bot for a different use case, and also to use your app with different platforms without re-writing your app for each one. A part of this is the Client support in Pyttman.

What is a Client anyway?

When you communicate with your chatbot, you're doing it through some kind of platform. It could be anything from a website chat component, a platform such as Discord or Telegram - it may even be a plain console window.

On your chatbot's side, these platforms integrate with your Pyttman app through clients. One client for each plattform is the idea.

Since plattforms use different schemas of their API's and not all interfaces look the same, Pyttman comes with an interface of the BaseClient client class.

The BaseClient class ensures that all clients used with Pyttman conform to a minimal standard of properties and methods.

Ready-to-use clients

Pyttman 1.1.4 comes pre-packaged with two clients:

  • CLIClient ( CommandLineInterfaceClient ) - chat with your Pyttman app in a terminal window
  • DiscordClient - Host your Pyttman app as a Discord chatbot

BaseClient(*args, message_router: AbstractMessageRouter, **kwargs)

Baseclass for Clients, for interfacing with users directly or through an API.

Attributes

  • message_router - MessageRouter

Methods

  • run_client(self)
    Starts the main method for the client, opening
    a session to the front end with which it is
    associated with.
    :return: None

CliClient(*args, message_router: AbstractMessageRouter, **kwargs)

The CliClient class is the most basic client class. It will run in the terminal window where the app is started, and show a simple command line interface in which you can write commands to your Pyttman app.

Attributes

  • message_router - MessageRouter

Methods

  • run_client(self)

    Starts the main method for the client, opening
    a session to the front end with which it is
    associated with.
    :return: None
    
  • publish(reply: Reply)

    Publish a message to the user.
    
    :param reply: Reply object
    :return: None
    

How to use with settings.py in a Pyttman app

# settings.py

CLIENT = {
    "class": "pyttman.clients.builtin.cli.CliClient"
}

DiscordClient(*args, message_router: AbstractMessageRouter, **kwargs)

Note!

This class inherits from the discord.py module's Client class. All methods and attributes are therefore available. on_message has been overloaded in this class to integrate the Discord on_message response with what your app produces as a Reply.

For other available hooks in this class, please read the discord Client documentation available here.

Attributes

  • message_router - MessageRouter

  • token - str, token string from discord developer portal for your bot app

  • guild - str - guild ID for the server on which the bot should join on

  • message_startswith - define what messages have to start with for your app to register them. Can be a single character or a word, equal to str().startswith().

  • message_endswith - define what messages have to end with for your app to register them. Can be a single character or a word, equal to str().endswith().

Methods

  • on_message(self)

    Overloads on_message in discord.Client().The
    method is called implicitly whenever an incoming
    message over the discord interface is intercepted.
    All messages are parsed, thus it's a good idea to
    verify that the author is not self to prevent endless
    loops.
    :param message: discord.Message
    :return: None
    
  • run_client(self)

    Starts the main method for the client, opening
    a session to the front end with which it is
    associated with.
    :return: None
    

Tip!

if you want to define hooks for your Discord bot, such as the on_member_join or any other available event hook which is not defined in the DiscordClient by default, you can subclass DiscordClient and overload these hooks as you please.

How to use with settings.py in a Pyttman app

Note!

Remember to use the import reference in settings.py in the class field instead of the DiscordClient import reference, e.g. myapp.client.MyCustomDiscordClient

Important - Discord Intents

With discord.py 2.0.0 being mandatory as of January 2023, the new discord.Intent class is a mandatory argument to pass to the discord client object. In short, discord Intents toggle feature flags which controls which parts of the Discord platform the bot has access to during runtime. In order for Pyttman to work with Discord, the content property on message objects must be available; or routing can't function. This means that the message_content intent must be set to True to use Discord with Pyttman. This intent is set to False by default as to not make passive decisions for developers - but an error is raised, informing you of this issue.

You can read more about them in the official documentation here: https://discordpy.readthedocs.io/en/stable/api.html#discord.Intents

In Pyttman apps, this is configured in settings.py. All you have to do to use the discord.Intent API is to configure them in the CLIENT scope in settings.py.

You have to declare any intent which you want to override False for. To do that, simply add them in the discord_intent_flags list in CLIENT as the example below.

Available intents:

* auto_moderation
* auto_moderation_configuration
* auto_moderation_execution
* bans
* dm_messages
* dm_reactions
* dm_typing
* emojis
* emojis_and_stickers
* guild_messages
* guild_reactions
* guild_scheduled_events
* guild_typing
* guilds
* integrations
* invites
* members
* message_content
* messages
* presences
* reactions
* typing
* value
* voice_states
* webhooks

A minimal configuration for a working Discord bot with a Pyttman app looks like this:

CLIENT = {
    "class": "pyttman.clients.community.discord.client.DiscordClient",
    "token": "DISCORD_TOKEN",
    "guild": "YOUR_DISCORD_GUILD_ID",
    "discord_intent_flags": {
        "message_content": True,     # You have to configure this to True, when creating a new project
        # Optional intent flags are added here.
    },
}

Detailed configuration

# settings.py

CLIENT = {
    "class": "pyttman.clients.community.discord.client.DiscordClient",
    "token": "your-token-here",
    "guild": 01234567890123456,
    "discord_intent_flags": {
        "dm_messages": True,
        "message_content": True,
    },

    # Optional fields
    "message_startswith": "!",
    # Only messages starting with '!' are considered by the Pyttman app.
    "message_endswith": "?"
    # Only messages ending with '?' are considered by the Pyttman app.
}