wa_gc_api / app.py
DmitrMakeev's picture
Update app.py
1d05f9c verified
raw
history blame
No virus
13.3 kB
from flask import Flask, request, render_template_string, send_from_directory, jsonify
from flask import render_template
import sqlite3
import os
import unittest
from whatsapp_api_webhook_server_python.webhooksHandler import startServer
app = Flask(__name__, template_folder="./")
app.config['DEBUG'] = True
UPLOAD_FOLDER = 'static'
IMAGE_FILENAME = 'latest_image.jpg'
# Создание директории, если она не существует
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
# Создание базы данных и таблицы
def init_db():
try:
conn = sqlite3.connect('data.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS contacts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
phone TEXT NOT NULL,
email TEXT NOT NULL
)
''')
conn.commit()
conn.close()
except Exception as e:
print(f"Error initializing database: {e}")
# Вызов функции для инициализации базы данных
init_db()
@app.route('/settings', methods=['GET'])
def settings():
return render_template('settings.html')
@app.route('/online', methods=['GET'])
def onli():
return render_template('online.html')
@app.route('/ver', methods=['GET'])
def veref():
return render_template('ver.html')
@app.route('/se_mes', methods=['GET'])
def se_mes():
return render_template('se_mes.html')
@app.route('/se_mes_im', methods=['GET'])
def se_mes_im():
return render_template('se_mes_im.html')
@app.route('/online', methods=['GET'])
def online():
return render_template('online.html')
@app.route('/upload', methods=['POST'])
def upload_file():
if 'photo' not in request.files:
return jsonify({'error': 'No file part'}), 400
file = request.files['photo']
if file.filename == '':
return jsonify({'error': 'No selected file'}), 400
save_path = os.path.join(UPLOAD_FOLDER, IMAGE_FILENAME)
file.save(save_path)
return jsonify({'message': 'File uploaded successfully', 'file_url': f'/image', 'file_name': file.filename}), 200
@app.route('/image', methods=['GET'])
def get_image():
return send_from_directory(UPLOAD_FOLDER, IMAGE_FILENAME)
@app.route('/se_mes_im2')
def index():
html = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Send Messages</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f0f0f0;
margin: 0;
padding: 0;
}
h1 {
background-color: #4CAF50;
color: white;
padding: 20px;
margin: 0;
border-bottom: 2px solid #388E3C;
}
.input-row {
display: flex;
justify-content: center;
gap: 10px;
margin-top: 20px;
}
.input-row input, .input-row textarea {
padding: 10px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 5px;
}
#messageInput {
width: 80%;
margin-top: 20px;
min-height: 100px;
}
#progressBarContainer {
width: 80%;
margin: 20px auto;
}
#progressBar {
width: 100%;
background-color: #ddd;
}
#progress {
width: 0%;
height: 30px;
background-color: #4CAF50;
text-align: center;
line-height: 30px;
color: white;
}
#sendButton {
color: white;
background-color: #4CAF50;
border: none;
cursor: pointer;
padding: 10px 20px;
font-size: 16px;
border-radius: 5px;
margin-top: 20px;
}
#sendButton:hover {
background-color: #388E3C;
}
</style>
</head>
<body>
<h1>Отправка сообщения(текст)</h1>
<div class="input-row">
<input type="text" id="apiKeyInput" placeholder="Введите API ключ">
<input type="number" id="minDelayInput" placeholder="Min Delay (ms)" value="500">
<input type="number" id="maxDelayInput" placeholder="Max Delay (ms)" value="1000">
<label>
Показывать превью:
<input type="checkbox" id="linkPreviewCheckbox" checked>
</label>
</div>
<textarea id="messageInput" placeholder="Введите текст сообщения, превью ссылки отображается в зависимости от настроек."></textarea>
<div id="progressBarContainer">
<div id="progressBar">
<div id="progress">0%</</div>
</div>
</div>
<input type="file" id="fileInput" accept=".txt">
<button id="sendButton">Запустить рассылку</button>
<h1>Upload Image</h1>
<form id="uploadForm" enctype="multipart/form-data" method="post" action="/upload">
<input type="file" name="photo" id="photoInput">
<button type="submit">Upload Image</button>
</form>
<div id="uploadMessage"></div>
<h1>Uploaded Image</h1>
<img id="cameraImage" src="" alt="No image uploaded" style="width:100%;">
<script>
document.getElementById('uploadForm').addEventListener('submit', function(event) {
event.preventDefault();
var formData = new FormData(this);
fetch('/upload', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.error) {
document.getElementById('uploadMessage').innerText = data.error;
} else {
document.getElementById('uploadMessage').innerText = data.message;
document.getElementById('cameraImage').src = data.file_url + '?' + new Date().getTime();
document.getElementById('uploadedFileName').innerText = data.file_name;
}
})
.catch(error => {
document.getElementById('uploadMessage').innerText = 'Error: ' + error.message;
});
});
document.getElementById('sendButton').addEventListener('click', function() {
const apiKey = document.getElementById('apiKeyInput').value;
const message = document.getElementById('messageInput').value;
const minDelay = parseInt(document.getElementById('minDelayInput').value) || 500;
const maxDelay = parseInt(document.getElementById('maxDelayInput').value) || 10000;
const linkPreview = document.getElementById('linkPreviewCheckbox').checked;
if (!apiKey) {
alert('Please enter your API key.');
return;
}
if (!message) {
alert('Please enter a message.');
return;
}
if (minDelay >= maxDelay) {
alert('Min delay must be less than max delay.');
return;
}
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
if (!file) {
alert('Please select a file.');
return;
}
const reader = new FileReader();
reader.onload = function(event) {
const text = event.target.result;
const phones = text.split('\n').map(phone => phone.trim()).filter(phone => phone);
sendMessages(phones, apiKey, message, minDelay, maxDelay, linkPreview);
};
reader.readAsText(file);
});
async function sendMessages(phones, apiKey, message, minDelay, maxDelay, linkPreview) {
const totalPhones = phones.length;
const progressBar = document.getElementById('progress');
for (let i = 0; i < totalPhones; i++) {
const phone = phones[i];
try {
const response = await fetch(`https://api.green-api.com/waInstance1101952913/sendMessage/${apiKey}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
chatId: `${phone}@c.us`,
message: message,
linkPreview: linkPreview
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log(`Message sent to ${phone}:`, data);
} catch (error) {
console.error(`Error sending message to ${phone}:`, error);
}
const progress = ((i + 1) / totalPhones) * 100;
progressBar.style.width = `${progress}%`;
progressBar.textContent = `${progress.toFixed(2)}%`;
if (i < totalPhones - 1) {
const randomDelay = Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
await new Promise(resolve => setTimeout(resolve, randomDelay));
}
}
}
</script>
</body>
</html>
'''
return render_template_string(html)
# Маршрут для обработки GET-запроса
@app.route('/add_contact', methods=['GET'])
def add_contact():
try:
name = request.args.get('name')
phone = request.args.get('phone')
email = request.args.get('email')
if not name or not phone or not email:
return "Parameters 'name', 'phone', and 'email' are required.", 400
conn = sqlite3.connect('data.db')
cursor = conn.cursor()
cursor.execute('INSERT INTO contacts (name, phone, email) VALUES (?, ?, ?)', (name, phone, email))
conn.commit()
conn.close()
return f"Contact added: {name} - {phone} - {email}", 200
except Exception as e:
print(f"Error adding contact: {e}")
return "Internal Server Error", 500
# Маршрут для отображения таблицы контактов
@app.route('/contacts')
def show_contacts():
try:
conn = sqlite3.connect('data.db')
cursor = conn.cursor()
cursor.execute('SELECT name, phone, email FROM contacts')
contacts = cursor.fetchall()
conn.close()
# HTML-шаблон для отображения таблицы
html = '''
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Contacts</title>
<style>
table {
width: 70%;
border-collapse: collapse;
}
th, td {
border: 1px solid black;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
</style>
</head>
<body>
<h1>Contacts</h1>
<table>
<tr>
<th>Name</th>
<th>Phone</th>
<th>Email</th>
</tr>
{% for contact in contacts %}
<tr>
<td>{{ contact[0] }}</td>
<td>{{ contact[1] }}</td>
<td>{{ contact[2] }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
'''
return render_template_string(html, contacts=contacts)
except Exception as e:
print(f"Error showing contacts: {e}")
return "Internal Server Error", 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))