Coder Social home page Coder Social logo

pokitoki's Introduction

ChatGPT Telegram Bot

This is a Telegram chat bot built using the ChatGPT (GPT-3.5 or GPT-4) language model from OpenAI.

Notable features:

  • Both one-on-one and group chats.
  • Direct questions, mentions, follow-ups.
  • Access external links (articles, code, data).
  • Shortcuts (custom AI commands).
  • Custom chat-wide prompts.
  • Image generation.
  • On-the-fly configuration.

Read on for a detailed feature description or jump to setup.

Personal chats

The bot acts as your personal assistant:

Sample chat

To allow other users to use the bot, list them in the telegram.usernames config property.

The bot has a terrible memory, so don't expect it to remember any chat context by default. You can, however, reply with a follow-up question (Ctrl/Cmd + ↑). Alternatively, use a plus sign to follow up:

Follow-up by reply Follow-up by plus sign

Available commands:

  • /retry - retry answering the last question
  • /help - show help
  • /version - show bot info

To rephrase or add to the last question, simply edit it. The bot will then answer the updated question.

Groups

To get an answer from the bot in a group, mention it in a reply to a question, or ask a question directly:

Reply with mention Direct question

To make the bot reply to group members, list the group id in the telegram.chat_ids config property. Otherwise, the bot will ignore questions from group members unless they are listed in the telegram.usernames config property.

If you don't know the group id, run the /version bot command in a group to find it:

Chat information:
- id: -1001405001234
- title: My Favorite Group
- type: supergroup
...

External links

If you ask "vanilla" ChatGPT about external resources, it will either hallucinate or admit that it doesn't have access to remote content:

Q: What is the content of https://sqlime.org/employees.sql? Make no assumptions.

A: As an AI language model, I cannot access external URLs on the internet.

The bot solves the problem by fetching the remote content and feeding it to the model:

External links

Currently only supports text content (articles, code, data), not PDFs, images or audio.

Shortcuts

Use short commands to save time and ask the bot to do something specific with your questions. For example, ask it to proofread your writing with a !proofread command:

Shortcuts

There are several built-in shortcuts:

  • bugfix fixes your code.
  • proofread fixes your writing.
  • translate translates your text into English.
  • summarize gives a two paragraph summary of a text.

You can add your own shortcuts. See config.example.yml for details.

Chat-wide prompts

To set a custom prompt for the current chat, use the /prompt command:

/prompt You are an evil genius. Reply with an evil laugh.

To return to the default prompt, use /prompt reset.

The /prompt command in group chats is only available to admins - users listed in the telegram.admins property.

Image generation

Use the /imagine command to generate an image using the DALL-E 3 model from OpenAI:

Generated image

The default image size is 1024×1024 px. Other supported sizes are 1792×1024 and 1024×1792:

/imagine a lazy cat on a sunny day 1792×1024

Image generation is quite pricey. By default it's only enabled for users listed in telegram.usernames, not for group members. You can change this with the imagine.enabled config property.

Other useful features

The convenience of working with a bot is made up of small details. Here are some situations where it can save you time and effort.

Forwarding

Say you received a message from a colleague or read a post on a channel and want to ask a question. Simply forward the message to the bot and answer the clarifying question it asks:

Forwarding 1 Forwarding 2

Ask with file

To ask a question about a document, send it as a file and write the question in the caption. The bot will read the file contents and answer. Currently only supports text content (plain text, code, data), not PDFs, images or audio. Sending multiple files is also not supported.

Ask with file

Reply with attachment

Sometimes the AI's reply exceeds the maximum message length set by Telegram. In this case, the bot will not fail or spam you with messages. Instead, it will send the answer as an attached markdown file:

Reply with attachment

Edited question

To rephrase or add to the last question, edit it ( shortcut). The bot will notice this and respond to the clarified question.

Bot information

Use the /version command to print detailed information about the current chat, bot, and AI model:

Chat information:
- id: -1001405001234
- title: My Favorite Group
- type: supergroup

Bot information:
- id: 5930739038
- name: @pokitokibot
- version: 129
- usernames: 6 users
- admins: 1 users
- chat IDs: []
- access to messages: True

