Skip to content

Instantly share code, notes, and snippets.

@raamdev raamdev/github-events.php
Last active Mar 10, 2016

Embed
What would you like to do?
<?php
if(!defined('WPINC')) // MUST have WordPress.
exit('Do NOT access this file directly: '.basename(__FILE__));
add_action('init', 'github_events::init');
class github_events // Event handler.
{
# Configuration ###############################################
private static $key = 'MY SECRET KEY'; // Secret webhook key.
// e.g., http://yourdomain.com/?github_events=$key is your GitHub Webhook URL.
// I set this up for all repos in my organization on GitHub, that way this handles all issue labeling events.
// See: <https://github.com/blog/1933-introducing-organization-webhooks>
// When you configure the Webhook at Github. Choose `application/json` and Send Everything.
private static $omnifocus = 'YOU-xxxxx@sync.omnigroup.com';
// i.e., Your OmniSync Maildrop address.
private static $github_username = 'GITHUB_USERNAME';
// i.e., Your GitHub Username
private static $github_events_to_capture = array('issues' => array('labeled', 'assigned'));
// An array of GitHub event types, with each event type containing an array of actions to capture
################################################################
private static $data; // GitHub event data.
public static function init()
{
if(empty($_REQUEST['github_events']))
return; // Not applicable.
static::maybe_handle_event();
}
private static function maybe_handle_event()
{
ignore_user_abort(TRUE); // Webhook may not wait.
status_header(200); // Make sure GitHub knows we got this.
nocache_headers(); // Do NOT allow browser caching here.
define('ZENCACHE_ALLOWED', FALSE); // No caching.
if($_REQUEST['github_events'] !== static::$key)
exit; // Nothing to do in this case.
if(empty($_SERVER['HTTP_X_GITHUB_EVENT']))
exit; // Nothing to do in this case.
if(strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST')
exit; // Nothing to do in this case.
if(!($raw_post_data = trim(file_get_contents('php://input'))))
exit; // Nothing to do in this case.
if(!is_object(static::$data = json_decode($raw_post_data)))
exit; // Nothing to do in this case.
static::$data->event_type = $_SERVER['HTTP_X_GITHUB_EVENT'];
static::maybe_handle_event_type(); // Handle this.
exit; // Stop here; all done now.
}
private static function maybe_handle_event_type()
{
switch(static::$data->event_type)
{
case 'issues': // An issue-related event at GitHub?
if(is_array(static::$github_events_to_capture) &&
!array_key_exists(static::$data->event_type, static::$github_events_to_capture))
break; // Not applicable.
switch(static::$data->action) // What action just occurred?
{
case 'labeled': // An issue was labeled.
if(is_array(static::$github_events_to_capture[static::$data->event_type]) &&
!in_array(static::$data->action, static::$github_events_to_capture[static::$data->event_type]))
break; // Not applicable.
if(empty(static::$data->label->name))
break; // No label name.
if(static::$data->issue->state !== 'open')
break; // Issue is no longer open.
$label = str_replace(array('-', '_'), ' ', static::$data->label->name);
if(strcasecmp($label, 'ready for work') !== 0)
break; // Not what we are looking for here.
$subject = static::$data->issue->title; // Issue title.
$body = 'GitHub Issue: '.static::$data->repository->full_name.'#'.static::$data->issue->number.' <'.static::$data->issue->html_url.'>'."\n";
$body .= 'Opened by: @'.static::$data->issue->user->login.' <'.static::$data->issue->user->html_url.'>'."\n";
$body .= 'Labels: '; // Begin labels.
foreach(static::$data->issue->labels as $_label)
$body .= $_label->name.', ';
unset($_label); // Housekeeping.
$body = rtrim($body, ', ')."\n"; // Line break after labels.
if(!empty(static::$data->issue->milestone->name))
$body .= 'Milestone: '.static::$data->issue->milestone->name."\n";
$body .= "\n".static::$data->issue->body;
wp_mail(static::$omnifocus, $subject, $body);
break; // Break switch handler.
case 'assigned': // An issue was assigned.
if(is_array(static::$github_events_to_capture[static::$data->event_type]) &&
!in_array(static::$data->action, static::$github_events_to_capture[static::$data->event_type]))
break; // Not applicable.
if(empty(static::$data->assignee->login))
break; // No assignee name.
// Uncomment the next two lines if you only want to hear about Open issues assigned to you
//if(static::$data->issue->state !== 'open')
// break; // Issue is no longer open.
if(strcasecmp(static::$data->assignee->login, static::$github_username) !== 0)
break; // Not what we are looking for here.
$subject = static::$data->issue->title; // Issue title.
$body = 'GitHub Issue: '.static::$data->repository->full_name.'#'.static::$data->issue->number.' <'.static::$data->issue->html_url.'>'."\n";
$body .= 'Opened by: @'.static::$data->issue->user->login.' <'.static::$data->issue->user->html_url.'>'."\n";
$body .= 'Labels: '; // Begin labels.
foreach(static::$data->issue->labels as $_label)
$body .= $_label->name.', ';
unset($_label); // Housekeeping.
$body = rtrim($body, ', ')."\n"; // Line break after labels.
if(!empty(static::$data->issue->milestone->name))
$body .= 'Milestone: '.static::$data->issue->milestone->name."\n";
$body .= "\n".static::$data->issue->body;
wp_mail(static::$omnifocus, $subject, $body);
break; // Break switch handler.
}
break; // Break switch handler.
}
}
}
@jaswrks

This comment has been minimized.

Copy link

jaswrks commented Apr 5, 2015

case 'assigned': // An issue was assigned.

Awesome idea! Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.