---
title: Service Integrations
description: Integration with external services - Telegram in Django-CFG
sidebar_label: Service Integrations
sidebar_position: 9
---

# Service Integrations

The Django-CFG sample project demonstrates integration with external services. This guide covers setup and usage of Telegram (notifications).

## Service Overview

The sample project integrates:
- **Telegram** - Real-time notifications and bot commands

## Telegram Integration

### Configuration

Configure Telegram in `api/config.py`:

```python
from django_cfg import TelegramConfig

telegram: TelegramConfig = TelegramConfig(
    bot_token=env.telegram.bot_token,
    chat_id=env.telegram.chat_id,
    enabled=env.is_prod
)
```

Environment configuration:

```yaml
# api/environment/config.prod.yaml
telegram:
  bot_token: "<from-yaml-config>"
  chat_id: "@your_channel"  # or numeric chat ID
```

### Sending Messages

Send messages to Telegram:

```python
from django_cfg import DjangoTelegram

telegram = DjangoTelegram()

# Send simple message
def send_alert(message):
    """Send alert to Telegram channel."""
    telegram.send_message(
        chat_id="@system_alerts",
        text=message
    )

# Send formatted message
def send_system_alert(message, level="info"):
    """Send formatted system alert."""
    emoji = {"info": "ℹ️", "warning": "⚠️", "error": "🚨"}

    telegram.send_message(
        chat_id="@system_alerts",
        text=f"{emoji[level]} *System Alert*\n\n{message}",
        parse_mode="Markdown"
    )
```

### Order Notifications

Send order notifications via Telegram:

```python
from django_cfg import DjangoTelegram

telegram = DjangoTelegram()

# Notify new order
def notify_new_order(order):
    """Send new order notification."""
    message = f"""
🛒 *New Order Received*

Order ID: `{order.id}`
Customer: {order.user.get_full_name()}
Total: ${order.total}
Items: {order.items.count()}

[View Order](https://admin.myapp.com/admin/shop/order/{order.id}/)
    """

    telegram.send_message(
        chat_id="@order_notifications",
        text=message,
        parse_mode="Markdown"
    )

# Notify order status change
def notify_order_status(order, old_status, new_status):
    """Notify when order status changes."""
    message = f"""
📦 *Order Status Updated*

Order ID: `{order.id}`
Status: {old_status} → *{new_status}*
Customer: {order.user.email}

[View Order](https://admin.myapp.com/admin/shop/order/{order.id}/)
    """

    telegram.send_message(
        chat_id="@order_notifications",
        text=message,
        parse_mode="Markdown"
    )
```

### Bot Commands

Create interactive bot commands:

```python
from django_cfg import DjangoTelegram

telegram = DjangoTelegram()

# Status command
@telegram.command("status")
def handle_status_command(update, context):
    """Handle /status command."""
    from django.contrib.auth import get_user_model

    User = get_user_model()

    status = f"""
🏥 *System Status*

Database: ✅ Connected
Cache: ✅ Active
Workers: ✅ Running

👥 Users: {User.objects.count()}
📊 Load: Low
    """

    return status

# Stats command
@telegram.command("stats")
def handle_stats_command(update, context):
    """Handle /stats command."""
    from django.contrib.auth import get_user_model
    from apps.shop.models import Order
    from django.db.models import Sum

    User = get_user_model()

    stats = f"""
📊 *Quick Stats*

👥 Users: {User.objects.count()}
🛒 Orders: {Order.objects.count()}
💰 Revenue: ${Order.objects.aggregate(Sum('total'))['total__sum'] or 0}
    """

    return stats

# Orders command
@telegram.command("orders")
def handle_orders_command(update, context):
    """Handle /orders command - show recent orders."""
    from apps.shop.models import Order

    recent_orders = Order.objects.order_by('-created_at')[:5]

    message = "📦 *Recent Orders*\n\n"
    for order in recent_orders:
        message += f"#{order.id} - ${order.total} - {order.status}\n"

    return message
```

## Async Service Usage

### Background Email Sending

Send emails asynchronously:

```python
from arq import ArqRedis
from django_cfg import DjangoEmailService

async def send_welcome_email_async(ctx, user_id):
    """Send welcome email in background."""
    from django.contrib.auth import get_user_model

    User = get_user_model()
    user = User.objects.get(id=user_id)

    email = DjangoEmailService()
    email.send_template(
        template_name="emails/welcome.html",
        context={"user_name": user.get_full_name()},
        recipient_list=[user.email],
        subject="Welcome!"
    )

# Usage
async def handle_user_registration(user):
    """Handle new user registration."""
    redis = await ArqRedis.create()
    await redis.enqueue_job('send_welcome_email_async', user.id)
```

See [Background Tasks](/docs/features/modules/django-rq/overview) for async processing details.

## Error Handling

### Graceful Degradation

Handle service failures gracefully:

```python
from django_cfg import DjangoTelegram
import logging

logger = logging.getLogger(__name__)

def notify_error(error_message):
    """Send error notification with fallback."""
    try:
        # Try Telegram first
        telegram = DjangoTelegram()
        telegram.send_message(
            chat_id="@system_alerts",
            text=f"🚨 Error: {error_message}"
        )
    except Exception as e:
        # Fallback to email
        logger.warning(f"Telegram notification failed: {e}")
        try:
            email = DjangoEmailService()
            email.send_simple(
                subject="System Error",
                message=error_message,
                recipient_list=["admin@myapp.com"]
            )
        except Exception as e:
            # Log as last resort
            logger.error(f"All notifications failed: {e}")
```

### Retry Logic

Implement retry logic for transient failures:

```python
from tenacity import retry, stop_after_attempt, wait_exponential

@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=4, max=10)
)
def send_critical_email(recipient, subject, message):
    """Send email with automatic retries."""
    email = DjangoEmailService()
    return email.send_simple(
        subject=subject,
        message=message,
        recipient_list=[recipient]
    )
```

## Best Practices

### 1. Async for Non-Critical Operations

```python
# ✅ Good: Async notification
notify_user.send(user.id)  # Non-blocking

# ❌ Bad: Synchronous notification
send_notification(user.id)  # Blocks request
```

### 2. Handle Service Failures

```python
# ✅ Good: Graceful error handling
try:
    telegram.send_message(chat_id, message)
except Exception as e:
    logger.warning(f"Telegram failed: {e}")
    # Continue without failing

# ❌ Bad: Unhandled failures
telegram.send_message(chat_id, message)  # Crashes on error
```

## Related Topics

- [Configuration](./configuration) - Service configuration setup
- [Background Tasks](/docs/features/modules/django-rq/overview) - Async service usage
- [Authentication](./authentication) - OTP authentication

External service integrations enhance application capabilities!