AI information:
- model: gpt-3.5-turbo
- history depth: 3
- imagine: True
- shortcuts: bugfix, proofread, summarize, translate

Configuration

Use the /config command to change almost any setting on the fly, without restarting the bot.

  • Add or remove users and chats allowed to interact with the bot (telegram.usernames and telegram.chat_ids).
  • Adjust the AI model (openai.model), prompt (openai.prompt) and params (openai.params).
  • Enable or disable image generation (imagine.enabled).
  • Add or change AI shortcuts (shortcuts).
  • Change any other config property.

To view a specific config property, put its name after /config:

/config telegram.usernames
/config openai.prompt
/config imagine.enabled

To change a specific config property, put its name and value after /config:

/config telegram.usernames ["alice", "bob", "cindy"]
/config openai.prompt "You are an evil AI bot"
/config imagine.enabled none

When working with list properties like telegram.usernames, you can add or remove individual items instead of redefining the whole list:

/config telegram.usernames +cindy
/config telegram.usernames -bob

The /config command is only available to admins - users listed in the telegram.admins property.

Message limits

Heated discussions with the bot in large groups can lead to high usage of the OpenAI API. To avoid spending your entire budget, set message limits for groups with the conversation.message_limit config property.

You can limit the number of messages from a user over a period of time. For example:

  • 10 messages per user per hour:
message_limit:
    count: 10
    period: hour
  • 1 message per user per minute:
message_limit:
    count: 1
    period: minute
  • 30 messages per user per day:
message_limit:
    count: 30
    period: day

Setup

  1. Get your OpenAI API key

  2. Get your Telegram bot token from @BotFather

  3. Clone the repo to the server:

git clone https://github.com/nalgeon/pokitoki.git
  1. Copy config.example.yml to config.yml and specify your tokens there. Add yourself to the telegram.usernames property, otherwise the bot will be available to everyone.

  2. Start the bot:

docker compose up --build --detach

To stop the bot:

docker compose stop

To update the bot to a new version:

docker compose stop
git pull
docker compose up --build --detach

For older Docker distributions, use docker-compose instead of docker compose.

Development setup

Prepare the environment:

python3 -m venv env
. env/bin/activate
pip install -r requirements.txt

Prepare the config and data directory:

cp config.example.yml config.yml
mkdir ./data

Set tokens and other settings in config.yml.

Run tests:

python -m unittest discover

Start the bot:

python -m bot.bot

Contributing

For new features and improvements, please first open an issue to discuss what you would like to change.

Be sure to add or update tests as appropriate.

Use Black for code formatting and Conventional Commits for commit messages.

Changelog

For feature history, see releases.

Credits

Originally based on chatgpt_telegram_bot, although the projects have diverged quite a bit.

pokitoki's People

Contributors

aib0t avatar heyslava avatar nalgeon avatar self-perfection avatar tandav avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pokitoki's Issues

Improvements

Hello. The command python -m bot.bot can be transformed into python -m bot. How to do this? Move the code from bot/bot.py to bot/__main__.py

python -m bot.bot

The bot works in groups and chats not included in the list /config telegram.chat_ids

Good afternoon. I have encountered the fact that the bot works in any group and answers questions of any user in private chats when two IDs are specified in the list of groups.
In the instructions to the bot I have not found a description of the correct configuration settings in terms of specifying chat_ids.
At the request /config telegram bot shows the following information:
{'token': 'mytoken', 'usernames': [], 'admins': ['1', '2'], 'chat_ids': ['10-character ID', '10-character ID']}
Please explain how to set the chat_ids so that the bot only works in the groups I want.

Failed to answer. Reason: httpx.ConnectTimeout

My prompt:

How to convert it into python requests?

curl --location --request POST 'http://172.22.1.70:5080/api/identity/connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=dep-soc-protect' \
--data-urlencode 'client_secret=password' \
--data-urlencode 'grant_type=client_credentials'

Response

Failed to answer. Reason: httpx.ConnectTimeout:

I tried it a lot

Logs

