Skip to content

Instantly share code, notes, and snippets.

@raamdev
Last active March 10, 2016 13:41
Show Gist options
  • Save raamdev/5034488ade6a054fa81a to your computer and use it in GitHub Desktop.
Save raamdev/5034488ade6a054fa81a to your computer and use it in GitHub Desktop.
<?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 = '[email protected]';
// 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
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