Skip to content

Commit

Permalink
Implement Discord webhooks for event log
Browse files Browse the repository at this point in the history
  • Loading branch information
carlbennett committed Dec 28, 2019
1 parent 96db479 commit f80a02e
Show file tree
Hide file tree
Showing 11 changed files with 683 additions and 0 deletions.
4 changes: 4 additions & 0 deletions etc/config.sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
"vultr": ""
},
"discord": {
"forward_event_log": {
"enabled": false,
"webhook": null
},
"invite_code": "u87WVeu",
"server_id": 405789880749260820
},
Expand Down
174 changes: 174 additions & 0 deletions src/libraries/Discord/Embed.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<?php

namespace BNETDocs\Libraries\Discord;

use \BNETDocs\Libraries\Discord\EmbedAuthor;
use \BNETDocs\Libraries\Discord\EmbedField;
use \BNETDocs\Libraries\Discord\EmbedFooter;
use \BNETDocs\Libraries\Discord\EmbedImage;
use \BNETDocs\Libraries\Discord\EmbedProvider;
use \BNETDocs\Libraries\Discord\EmbedThumbnail;
use \BNETDocs\Libraries\Discord\EmbedVideo;

use \DateTime;
use \JsonSerializable;
use \LengthException;
use \OverflowException;
use \SplObjectStorage;

// <https://discordapp.com/developers/docs/resources/channel#embed-object>

class Embed implements JsonSerializable {

const MAX_DESCRIPTION = 2048;
const MAX_FIELDS = 25;
const MAX_TITLE = 256;

protected $author;
protected $color;
protected $description;
protected $fields;
protected $footer;
protected $image;
protected $provider;
protected $thumbnail;
protected $timestamp;
protected $title;
protected $type;
protected $url;
protected $video;

public function __construct() {
$this->author = null;
$this->color = -1;
$this->description = '';
$this->fields = new SplObjectStorage();
$this->footer = null;
$this->image = null;
$this->provider = null;
$this->thumbnail = null;
$this->timestamp = null;
$this->title = '';
$this->type = 'rich';
$this->url = '';
$this->video = null;
}

public function addField(EmbedField &$field_object) {
if ($this->fields->count() >= self::MAX_FIELDS) {
throw new OverflowException(sprintf(
'Discord forbids adding more than %d fields',
self::MAX_FIELDS
));
}

$this->fields->attach($field_object);
}

public function fieldCount() {
return $this->fields->count();
}

public function hasField(EmbedField &$field_object) {
return $this->fields->contains($field_object);
}

public function jsonSerialize() {
// part of JsonSerializable interface
$r = array();

if (!empty($this->description)) $r['description'] = $this->description;
if (!empty($this->title)) $r['title'] = $this->title;
if (!empty($this->type)) $r['type'] = $this->type;
if (!empty($this->url)) $r['url'] = $this->url;
if ($this->author) $r['author'] = $this->author;
if ($this->color > -1) $r['color'] = $this->color;
if ($this->fields->count() > 0) $r['fields'] = array();
if ($this->footer) $r['footer'] = $this->footer;
if ($this->image) $r['image'] = $this->image;
if ($this->provider) $r['provider'] = $this->provider;
if ($this->thumbnail) $r['thumbnail'] = $this->thumbnail;
if ($this->video) $r['video'] = $this->video;

if ($this->timestamp) $r['timestamp'] = $this->timestamp->format(
DateTime::ISO8601
);

foreach ($this->fields as $field_object) {
$r['fields'][] = $field_object;
}

return $r;
}

public function removeAllFields() {
$this->fields = new SplObjectStorage();
}

public function removeField(EmbedField &$field_object) {
$this->fields->detach($field_object);
}

public function setAuthor(EmbedAuthor &$author_object) {
$this->author = $author_object;
}

public function setColor(int $color) {
$this->color = $color;
}

public function setDescription(string $description) {
if (strlen($description) > self::MAX_DESCRIPTION) {
throw new LengthException(sprintf(
'Discord forbids description longer than %d characters',
self::MAX_DESCRIPTION
));
}

$this->title = $title;
}

public function setFooter(EmbedFooter &$footer_object) {
$this->footer = $footer_object;
}

public function setImage(EmbedImage &$image_object) {
$this->image = $image_object;
}

public function setProvider(EmbedProvider &$provider_object) {
$this->provider = $provider_object;
}

public function setThumbnail(EmbedThumbnail &$thumbnail_object) {
$this->thumbnail = $thumbnail_object;
}

public function setTimestamp(DateTime $timestamp) {
$this->timestamp = $timestamp;
}

public function setTitle(string $title) {
if (strlen($title) > self::MAX_TITLE) {
throw new LengthException(sprintf(
'Discord forbids title longer than %d characters',
self::MAX_TITLE
));
}

$this->title = $title;
}

public function setType(string $type) {
$this->type = $type;
}

public function setUrl(string $url) {
$this->url = $url;
}

public function setVideo(EmbedVideo &$video_object) {
$this->video = $video_object;
}

}
64 changes: 64 additions & 0 deletions src/libraries/Discord/EmbedAuthor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace BNETDocs\Libraries\Discord;