pokitoki    | 2023-04-27 07:06:13,074 INFO __main__ -> question id=2321, user=Vyacheslav_Kapitonov, n_chars=329
pokitoki    | 2023-04-27 07:06:16,097 ERROR __main__ Failed to answer. Reason: httpx.ConnectTimeout: 
pokitoki    | 2023-04-27 07:06:26,752 INFO __main__ -> question id=2323, user=Vyacheslav_Kapitonov, n_chars=329
pokitoki    | 2023-04-27 07:06:29,763 ERROR __main__ Failed to answer. Reason: httpx.ConnectTimeout: 
pokitoki    | 2023-04-27 07:06:57,076 INFO __main__ -> question id=2325, user=Vyacheslav_Kapitonov, n_chars=1
pokitoki    | 2023-04-27 07:06:59,345 INFO __main__ <- answer id=2325, user=Vyacheslav_Kapitonov, n_chars=1, len_history=0, took=2266ms
pokitoki    | 2023-04-27 07:07:02,764 INFO __main__ -> question id=2327, user=Vyacheslav_Kapitonov, n_chars=329
pokitoki    | 2023-04-27 07:07:05,774 ERROR __main__ Failed to answer. Reason: httpx.ConnectTimeout: 
pokitoki    | 2023-04-27 07:07:21,001 INFO __main__ -> question id=2327, user=Vyacheslav_Kapitonov, n_chars=329
pokitoki    | 2023-04-27 07:07:24,008 ERROR __main__ Failed to answer. Reason: httpx.ConnectTimeout: 
pokitoki    | 2023-04-27 07:07:30,719 INFO __main__ -> question id=2330, user=Vyacheslav_Kapitonov, n_chars=1
pokitoki    | 2023-04-27 07:07:32,362 INFO __main__ <- answer id=2330, user=Vyacheslav_Kapitonov, n_chars=1, len_history=0, took=1641ms
pokitoki    | 2023-04-27 07:09:29,612 INFO __main__ -> question id=2332, user=Vyacheslav_Kapitonov, n_chars=329
pokitoki    | 2023-04-27 07:09:32,622 ERROR __main__ Failed to answer. Reason: httpx.ConnectTimeout: 
pokitoki    | 2023-04-27 07:09:47,749 INFO __main__ -> question id=2334, user=Vyacheslav_Kapitonov, n_chars=327
pokitoki    | 2023-04-27 07:09:50,761 ERROR __main__ Failed to answer. Reason: httpx.ConnectTimeout: 
pokitoki    | 2023-04-27 07:10:52,042 INFO __main__ -> question id=2334, user=Vyacheslav_Kapitonov, n_chars=323
pokitoki    | 2023-04-27 07:10:55,054 ERROR __main__ Failed to answer. Reason: httpx.ConnectTimeout: 
pokitoki    | 2023-04-27 07:10:57,707 INFO __main__ -> question id=2337, user=Vyacheslav_Kapitonov, n_chars=327
pokitoki    | 2023-04-27 07:11:00,719 ERROR __main__ Failed to answer. Reason: httpx.ConnectTimeout: 
pokitoki    | 2023-04-27 07:12:05,088 INFO __main__ -> question id=2339, user=Vyacheslav_Kapitonov, n_chars=327
pokitoki    | 2023-04-27 07:12:08,099 ERROR __main__ Failed to answer. Reason: httpx.ConnectTimeout: 
Chat information:
- id: 171040690
- title: None
- type: private

Bot information:
- id: 6248584602
- name: @kapitonov_gpt_bot
- version: 165
- usernames: 2 users
- admins: 1 users
- chat IDs: [-1001906330868]
- access to messages: True

AI information:
- model: gpt-3.5-turbo
- history depth: 10
- imagine: none
- shortcuts: bf, eng, pr, sum, tr

but the bot works in general

Bot does not respond to group users not included in the userlist

Dear Developer.
I have filled in the config telegram section as follows:
/config telegram
{'token': 'my_token', 'usernames': ['a', 'b'], 'admins': ['a', 'b'], 'chat_ids': [1, 2]}

