🎉 Hello world

This commit is contained in:
Shikiryu 2024-08-05 23:33:27 +02:00
commit a63538c768
10 changed files with 359 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.idea
/vendor
/config.php

5
README.md Normal file
View File

@ -0,0 +1,5 @@
help from :
* [Official docs](https://nextcloud-talk.readthedocs.io/en/stable/bots/)
* [Hackerone bot to help send message to talk](https://github.com/nextcloud/hackerone_bot)
* [Custom component for HA](https://github.com/klatka/nc-talk-bot-component/blob/main/custom_components/nctalkbot/__init__.py)

143
bot/Bot.php Normal file
View File

@ -0,0 +1,143 @@
<?php
namespace Shikiryu\Bot;
class Bot
{
/**
* @var Request
*/
protected $request;
protected $events = [];
protected $config = [];
/**
* @var string[]
*/
protected static $masters = [];
/**
* @return string
*/
protected function getMaster()
{
$masters = array_merge(self::$masters, $this->getConfig()['masters']);
return $masters[array_rand($masters, 1)];
}
/**
* Bot constructor.
* @param array $config
*/
public function __construct(array $config = [])
{
$this->config = $config;
}
/**
* @param Request $request
* @return bool
*/
public function isValid(Request $request)
{
$this->request = $request;
return $this->config['token'] === $request->getToken();
}
/**
* @param string $pattern the pattern to listen for
* @param \Closure|string $callback the callback to execute. Either a closure or a Class@method notation
*
* @return $this
*/
public function hears($pattern, $callback)
{
if (!array_key_exists($pattern, $this->events)) {
$this->events[$pattern] = $callback;
} else {
error_log(sprintf('Event %s déjà en place', $pattern));
}
// $this->events[$pattern][] = $callback;
return $this;
}
/**
* Try to match messages with the ones we should
* listen to.
*/
public function listen($sentence)
{
foreach ($this->events as $pattern => $command) {
$preg_pattern = sprintf('#%s#i', $pattern);
if (preg_match($preg_pattern, $sentence, $matches)) {
if (is_callable($command)) {
call_user_func($command, $this);
} else {
call_user_func([$command, 'getMessage'], $this, $matches);
}
return;
}
}
$this->replyPolitely('Je n\'ai pas compris');
}
/**
* @param string $message
*/
public function replyPolitely($message)
{
$message .= ', '.$this->getMaster().'.';
$this->reply($message);
}
public function sendChatMessage(string $referenceId, string $message): void {
$body = [
'message' => $message,
'referenceId' => $referenceId,
];
$jsonBody = json_encode($body, JSON_THROW_ON_ERROR);
$random = bin2hex(random_bytes(32));
$hash = hash_hmac('sha256', $random . $message, $this->config['secret']);
$ch = curl_init(rtrim($this->config['url'], '/') . '/ocs/v2.php/apps/spreed/api/v1/bot/' . $this->config['conversation'] . '/message');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonBody);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, 'nextcloud-talk-hackerone-adapter/1.0');
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'OCS-APIRequest: true',
'Content-Type: application/json',
'X-Nextcloud-Talk-Bot-Random: ' . $random,
'X-Nextcloud-Talk-Bot-Signature: ' . $hash,
]);
$var = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
}
private function sanitizeStringForTalkMessage(string $text): string {
return str_replace(['@', 'http://', 'https://'], ['👤', '🔗', '🔗🔒'], $text);
}
/**
* @param string $message
*/
public function reply($message)
{
// header('Content-type: application/json');
// die('{"text": "'.$message.'"}');
$this->sendChatMessage('', $message);
}
public function getConfig()
{
return $this->config;
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace Shikiryu\Bot\Commands;
use Shikiryu\Bot\Bot;
interface Icommands
{
public static function getMessage(Bot $bot, array $data);
/**
* @return string
*/
public static function getDescription();
}

21
bot/Commands/Lorem.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace Shikiryu\Bot\Commands;
use Shikiryu\Bot\Bot;
class Lorem implements Icommands
{
public static function getMessage(Bot $bot, array $data)
{
$bot->reply('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ac lectus ac lacus auctor porttitor nec non sem. Etiam tempor in turpis eleifend vehicula. Mauris congue tempus faucibus. Vestibulum varius lacinia ornare. Sed eu velit aliquet, tempor tortor eu, porttitor turpis. Ut urna ligula, finibus ac vehicula sit amet, semper non quam. Integer non lectus luctus, dictum ex ut, tempus enim.'."\n".'Aenean venenatis, nulla efficitur iaculis rutrum, velit dui ultrices lorem, sed fermentum orci ligula hendrerit erat. Phasellus porta est nec nisl ornare eleifend. Vivamus in placerat odio. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris eu euismod lectus. Aenean tristique nec odio in sollicitudin. Pellentesque egestas venenatis eros, non auctor magna hendrerit ac. Aenean bibendum rhoncus congue. Duis faucibus, tortor et euismod rhoncus, mi ipsum sollicitudin tellus, a condimentum ligula purus sit amet nibh. Nulla facilisi. Nullam sit amet ultrices ante. Vivamus dapibus congue libero in commodo. Nunc hendrerit sodales euismod. Praesent sapien ipsum, congue vel neque eget, condimentum venenatis felis. Phasellus et scelerisque odio. Aenean cursus quam nec purus hendrerit rutrum.'."\n".'Nunc leo purus, bibendum quis eros in, malesuada tincidunt nisi. Donec laoreet iaculis odio, sed efficitur libero condimentum vel. Suspendisse semper aliquam fringilla. Fusce posuere leo nulla. Sed fermentum arcu et dui scelerisque placerat. Vivamus ullamcorper orci in gravida porttitor. Nulla eu commodo neque. Cras eu risus in turpis commodo molestie. Donec lacinia, erat nec aliquet congue, risus ligula rhoncus neque, in ornare ipsum neque eget eros. Donec erat leo, porttitor in augue quis, pellentesque porta purus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin nec tortor vestibulum, egestas purus sit amet, aliquam justo. Vivamus vestibulum ligula quis enim efficitur semper.'."\n".'Aliquam erat mi, porttitor vel scelerisque at, lacinia et lacus. Ut et viverra ante. Vivamus accumsan nunc a tristique placerat. Duis fringilla, lorem nec fringilla pulvinar, orci justo efficitur sem, vulputate congue ipsum ex nec nunc. Nullam congue, urna lacinia pulvinar fermentum, nisl metus dapibus nulla, eu condimentum elit magna sit amet ante. Pellentesque venenatis dapibus erat a molestie. Vivamus mollis est non sagittis mollis. Cras odio nisl, viverra in pretium non, placerat at nibh.'."\n".'Sed quis rhoncus enim. Integer tellus diam, faucibus sit amet venenatis non, fringilla sit amet est. Vestibulum sed justo a ante porta tempor. Quisque gravida id ante vitae ultricies. Praesent a malesuada massa. Quisque feugiat, enim non volutpat ornare, nisi sem malesuada felis, et cursus mi justo quis turpis. Aenean id euismod erat, in ullamcorper ligula. Maecenas quis felis id lorem ornare ullamcorper. Donec augue dolor, euismod id sapien non, facilisis posuere nunc. Aenean lectus enim, laoreet non urna eu, pellentesque consectetur turpis.');
}
/**
* @return string
*/
public static function getDescription()
{
return 'Génère du lorem ipsum';
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace Shikiryu\Bot\Commands;
use Shikiryu\Bot\Bot;
class Youtubedl implements Icommands
{
public static function getMessage(Bot $bot, array $data)
{
$action = strtolower($data[1]); // ex: télécharge
$url = filter_var($data[2], FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED); // ex: https://www.youtube.com/watch?v=3BXDsVD6O10
$type = $data[3]; // ex: audio
if (empty($url)) {
$bot->replyPolitely('L\'url n\'est pas conforme');
}
if (!in_array($type, ['', 'audio', 'video'], true)) {
$bot->replyPolitely('Je n\'ai pas compris ce que je devais faire');
}
if (in_array($type, ['', 'audio'], true)) {
$type = 'l\'audio';
exec("youtube-dl --extract-audio --audio-format mp3 -o '/volume1/music/Podcast/Youtube/%(upload_date)s-%(uploader)s-%(title)s.%(ext)s' $url &> /dev/null &");
} else {
$type = 'la vidéo';
exec("youtube-dl -f bestvideo+bestaudio/best -o '/volume1/music/Podcast/Youtube/%(upload_date)s-%(uploader)s-%(title)s.%(ext)s' $url &> /dev/null &");
}
$bot->replyPolitely(sprintf('Je %s %s', $action, $type));
}
public static function getDescription()
{
return 'Youtubedl wrapper';
}
}

10
composer.json Normal file
View File

@ -0,0 +1,10 @@
{
"require": {
"fguillot/json-rpc": "@stable"
},
"autoload": {
"psr-4": {
"Shikiryu\\Bot\\": "bot/"
}
}
}

66
composer.lock generated Normal file
View File

@ -0,0 +1,66 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5ba319f496d82db0def48509079b247a",
"packages": [
{
"name": "fguillot/json-rpc",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/matasarei/json-rpc.git",
"reference": "85112c916c3c55f7e899c827550c52e9edb4928a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/matasarei/json-rpc/zipball/85112c916c3c55f7e899c827550c52e9edb4928a",
"reference": "85112c916c3c55f7e899c827550c52e9edb4928a",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": ">=7.4"
},
"require-dev": {
"phpunit/phpunit": "^9.6",
"squizlabs/php_codesniffer": "^3.9"
},
"type": "library",
"autoload": {
"psr-0": {
"JsonRPC": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frédéric Guillot"
}
],
"description": "Simple JSON-RPC client/server library that just works",
"homepage": "https://github.com/matasarei/JsonRPC",
"support": {
"issues": "https://github.com/matasarei/json-rpc/issues",
"source": "https://github.com/matasarei/json-rpc/tree/v1.3.0"
},
"time": "2024-06-08T19:21:47+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"fguillot/json-rpc": 0
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.6.0"
}

14
config.example.php Normal file
View File

@ -0,0 +1,14 @@
<?php
return [
'url' => '',
'secret' => '',
'conversation' => '',
'masters' => [
'Maître',
'Monsieur',
'Seigneur',
'Doyen',
'Monseigneur',
],
];

44
nextcloud.php Normal file
View File

@ -0,0 +1,44 @@
<?php
use Shikiryu\Bot\Bot;
use Shikiryu\Bot\Commands\Lorem;
use Shikiryu\Bot\Commands\Youtubedl;
require 'vendor/autoload.php';
error_reporting(E_ALL);
ini_set('log_errors', 1);
$config = include 'config.php';
$bot = new \Shikiryu\Bot\Bot($config);
$signature = $_SERVER['HTTP_X_NEXTCLOUD_TALK_SIGNATURE'] ?? '';
$random = $_SERVER['HTTP_X_NEXTCLOUD_TALK_RANDOM'] ?? '';
$server = $_SERVER['HTTP_X_NEXTCLOUD_TALK_BACKEND'] ?? '';
$delivery = $_SERVER['HTTP_X_H1_DELIVERY'] ?? '';
$event = $_SERVER['HTTP_X_H1_EVENT'] ?? '';
$signature = $_SERVER['HTTP_X_H1_SIGNATURE'] ?? '';
// Give the bot something to listen for.
$bot->hears('(convertis|télécharges?) (https?:\/\/[^\s]+) en (audio|video|vidéo)', Youtubedl::class);
$bot->hears('lorem( ipsum)?', Lorem::class);
$bot->hears('(hello|hi|bonjour|salut)', function (\Shikiryu\Bot\Bot $bot) {
$bot->replyPolitely('Bonjour');
});
$body = file_get_contents('php://input');
$data = json_decode($body, true);
if ($data['type'] !== 'Create' || $data['object']['name'] !== 'message') {
return ;
}
$message = json_decode($data['object']['content'], true)['message'];
$bot->listen($message);