Skip to content

Commit

Permalink
Merge pull request #3 from Delitel-WEB/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Delitel-WEB authored Sep 20, 2023
2 parents 92a304c + 8ba246a commit b4cc3d0
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 4 deletions.
85 changes: 85 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# VK-TG-SYNC | Синхронизация чатов между Вконтакте и Телеграмом

> Этот скрипт предназначен для пользователей, которые уже давно сделали Телеграм своим основным мессенджером, но у них все еще есть чаты во Вконтакте, в которых им приходится участвовать. Скрипт позволяет перенести эти чаты из Вконтакте в Телеграм и упростить процесс коммуникации.
⚠️ **Примечание:** На данный момент скрипт находится в недоделанном виде и может иметь ограничения и проблемы. Пожалуйста, учитывайте это при его использовании.

![Поддерживаемые версии Python](https://img.shields.io/badge/python-3.7+-blue.svg)

## 🚀 Установка

1. Склонируйте репозиторий GitHub:

```shell
git clone https://github.com/Delitel-WEB/vk-tg-sync.git
```

2. Перейдите в директорию проекта:

```shell
cd vk-tg-sync
```

3. Установите необходимые пакеты Python из файла `req.txt`:
```shell
pip install -r req.txt
```

## ⚙️ Настройка

Для настройки скрипта создайте файл `settings.sh` для Linux.

- Для Linux: `settings.sh`
```shell
export tgBotToken=""
export vkBotToken=""
export dbPassword=""
```

Выполните следующую команду, чтобы создать таблицы в базе данных:

```shell
alembic upgrade head
```

⚠️ Перед выполнением этой команды убедитесь, что у вас установлена база данных MySQL и создана пустая таблица `vk_to_tg`.

## ▶️ Запуск бота

⚠️ Перед запуском убедитесь, что вы установили значения переменных в файле `settings.sh`.

Перед запуском выполните команду:

```shell
source settings.sh
```

И запустите скрипт:

```shell
python main.py
```

## Что реализовано на данный момент

> **Синхронизация указана в виде мессенджер ➔ мессенджер. То есть если галочка стоит у ВКонтакте, то сделана синхронизация VK ➔ Telegram и наоборот. Если галочки стоят сразу на двух мессенджерах, значит, синхронизация двусторонняя.**

| Виды синхронизации | Telegram | VKontakte |
| ------------------------ | -------- | --------- |
| **Сообщения** | | |
| Текстовые сообщения |||
| Голосовые сообщения |||
| Стикеры |||
| Пересланные сообщения |||
| Документы |||
| Удаление сообщений |||
| Редактирование сообщений |||
| **Медиа** | | |
| Фото |||
| Видео |||
| Геолокация |||
| Гифки |||
| **Действия с чатами** | | |
| Изменение Фото |||
| Изменение Названия Чата |||
4 changes: 3 additions & 1 deletion req.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
vkbottle==4.3.12
aiogram==2.25.1
cryptography==41.0.4
SQLAlchemy==2.0.20
alembic==1.12.0
aiomysql==0.2.0
PyMySQL==1.1.0
black==23.9.1
black==23.9.1
aiohttp==3.8.5
31 changes: 28 additions & 3 deletions sync/tg/handlers/bind_chats.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from aiogram.utils.exceptions import ChatNotFound
from ...db import Sessions
from ...db.models import Conversations
from sqlalchemy import select
from sqlalchemy import select, or_
from ..utils import update_chat_info


@dp.message_handler(commands=["bind_chat"], state="*")
Expand Down Expand Up @@ -49,7 +50,7 @@ async def get_vk_id(message: Message, state: FSMContext):
if data["chat_type"] == "DM":
chat = await vk.api.users.get(message.text)
if chat:
data["vk_chat_id"] = 2000000000 + int(message.text)
data["vk_chat_id"] = message.text
await state.set_data(data)

await BindChats.verify_choice_vk.set()
Expand Down Expand Up @@ -137,7 +138,10 @@ async def get_tg_id(message: Message, state: FSMContext):
data = await state.get_data()
chat_exists = await session.scalar(
select(Conversations).where(
Conversations.vk_id == data["vk_chat_id"]
or_(
Conversations.vk_id == data["vk_chat_id"],
Conversations.tg_id == message.text,
)
)
)
if not chat_exists:
Expand All @@ -149,6 +153,27 @@ async def get_tg_id(message: Message, state: FSMContext):
await session.commit()

await message.answer("Отлично!\n" "Чаты успешно связаны!")
await state.finish()

if data["chat_type"] == "GR":
chat = await vk.api.messages.get_conversations_by_id(
data["vk_chat_id"]
)
await update_chat_info(
message.text,
chat.items[0].chat_settings.title,
preview=chat.items[0].chat_settings.photo.photo_200
if chat.items[0].chat_settings.photo
else None,
)
else:
chat = await vk.api.users.get(
data["vk_chat_id"], fields=["photo_max_orig"]
)
full_name = f"{chat[0].first_name} {chat[0].last_name}"
await update_chat_info(
message.text, full_name, preview=chat[0].photo_max_orig
)
else:
await message.answer("Чат уже к чему-то подключен!")

Expand Down
2 changes: 2 additions & 0 deletions sync/tg/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .chats import update_chat_info
from .photos import get_photo_from_url
15 changes: 15 additions & 0 deletions sync/tg/utils/chats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from ..core import bot
from .photos import get_photo_from_url


async def update_chat_info(chat_id: int, title: str, preview: str):
"""
Обновление информации о группе.
Название, Фото
"""

if preview:
photo = await get_photo_from_url(preview)
await bot.set_chat_photo(chat_id, photo)

await bot.set_chat_title(chat_id, title)
15 changes: 15 additions & 0 deletions sync/tg/utils/photos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import aiohttp
from io import BytesIO


async def get_photo_from_url(photo_url):
try:
async with aiohttp.ClientSession() as session:
async with session.get(photo_url) as response:
if response.status == 200:
photo_bytes = await response.read()
return BytesIO(photo_bytes)
else:
return None
except Exception as e:
return None
1 change: 1 addition & 0 deletions sync/vk/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .core import bot
from . import handlers


def start_vk():
Expand Down
1 change: 1 addition & 0 deletions sync/vk/handlers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import messages
24 changes: 24 additions & 0 deletions sync/vk/handlers/messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from ..core import bot
from vkbottle.user import Message
from ...db import Sessions
from ...db.models import Conversations
from sqlalchemy import select
from ...tg.core import bot as tg
from ..utils import create_vk_link


@bot.on.message()
async def on_message(message: Message):
async with Sessions() as session:
bundle = await session.scalar(
select(Conversations).where(Conversations.vk_id == message.peer_id)
)
if bundle:
users_info = await bot.api.users.get(message.from_id)
await tg.send_message(
bundle.tg_id,
f"<a href='{create_vk_link(message.from_id)}'>{users_info[0].first_name} {users_info[0].last_name}</a>\n"
+ "_" * 10
+ f"\n{message.text}",
parse_mode="html",
)
1 change: 1 addition & 0 deletions sync/vk/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .links import create_vk_link
3 changes: 3 additions & 0 deletions sync/vk/utils/links.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def create_vk_link(id: int):
"""Создание ссылки на профиль в вк из id"""
return f"https://vk.com/id{id}"

0 comments on commit b4cc3d0

Please sign in to comment.