With this setting, the bot does not answer questions from all group members, only from users in the list (same as admins list).
Both groups are closed (not public).
To make the bot respond to all members of a group I have to clear the list of users, but then the bot starts responding to any telegram user outside of the groups set in the config.
What am I doing wrong?
I need my bot works same as @Marika_tgbot))

Access external URLs

When you ask ChatGPT about external resources, it either hallucinates:

Q: Explain https://sqlime.org/employees.sql?

A: The employees table appears to have columns such as employee_id, first_name, last_name, email, phone_number, hire_date, job_id, salary, commission_pct, manager_id, and department_id.

Or acknowledges that it doesn't have access to remote URLs:

Q: What is the content of https://sqlime.org/employees.sql? Make no assumptions.

A: As an AI language model, I cannot access external URLs on the internet.

We can probably fix this by fetching the external content and feeding it to the model.

TypeError: 'type' object is not subscriptable

(env) projektxamelion@xamelion-server:~/pokitoki$ python3 -m bot.bot
Traceback (most recent call last):
File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/home/projektxamelion/pokitoki/bot/bot.py", line 16, in
from bot import askers
File "/home/projektxamelion/pokitoki/bot/askers.py", line 15, in
from bot import ai
File "/home/projektxamelion/pokitoki/bot/ai/init.py", line 1, in
from . import chatgpt
File "/home/projektxamelion/pokitoki/bot/ai/chatgpt.py", line 6, in
from bot.config import config
File "/home/projektxamelion/pokitoki/bot/config.py", line 143, in
class ConfigEditor:
File "/home/projektxamelion/pokitoki/bot/config.py", line 204, in ConfigEditor
def set_value(self, property: str, value: str) -> tuple[bool, bool]:
TypeError: 'type' object is not subscriptable

//////why it happens?

"Message is too long"

Hi, I've just followed every step of the Setup paragraph and the bot says it's too long literally for every message except commands.
Any ideas why this happens? Please help...
IMG_20240126_192658_883

Message token count exceeds the maximum allowed token count

If the text of the link is too long, the bot gives the typical answer: "Failed to answer. Reason: openai.error.InvalidRequestError: This model's maximum context length is 4097 tokens. However, your messages resulted in 5651 tokens. Please reduce the length of the messages."
Is it possible to automatically split the text into several parts, no longer than 4097 tokens for English and no more than 3000 tokens for Russian?

Add new message to old context

Hello!

I'm not sure if it's a bug, but I believe it's an area for improvement.

What is the issue?

Imagine you asked a question and then followed up with another question. By mistake, you forgot to include a "+" at the beginning of the second message. Later, you noticed the error and edited your last message to include the "+". Unfortunately, the context was lost.

Default:

Слава Слава, [26 Apr 2023 09:30:11]
Remember. I am 80 years old

Капитонов GPT/pokitoki, [26 Apr 2023 09:30:14]
Of course, I will keep that in mind and try my best to explain things clearly and concisely. If you have any trouble understanding my responses, please let me know and I will do my best to clarify.

Слава Слава, [26 Apr 2023 09:30:24]
+ add 10 years

Капитонов GPT/pokitoki, [26 Apr 2023 09:30:27]
To add 10 years to your current age, you would simply add 10 to your current age. For example, if you are currently 80 years old, adding 10 years would make you 90 years old.

Missed +

Слава Слава, [26 Apr 2023 09:30:40]
Remember. I am 80 years old

Капитонов GPT/pokitoki, [26 Apr 2023 09:30:42]
Of course, I will keep that in mind and try to explain things in a clear and concise manner. Please feel free to let me know if you need any further clarification or assistance.

Слава Слава, [26 Apr 2023 09:30:50]
add 10 years

Капитонов GPT/pokitoki, [26 Apr 2023 09:30:57]
Adding 10 years can be done easily using programming. Here are some examples in different programming languages:

Python:


import datetime

current_year = datetime.datetime.now().year
new_year = current_year + 10

print(new_year)


JavaScript:


var currentYear = new Date().getFullYear();
var newYear = currentYear + 10;

console.log(newYear);


Java:


import java.util.Calendar;

