New way for message forwarding. Improved scheduled listing

This commit is contained in:
giuliof 2017-09-28 21:41:43 +02:00
parent cb69679e4e
commit 36337b3f37
5 changed files with 362 additions and 57 deletions

9
TODO
View File

@ -3,6 +3,15 @@
* Document code
Very important, since now it is far more complex
* Clean code. Some ideas:
** Substitute bot calls with API functions (i.e. sendMessage, forwardMessage...).
Functions are already written (not yet tested!) in shared.php
** Create a class for inline keyboard management
** Use info(), warning() and error() instead of botlog()
** Always insert "or error(... $sql->error())" when making SQL queries.
* Capabilities to send Image/Videos/Document (at the moment are blocked)
* Facebook page integration
Make the bot publish info not only in mailing list and Telegram channel,
but also on our Facebook page

View File

@ -16,6 +16,13 @@
const DEBUG = true;
/* Log file name */
const LOGFILE = 'botlog.log';
/* MySQL informations */
const MYSQL_USER = '';
const MYSQL_PASSWORD = '';
const MYSQL_DB = '';
const MYSQL_TABLE = '';
/* Memcached local server port */
const MEMCACHED_PORT = '11211';
$EMOJI_THUMBSUP = mb_convert_encoding('👍', 'UTF-8', 'HTML-ENTITIES');
$EMOJI_THUMBSDOWN = mb_convert_encoding('👎', 'UTF-8', 'HTML-ENTITIES');
@ -33,23 +40,20 @@
const STATE_MSG_ANSWER = 'msg_answer';
// Saved variables in memcached
const MC_STATUS = 'status';
const MC_FORWARD_MSG = 'msg_forward';
const MC_DATE_MSG = 'msg_date';
const MC_INLINE_ID = 'inline_id';
const MC_STATUS = 'status';
const MC_FORWARD_MSG = 'msg_forward';
const MC_DATE_MSG = 'msg_date';
const MC_INLINE_ID = 'inline_id';
const MC_FW_EDIT = 'fw_edit'; // should not be necessary anymore
const MC_LIST_NUMBER = 'list_number';
const MC_DELETE_SCHEDULED_ID = 'delete_sch_id';
// buttons costants
const MSG_YES = 'y';
const MSG_NO = 'n';
const MSG_SCHEDULE = 'sch';
const MSG_ABORT = 'abort';
const MYSQL_USER = '';
const MYSQL_PASSWORD = '';
const MYSQL_DB = '';
const MYSQL_TABLE = '';
const MEMCACHED_PORT = '11211';
const MSG_DELETE = 'delete';
$WELCOME_MESSAGE = "$EMOJI_BOT GOLEMbot
$EMOJI_MSG Se scrivi un messaggio ti chiedo se inoltrarlo al canale

272
main.php
View File

