Skip to content

Instantly share code, notes, and snippets.

@carlbennett
Last active September 27, 2019 03:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlbennett/d77760b1f758ea160870c778667969e5 to your computer and use it in GitHub Desktop.
Save carlbennett/d77760b1f758ea160870c778667969e5 to your computer and use it in GitHub Desktop.
A php script that takes an email formatted as a POST form and turns it into a Discord webhook
<?php
namespace CarlBennett;
use \DateTime;
use \DateTimeZone;
use \Exception;
use \StdClass;
const GRAVATAR_BASE = 'https://secure.gravatar.com/avatar/';
const GRAVATAR_ARGS = '?s=256&d=identicon';
const TOKEN_SECRET = 'INSERT_SECRET_HERE';
function exit_here( $code = 500, $message = '' ) {
http_response_code( $code );
header( 'Content-Type: text/plain;charset=utf-8' );
die( $message );
}
function get_name_and_email_address( $str ) {
$name = '';
$email = '';
try {
$addresses = \mailparse_rfc822_parse_addresses( $str );
if ( count( $addresses ) > 0 ) {
$name = $addresses[ 0 ][ 'display' ];
$email = $addresses[ 0 ][ 'address' ];
}
} catch ( Exception $e ) {}
return [ $name, $email ];
}
function get_avatar( $email ) {
return GRAVATAR_BASE . hash( 'md5', trim( $email )) . GRAVATAR_ARGS;
}
function query_arg( $name, $default = null ) {
return ( isset( $_REQUEST[ $name ]) ? $_REQUEST[ $name ] : $default );
}
$token = query_arg( 'token' );
$subject_filter = query_arg( 'subject_filter' );
$from = query_arg( 'from' );
$subject = query_arg( 'subject' );
$body_plain = query_arg( 'body_plain' );
$body_html = query_arg( 'body_html' );
$date = query_arg( 'date' );
$color = query_arg( 'color' );
$discord_webhook = query_arg( 'discord_webhook' );
if ( empty( $token ) && !empty( TOKEN_SECRET )) {
exit_here( 400, 'Missing: token' );
}
if ( $token !== TOKEN_SECRET ) {
exit_here( 401, 'Unauthorized' );
}
if ( empty( $discord_webhook )) {
exit_here( 400, 'Missing: discord_webhook' );
}
if ( !empty( $subject_filter ) &&
stripos( $subject, $subject_filter ) === false ) {
exit_here( 204 );
}
if ( empty( $body_plain )) {
$body = filter_var( $body_html, FILTER_SANITIZE_STRING );
} else {
$body = $body_plain;
}
$color = trim( $color );
if ( preg_match( '/^\d{1,3},\d{1,3},\d{1,3},\d{1,3}$/', $color )) {
// ARGB
$colors = explode( ',', $color );
$color = sprintf( '%02x%02x%02x%02x',
$colors[ 0 ], $colors[ 1 ], $colors[ 2 ], $colors[ 3 ]
);
$color = hexdec( $color );
} else if ( preg_match( '/^\d{1,3},\d{1,3},\d{1,3}$/', $color )) {
// RGB
$colors = explode( ',', $color );
$color = sprintf( '%02x%02x%02x',
$colors[ 0 ], $colors[ 1 ], $colors[ 2 ]
);
$color = hexdec( $color );
} else if ( preg_match( '/^[A-Fa-f0-9]{1,8}$/', $color )) {
// Hex
$color = hexdec( $color );
}
try {
$tz = new DateTimeZone( 'Etc/UTC' );
$date_obj = new DateTime( $date, $tz );
$date_str = $date_obj->format( DateTime::ISO8601 );
} catch ( Exception $e ) {
$date_str = $date;
}
$from_info = get_name_and_email_address( $from );
$discord_data = [
'embeds' => [
[
'author' => [
'icon_url' => get_avatar( $from_info[ 1 ]),
'name' => $from_info[ 0 ],
],
'color' => $color,
'description' => $body,
'timestamp' => $date_str,
'title' => $subject,
'type' => 'rich',
],
],
'wait' => true,
];
$curl = curl_init();
$time = microtime( true );
curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 5 );
curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $curl, CURLOPT_MAXREDIRS, 10 );
curl_setopt( $curl, CURLOPT_POSTREDIR, 7 ); // redirect POST on 301,302,303
curl_setopt( $curl, CURLOPT_URL, $discord_webhook );
curl_setopt( $curl, CURLOPT_POST, true );
curl_setopt( $curl, CURLOPT_SAFE_UPLOAD, true );
curl_setopt( $curl, CURLOPT_POSTFIELDS, json_encode( $discord_data ));
curl_setopt( $curl, CURLOPT_HTTPHEADER, [
'Content-Type: application/json;charset=utf-8'
]);
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
$r = new StdClass();
$r->data = curl_exec( $curl );
$r->code = curl_getinfo( $curl, CURLINFO_HTTP_CODE );
$r->type = curl_getinfo( $curl, CURLINFO_CONTENT_TYPE );
$r->time = microtime( true ) - $time;
curl_close( $curl );
http_response_code( $r->code );
header( 'Content-Type: ' . $r->type );
echo $r->data;
// DEBUGGING
file_put_contents( __DIR__ . DIRECTORY_SEPARATOR . '.r.json',
json_encode( $discord_data, JSON_PRETTY_PRINT ) . PHP_EOL .
json_encode( $r, JSON_PRETTY_PRINT ) . PHP_EOL
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment