Finb / Bark

Bark is an iOS App which allows you to push custom notifications to your iPhone

Home Page:https://bark.day.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Python script for msg sender with AES-256-CBC

cfbsks opened this issue · comments

commented
"""
Bark Notification Script
------------------------

This script allows you to send encrypted notifications using the Bark API.

Usage:
1. Set up your configuration:
   - Set `DEVICE_KEY` to your Bark device key.
   - Set `encryption_key` to your chosen AES key. (Ensure it's secure and kept private.)

2. The `send_notification` function can be used to send notifications. It accepts the following keyword arguments:
   - `title`: The title of the notification.
   - `body`: The body content of the notification.
   - `level`: The urgency level of the notification.
   - `autoCopy`: Whether to automatically copy content.
   - `copy`: The copied content.
   - `sound`: The sound of the notification.
   - `icon`: The icon URL of the notification.
   - `group`: The group of the notification.
   - `isArchive`: Whether the notification is archived.
   - `url`: The URL to open upon clicking the notification.

3. By default, all parameters have `None` value. If you want to set any default values, update the respective constants at the top of the script.

4. Use the `main` function to test or send out notifications as required.

Example:
    send_notification(body='This is a custom message.')
    send_notification(body='Another message', sound='bell', group='new_group')

Note:
Always remember not to hard-code sensitive information like `DEVICE_KEY` and `encryption_key` directly in the script. Consider safer methods like environment variables or secure config files.

"""

import base64
import json
import logging
import random

import requests
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import algorithms, modes, Cipher
from cryptography.hazmat.primitives.ciphers.algorithms import AES

TIMEOUT_REQUEST_SEC = 10
MAX_RETRIES = 3
LOG_LEVEL = logging.WARNING

API_BASE = 'https://api.day.app'
DEVICE_KEY = "this is your device_key"

# Encryption key and IV (Initialization Vector)
encryption_key = '12345678901234567890123456789012'

# Set Default Values
TITLE = None
BODY = None
LEVEL = None
GROUP = None
AUTOCOPY = None
COPY = None
SOUND = None
ICON = None
URL = None
ISARCHIVE = None

# Set up logging
logging.basicConfig(filename='Bark.log', level=LOG_LEVEL,
                    format='%(asctime)s - %(levelname)s - %(message)s')


def encrypt_payload(payload: bytes, aes_key: bytes, aes_iv: bytes):
    """
    Encrypt the given payload using AES-256-CBC with PKCS7 padding.
    """

    # Add padding to the payload
    padder = padding.PKCS7(AES.block_size).padder()
    padded_data = padder.update(payload) + padder.finalize()

    # Create the cipher
    cipher = Cipher(algorithms.AES(aes_key), modes.CBC(aes_iv), backend=default_backend())

    # Encrypt the padded data
    encryptor = cipher.encryptor()
    encrypted = encryptor.update(padded_data) + encryptor.finalize()

    # Return the Base64 encoded ciphertext
    return base64.b64encode(encrypted).decode()


def send_notification(**kwargs):
    defaults = {
        'title': TITLE,
        'body': BODY,
        'level': LEVEL,
        'autoCopy': AUTOCOPY,
        'copy': COPY,
        'sound': SOUND,
        'icon': ICON,
        'group': GROUP,
        'isArchive': ISARCHIVE,
        'url': URL
    }

    for key, value in defaults.items():
        defaults[key] = kwargs.get(key, value)
    # Remove keys with empty string values
    cleaned_data = {k: v for k, v in defaults.items() if v}

    for _ in range(MAX_RETRIES):
        try:
            url = API_BASE + "/" + DEVICE_KEY
            headers = {'Content-Type': 'application/x-www-form-urlencoded'}

            json_data = json.dumps(cleaned_data)

            encryption_iv = bytes(random.randint(32, 126) for _ in range(16))
            encrypted_payload = encrypt_payload(json_data.encode(), encryption_key.encode(), encryption_iv)

            payload = {
                'ciphertext': encrypted_payload,
                'iv': encryption_iv.decode()
            }
            response = requests.request("GET", url, headers=headers, data=payload, timeout=TIMEOUT_REQUEST_SEC)

            if response.status_code == 200:
                logging.info(f"Sending notification. Response: {response.text}")
                return
            else:
                logging.warning(
                    f"Retrying notification. Status code: {response.status_code}, Response: {response.text}")
        except requests.RequestException as e:
            logging.warning(f"Retrying due to requests exception: {e}")
        except Exception as e:
            logging.error(f"Error sending notification: {e}")

    logging.error(f"Failed to send notification after {MAX_RETRIES} attempts. Content: {cleaned_data.get('body', '')}")


def main():
    send_notification(body='This is a custom message.')
    send_notification(body='Another message', sound='bell', group='new_group')


if __name__ == '__main__':
    main()