@ -1,8 +1,8 @@
<?php
/*
* Codice beta v0.99 del GOLEMbot - 24 set 2017
* Codice beta v0.99.1 del GOLEMbot - 28 set 2017
*
* Opera by giomba e giuliof rilasciata sotto licenza GPLv3
* Opera by giomba, lucam e giuliof released by GPLv3 license
*
*/
@ -27,8 +27,8 @@ $mc->addServer('localhost', MEMCACHED_PORT)
or error("Something is wrong connecting to memcached daemon");
// Accept only messages from a private chat
if (isset($row->message->chat->type) and $row->message->chat->type != "private") {
if (DEBUG) warning("Message from ".$row->message->chat->type);
if(!isset($row->message->text)) {
if (DEBUG) warning("Message from a not acceptable source");
die();
}
// HANDLE A CALLBACK
@ -59,6 +59,12 @@ elseif (isset ($row->callback_query)) {
}
// HANDLE A COMMON MESSAGE (text/commands/keyboard)
else {
// throw away photos, documents and stickers (fixit)
if(isset($row->message->sticker) or isset($row->message->document)) {
// sto username si potrebbe quasi quasi estrapolare e mettere in una variabile decente
error("Qualcheduno (".$row->message->from->username.") ha mandato una cosa non supportata");
}
// Load variables
$chatID = $row->message->chat->id;
@ -70,7 +76,11 @@ else {
}
// Finally, check actual state and do things
$status = $mc->get($chatID.MC_STATUS) or $mc->set($chatID.MC_STATUS, STATE_IDLE) or die(); // set status or force it to STATE_IDLE
$status = $mc->get($chatID.MC_STATUS);
if (!$status) {
$mc->set($chatID.MC_STATUS, STATE_IDLE) or die(); // set status or force it to STATE_IDLE
$status = STATE_IDLE;
}
if (DEBUG) info("Starting from status $status");
// ricordati di schiantare quando ricevi un messaggio invece di una callback
@ -79,12 +89,114 @@ switch ($status) {
case STATE_IDLE:
// In this state are not accepted callback requests
if (isset($callback_data)) {
if (DEBUG) warning("Callback request is not accepted in status $status");
die();
}
switch ($callback_data){
case MSG_DELETE:
$sql = new mysqli('localhost', MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB);
$IDdelete = $mc->get($chatID.MC_DELETE_SCHEDULED_ID);
$sql->query("DELETE FROM ".MYSQL_TABLE." WHERE ID=$IDdelete")
or error("Can't make the query, SQL error ".$sql->error);
$sql->close();
$url = API_URL.API_TOKEN."/editMessageText?chat_id=".($chatID).
"&message_id=".$inlineID .
"&text=Rimosso correttamente";
file_get_contents($url);
die();
break;
case '>':
$sql = new mysqli('localhost', MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB);
$numbers = $sql->query("SELECT COUNT(*) FROM ".MYSQL_TABLE);
$numbers = $numbers->fetch_array()[0];
info("Number of pages: $numbers");
$offset = $mc->get($chatID.MC_LIST_NUMBER);
// gestire meglio qui
$offset++;
break;
case '<':
$sql = new mysqli('localhost', MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB);
$numbers = $sql->query("SELECT COUNT(*) FROM ".MYSQL_TABLE);
$numbers = $numbers->fetch_array()[0];
info("Number of pages: $numbers");
$offset = $mc->get($chatID.MC_LIST_NUMBER);
// gestire meglio qui
$offset--;
break;
default:
if (DEBUG) warning("Callback request is not accepted in status $status");
die();
}
$query = $sql->query("SELECT DATE_FORMAT(DateTime,'%d/%m/%Y ore %H') as DateTime,Text,Author,ID FROM ".MYSQL_TABLE."
ORDER BY DateTime ASC LIMIT 1 OFFSET $offset") or error("Can't make the query, SQL error ".$sql->error);
//while($row = $query->fetch_assoc()) {
$row = $query->fetch_assoc();
$mc->set($chatID.MC_DELETE_SCHEDULED_ID, $row['ID'])
or $mc->replace($chatID.MC_DELETE_SCHEDULED_ID, $row['ID']);
//~ $query = API_URL . API_TOKEN . '/forwardMessage?' .
//~ 'chat_id=' . urlencode($chatID) .
//~ '&from_chat_id=' . urlencode($row['ChatID']) .
//~ '&message_id=' . urlencode($row['MessageID']);
//~ $answer = file_get_contents($query);
//~ $answer = json_decode($answer);
$sql->close();
$container = array(
array(
array(
"text" => $row['DateTime'],
"callback_data" => "null"
)));
$container[] = array(
$offset > 0?
array(
"text" => "<",
"callback_data" => "<"
)
:
array(
"text" => " ",
"callback_data" => "null"
),
array(
"text" => "$EMOJI_THUMBSDOWN Canc",
"callback_data" => MSG_DELETE
),
$offset < $numbers-1 ?
array(
"text" => ">",
"callback_data" => ">"
)
:
array(
"text" => " ",
"callback_data" => "null"
)
);
$resp = array(
"inline_keyboard" => $container);
$reply = json_encode($resp);
$text="$row[Text]\n_$row[Author]_"; // NOME CANALE ".API_CHANNEL_ID."?";
$query = API_URL.API_TOKEN."/editMessageText?chat_id=".($chatID).
"&message_id=".$inlineID.
"&text=".urlencode($text).
"&parse_mode=".urlencode("Markdown").
"&reply_markup=".$reply;
$answer = file_get_contents($query);
$answer = json_decode($answer);
$mc->set($chatID.MC_LIST_NUMBER, $offset)
or $mc->replace($chatID.MC_LIST_NUMBER, $offset);
die();
}
// qui ci metterei un else
// Search for a command
if (($command = getCommand($row->message)) != -1) {
if (($command = getCommand($row->message)) != null) {
info("Command received: $command[command] with options $command[options]");
switch ($command['command']) {
@ -99,29 +211,116 @@ switch ($status) {
file_get_contents($query);
break;
case '/edit':
//~ $text = "Invio effettuato correttamente";
//~ $url = API_URL.API_TOKEN."/deleteMessage?chat_id=".($chatID).
//~ "&message_id=2551";
//~ file_get_contents($url);
break;
case '/list':
$dateID = date('Y-n-j G:*');
//~ $dateID = date('Y-n-j G:*');
//~ $sql = new mysqli('localhost', MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB);
//~ $query = $sql->query("SELECT DateTime,ChatID,MessageID FROM ".MYSQL_TABLE." WHERE DateTime>='$dateID'
//~ ORDER BY DateTime ASC LIMIT 10") or error("Can't make the query, SQL error ".$sql->error);
//~ $text = "Prossimi 10 messaggi programmati";
//~ $i = 1;
//~ while($row = $query->fetch_assoc()) {
//~ $text .= "\n".$i." - ". $row['DateTime'];
//~ $i++;
//~ }
//~ $text .= "\nFunzione in miglioramento";
//~ $query = API_URL . API_TOKEN . '/sendMessage?' .
//~ 'chat_id=' . urlencode($chatID) .
//~ '&text=' . urlencode($text);
//~ $sql->close();
//~ file_get_contents($query);
//~ break;
// yusdgfdsjf
//~ $dateID = date('Y-n-j G:*');
$sql = new mysqli('localhost', MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB);
$query = $sql->query("SELECT DateTime FROM ".MYSQL_TABLE." WHERE DateTime>='$dateID'
ORDER BY DateTime ASC LIMIT 10") or error("Can't make the query, SQL error ".$sql->error);
$text = "Prossimi 10 messaggi programmati";
$i = 1;
while ($row = $query->fetch_assoc()) {
$text .= "\n".$i." - ". $row['DateTime'];
$i++;
$numbers = $sql->query("SELECT COUNT(*) FROM ".MYSQL_TABLE);
$numbers = $numbers->fetch_array()[0];
if ($numbers == 0) {
$query = API_URL.API_TOKEN."/sendmessage?chat_id=".($chatID).
"&text=Nessun messaggio programmato";
$answer = file_get_contents($query);
die();
}
$query = $sql->query("SELECT DATE_FORMAT(DateTime,'%d/%m/%Y ore %H') as DateTime,Text,Author,ID FROM ".MYSQL_TABLE."
ORDER BY DateTime ASC LIMIT 1") or error("Can't make the query, SQL error ".$sql->error);
//while($row = $query->fetch_assoc()) {
$row = $query->fetch_assoc();
$mc->set($chatID.MC_DELETE_SCHEDULED_ID, $row['ID'])
or $mc->replace($chatID.MC_DELETE_SCHEDULED_ID, $row['ID']);;
//~ $query = API_URL . API_TOKEN . '/forwardMessage?' .
//~ 'chat_id=' . urlencode($chatID) .
//~ '&from_chat_id=' . urlencode($row['ChatID']) .
//~ '&message_id=' . urlencode($row['MessageID']);
//~ $answer = file_get_contents($query);
//~ $answer = json_decode($answer);
$sql->close();
$query = API_URL.API_TOKEN."/sendmessage?chat_id=".($chatID).
"&text=".urlencode($text).
"&reply_markup=".$reply;
$answer = file_get_contents($query);
//$mc->set($chatID.MC_FW_EDIT, $answer->result->message_id)
// or $mc->replace($chatID.MC_FW_EDIT, $answer->result->message_id);
$container = array(
array(
array(
"text" => $row['DateTime'],
"callback_data" => "null"
)));
$container[] = array(
array(
"text" => " ",
"callback_data" => "null"
),
array(
"text" => "$EMOJI_THUMBSDOWN Canc",
"callback_data" => MSG_DELETE
),
$numbers > 1 ?
array(
"text" => ">",
"callback_data" => ">"
)
:
array(
"text" => " ",
"callback_data" => "null"
)
);
$resp = array(
"inline_keyboard" => $container);
$reply = json_encode($resp);
$text="$row[Text]\n_$row[Author]_"; // NOME CANALE ".API_CHANNEL_ID."?";
$query = API_URL.API_TOKEN."/sendmessage?chat_id=".($chatID).
"&text=".urlencode($text).
"&parse_mode=".urlencode("Markdown").
"&reply_markup=".$reply;
$answer = file_get_contents($query);
$answer = json_decode($answer);
$mc->set($chatID.MC_INLINE_ID, $answer->result->message_id)
or $mc->replace($chatID.MC_INLINE_ID, $answer->result->message_id);
$mc->set($chatID.MC_LIST_NUMBER, 0)
or $mc->replace($chatID.MC_LIST_NUMBER, 0);
break;
default:
if (DEBUG) warning("$command[command] is not a valid command");
warning("$command[command] is not a valid command");
}
}
else { // not a command (pure text)
@ -181,11 +380,17 @@ switch ($status) {
$msg = $mc->get($chatID.MC_FORWARD_MSG)
or error("Can't forward message\n");
$query = API_URL . API_TOKEN . '/forwardMessage?' .
'chat_id=' . urlencode(API_CHANNEL_ID) .
'&from_chat_id=' . urlencode($msg->message->chat->id) .
'&message_id=' . urlencode($msg->message->message_id);
file_get_contents($query);
//~ $query = API_URL . API_TOKEN . '/forwardMessage?' .
//~ 'chat_id=' . urlencode(API_CHANNEL_ID) .
//~ '&from_chat_id=' . urlencode($msg->message->chat->id) .
//~ '&message_id=' . urlencode($msg->message->message_id);
//~ file_get_contents($query);
$query = API_URL . API_TOKEN . '/sendmessage?' .
'chat_id=' . urlencode(API_CHANNEL_ID) .
'&text='.urlencode($msg->message->text."\n_".$msg->message->chat->username."_").
"&parse_mode=".urlencode("Markdown"); //bah, un isset un ce lo vedrei male
$result = file_get_contents($query);
if(DEBUG) botlog("[LOG] $result\n");
// Remove kbd
$text = "Invio effettuato correttamente";
@ -386,7 +591,7 @@ switch ($status) {
$msg = $mc->get($chatID.MC_FORWARD_MSG);
// add to database (mysql)
$sql = new mysqli('localhost', MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB);
// Build up mysql query
$value = "(";
$value .= $msg->message->message_id;
@ -397,12 +602,17 @@ switch ($status) {
$value .= $currentTab['month'].'-';
$value .= $currentTab['day'].' ';
$value .= $callback_data.":00:00'";
$value .= ",";
$value .= "'".$sql->escape_string($msg->message->text)."'";
$value .= ",";
$value .= "'".$sql->escape_string($msg->message->from->username)."'"; // andrebbe fatto un isset, vabbé
$value .= ");";
info("Saving post in ".MYSQL_TABLE.", scheduled date: ".$value);
$sql = new mysqli('localhost', MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB);
$query = $sql->query("INSERT INTO ".MYSQL_TABLE." (MessageID,ChatID,DateTime) VALUE ".$value);
$query = $sql->query("INSERT INTO ".MYSQL_TABLE." (MessageID,ChatID,DateTime,Text,Author) VALUE ".$value)
or error("Can't make the query, SQL error ".$sql->error);
$sql->close();
$text = "Programmazione avvenuta con successo";

View File

@ -1,23 +1,33 @@
<?php
/*
* This script must be called from the system every hour (i.e. cron)
*/
require_once('config.php');
require_once('shared.php');
if (DEBUG) botlog("\n\n\n".'[II] Scheduler starting at ' . date('Y-m-d H:i:s') . ' ====================' . "\n\n");
// Get current date in MySQL DATETIME default format
$dateID = date('Y-n-j G:*');
echo $dateID;
// Connect to MySQL DB
$sql = new mysqli('localhost', MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB);
$query = $sql->query("SELECT MessageID,ChatID FROM ".MYSQL_TABLE." WHERE DateTime='".$dateID."'");
$query = $sql->query("SELECT DateTime,Text,Author FROM ".MYSQL_TABLE.
"WHERE DateTime='".$dateID."'")
or error("Can't make the query, SQL error ".$sql->error);
// Post all messages (only text)
while ($row = $query->fetch_assoc()) {
info("Publishing message $row[MessageID]");
$bot_query = API_URL . API_TOKEN . '/forwardMessage?' .
$bot_query = API_URL . API_TOKEN . '/sendMessage?' .
'chat_id=' . urlencode(API_CHANNEL_ID) .
'&from_chat_id=' . urlencode($row['ChatID']) .
'&message_id=' . urlencode($row['MessageID']);
'&text=' . urlencode($row['Text']."\n_".$row['Author']."_").
"&parse_mode=".urlencode("Markdown");
file_get_contents($bot_query);
}
// clean events <= today
// Remove just posted messages (and any eventual previous one)
$sql->query("DELETE FROM ".MYSQL_TABLE." WHERE DateTime<='".$dateID."'");
$sql->close();
?>

View File

@ -25,26 +25,98 @@
if (DEBUG) botlog("[II] $message\n");
}
// Interpreta un comando inviato al bot - mettere null o simili invece di -1
// Interpreta un comando inviato al bot - mettere null o simili invece di -1
function getCommand($messaggio, $NoOffset = true) {
if (!isset($messaggio->entities))
return -1;
return null;
foreach ($messaggio->entities as $entity) {
if ($entity->type == "bot_command") {
if ($NoOffset == true and $entity->offset != 0)
return -1;
return null;
//~ if (DEBUG) botlog("[II] Comando: ".$entity->offset. " ".$messaggio->text);
//return substr($messaggio->text, $entity->offset, $entity->length);
$ret['command'] = substr($messaggio->text, $entity->offset, $entity->length);
$ret['options'] = substr($messaggio->text, $entity->length+$entity->offset+1);
if (DEBUG) botlog("[II] Comando: ".$ret['command']."\n");
info("Command: $ret[command]");
return $ret;
}
}
return -1;
return null;
}
// fabbrica una tabellina che in futuro sarà la pagina di calendario specificata da $mese e $anno
/**** Telegram query functions ****/
// return a message object, null if is error
function sendMessage($chat_id, $text, $parse_mode = null,
$disable_web_preview = false,
$disable_notification = false,
$reply_to_message_id = null,
$reply_markup = null) {
$query = API_URL.API_TOKEN."/sendMessage?chat_id=".$chat_id.
"&text=".urlencode($text);
if ($parse_mode != null) $query .= "&parse_mode=$parse_mode";
if ($reply_markup != null) $query .= "&reply_markup=$reply_markup";
if ($disable_web_preview != false) $query .= "&disable_web_preview=$disable_web_preview";
if ($disable_notification != false) $query .= "&disable_notification=$disable_notification";
if ($reply_to_message_id != null) $query .= "&reply_to_message_id=$reply_to_message_id";
if ($reply_markup != null) $query .= "&reply_markup=$reply_markup";
$answer = file_get_contents($query);
if ($answer === false) warning("Something is wrong in sendMessage - chat_id: $chat_id - text: $text");
return $answer;
}
//
function forwardMessage($chat_id, $from_chat_id,
$message_id,
$disable_notification = false) {
$query = API_URL . API_TOKEN . "/forwardMessage?" .
"chat_id=".urlencode($chat_id) .
"&from_chat_id=" . urlencode($from_chat_id) .
"&message_id=" . urlencode($message_id);
if ($disable_notification != null) $query .= "&disable_notification=$disable_notification";
$answer = file_get_contents($query);
if ($answer === false) warning("Something is wrong in forwardMessage - chat_id: $chat_id - message_id: $message_id");
return $answer;
}
// omitted "inline parameters", for inline bot funtions (not used here)
function editMessageText($chat_id, $message_id, $text,
$parse_mode = null,
$disable_web_page_preview = false,
$reply_markup = null) {
$query = API_URL . API_TOKEN . "/forwardMessage?" .
"chat_id=".urlencode($chat_id) .
"&message_id=" . urlencode($message_id).
"&text=" . urlencode($text);
if ($disable_web_page_preview != null) $query .= "&disable_web_page_preview=$disable_web_page_preview";
if ($reply_markup != null) $query .= "&reply_markup=$reply_markup";
$answer = file_get_contents($query);
if ($answer === false) warning("Something is wrong in editMessageText - chat_id: $chat_id - message_id: $message_id");
return $answer;
}
//
function deleteMessage($chat_id, $message_id) {
$query = API_URL . API_TOKEN . "/deleteMessage?" .
"chat_id=".urlencode($chat_id) .
"&message_id=" . urlencode($message_id);
$answer = file_get_contents($query);
if ($answer === false) warning("Something is wrong in deleteMessage - chat_id: $chat_id - message_id: $message_id");
return $answer;
}
// Makes the calendar inline keyboard
function getCalendarTab ($month, $year) {
$container = array();
$riga = array();
@ -66,8 +138,8 @@
$daysInMonth = cal_days_in_month (CAL_GREGORIAN , $month , $year);
$date = $year."-".$month;
$currentMonth = date('nY') == $month.$year; //magari anche l'anno?
$startingDay = $currentMonth ? date('j') : 1;
$isCurrentMonth = date('nY') == $month.$year;
$startingDay = $isCurrentMonth ? date('j') : 1;
if (DEBUG) botlog("[II] First day: ".$date.'-'.$startingDay."\n");
$firstDay = date("N", strtotime($date.'-'.$startingDay));
@ -121,7 +193,7 @@
$container[] = array(
$currentMonth ?
$isCurrentMonth ?
array(
"text" => " ",
"callback_data" => "null"