use \JsonSerializable;
use \LengthException;

// <https://discordapp.com/developers/docs/resources/channel#embed-object-embed-author-structure>

class EmbedAuthor implements JsonSerializable {

const MAX_NAME = 256;

protected $icon_url;
protected $name;
protected $proxy_icon_url;
protected $url;

public function __construct(string $name, string $url = '', string $icon_url = '') {
$this->setIconUrl($icon_url);
$this->setName($name);
$this->setProxyIconUrl('');
$this->setUrl($url);
}

public function jsonSerialize() {
// part of JsonSerializable interface
$r = array();

if (!empty($this->icon_url)) $r['icon_url'] = $this->icon_url;
if (!empty($this->name)) $r['name'] = $this->name;
if (!empty($this->proxy_icon_url)) $r['proxy_icon_url'] = $this->proxy_icon_url;
if (!empty($this->url)) $r['url'] = $this->url;

return $r;
}

public function setIconUrl(string $icon_url) {
$this->icon_url = $icon_url;
}

public function setName(string $name) {
if (empty($name)) {
throw new LengthException('The name cannot be empty');
}

if (strlen($name) > self::MAX_NAME) {
throw new LengthException(sprintf(
'Discord forbids name longer than %d characters', self::MAX_NAME
));
}

$this->name = $name;
}

public function setProxyIconUrl(string $proxy_icon_url) {
$this->proxy_icon_url = $proxy_icon_url;
}

public function setUrl(string $url) {
$this->url = $url;
}

}
61 changes: 61 additions & 0 deletions src/libraries/Discord/EmbedField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace BNETDocs\Libraries\Discord;

use \JsonSerializable;
use \LengthException;

// <https://discordapp.com/developers/docs/resources/channel#embed-object-embed-field-structure>

class EmbedField implements JsonSerializable {

const MAX_NAME = 256;
const MAX_VALUE = 1024;

protected $inline;
protected $name;
protected $value;

public function __construct(string $name, string $value, bool $inline) {
$this->setInline($inline);
$this->setName($name);
$this->setValue($value);
}

public function jsonSerialize() {
// part of JsonSerializable interface
$r = array();

if (!empty($this->name)) $r['name'] = $this->name;
if (!empty($this->value)) $r['value'] = $this->value;

$r['inline'] = $this->inline;

return $r;
}

public function setInline(bool $inline) {
$this->inline = $inline;
}

public function setName(string $name) {
if (strlen($name) > self::MAX_NAME) {
throw new LengthException(sprintf(
'Discord forbids name longer than %d characters', self::MAX_NAME
));
}

$this->name = $name;
}

public function setValue(string $value) {
if (strlen($value) > self::MAX_VALUE) {
throw new LengthException(sprintf(
'Discord forbids value longer than %d characters', self::MAX_VALUE
));
}

$this->value = $value;
}

}
52 changes: 52 additions & 0 deletions src/libraries/Discord/EmbedFooter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace BNETDocs\Libraries\Discord;

use \JsonSerializable;

// <https://discordapp.com/developers/docs/resources/channel#embed-object-embed-footer-structure>

class EmbedFooter implements JsonSerializable {

const MAX_TEXT = 2048;

protected $icon_url;
protected $proxy_icon_url;
protected $text;

public function __construct(string $text, string $icon_url = '', string $proxy_icon_url = '') {
$this->setIconUrl($icon_url);
$this->setProxyIconUrl($proxy_icon_url);
$this->setText($text);
}

public function jsonSerialize() {
// part of JsonSerializable interface
$r = array();

if (!empty($this->icon_url)) $r['icon_url'] = $this->icon_url;
if (!empty($this->proxy_icon_url)) $r['proxy_icon_url'] = $this->proxy_icon_url;
if (!empty($this->text)) $r['text'] = $this->text;

return $r;
}

public function setIconUrl(string $icon_url) {
$this->icon_url = $icon_url;
}

public function setProxyIconUrl(string $proxy_icon_url) {
$this->proxy_icon_url = $proxy_icon_url;
}

public function setText(string $text) {
if (strlen($text) > self::MAX_TEXT) {
throw new LengthException(sprintf(
'Discord forbids text longer than %d characters', self::MAX_TEXT
));
}

$this->text = $text;
}

}
Loading

0 comments on commit f80a02e

Please sign in to comment.