Calendar now = Calendar.getInstance();
int currentYear = now.get(Calendar.YEAR);
int newYear = currentYear + 10;

System.out.println(newYear);


Each of these examples will output the current year plus 10.

Edited message and added +

Слава Слава, [26 Apr 2023 09:30:40]
Remember. I am 80 years old

Капитонов GPT/pokitoki, [26 Apr 2023 09:30:42]
Of course, I will keep that in mind and try to explain things in a clear and concise manner. Please feel free to let me know if you need any further clarification or assistance.

Слава Слава, [26 Apr 2023 09:30:50]
+ add 10 years

Капитонов GPT/pokitoki, [26 Apr 2023 09:30:57]
# First answer
...

Капитонов GPT/pokitoki, [26 Apr 2023 09:34:34]
Adding 10 years to what exactly? Could you please provide more context or information so that I can give a more accurate response?

Image generation

Create an image with the /imagine command, e.g:

/imagine lazy cat on a sunny day

Use the DALL-E 2 model from OpenAI.

The model: `gpt-4` does not exist

In the configuration, I specified GPT-4, but the bot returned the following response:
Failed to answer. Reason: openai.error.InvalidRequestError: The model: gpt-4 does not exist

DALL-E 3?

could you add support for dall-e-3?

Requests to openai are blocking

This screenshot requires an explanation: we can see that there is a two-second time difference between my two messages, but I received my response on /help after the response on the "ping" message. Which is strange.

There are cases where it poses a real problem. A few weeks ago, there was an issue with the API where the service returned an error 502.

Failed to answer. Reason: HTTP code 502 from API (<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx</center>
</body>
</html>
)

It took a very long time to respond, and I couldn't realize which side the problem is on. I sent the /help command but It didn't work too.

Incorrect parse mode

HI!

await message.reply_text(answer, parse_mode=ParseMode.HTML)

Why are you using HTML parse mode here. It seems to me, even from your readme that ChatGPT answers in markdown mode.

I think the only stable solution is to rudely escape everything except triple ```. It wouldn't be perfect, but It will be easier to work with big blocks of code. Related Telegram API documentation

[upd] or replace ``` with code tag and leave parse mode as it is

PermissionDeniedError: Error code: 403

When communicating with the bot, the following message appears:
openai.PermissionDeniedError: Error code: 403 - {'error': {'code': 'unsupported_country_region_territory', 'message': 'Country, region, or territory not supported', 'param': None, 'type': 'request_forbidden'}}

update openai>=1.3.0 to support OPENAI_BASE_URL environment variable

Hi, thank you for great project. It would be nice to update openai to >=1.3.0. It support base_url setting via argument to client or via OPENAI_BASE_URL environment variable.

This setting allows to use openai api proxy and access openai api if it's blocked. For example, someone can set:

os.environ['OPENAI_BASE_URL'] = 'https://openai-proxy.company.com/v1'

And use it if default api url https://api.openai.com/v1 is blocked, or giving some cloudflare errors.

Ideas for usage in chat

Hi!

I have a few small ideas for this bot, so I decided to combine them into one issue.

  1. Currently, when I use the bot in a chat, each participant has their own context. This means that if person-1 asks a question, person-2 cannot ask a follow-up question. My idea is to have a shared context for the entire chat, rather than for each person individually.

  2. Sometimes, I come across a long text in another channel and I want to ask the bot to summarize it. My expected behavior is to forward the message to the bot with my comments, such as "Make summary into 2 sentences". However, this doesn't work because the bot receives my comment as a separate message from the forwarded text. I tried to solve this on my own, but I don't know how to join these messages into one. Telegram-bot treats them as two separate messages.

  3. I think that the MAX_HISTORY_DEPTH variable should be included in the config.yml file, and I would also like to add this information to the /version command.

Admin panel

Hi!

Is is interesting for you if I add an admin's panel?

It will be for new users. Currently, you add them manually in config.

How I see it:

Add /users command. It will be available only for admin

/users add @some_user
/users drop @some_user
/users list

gpt-4o support

Please add support for gpt-4o (for the new model the bot does not behave correctly)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.