Created
June 14, 2016 00:30
-
-
Save michaelbramwell/2ed8094a9c00369806f185b2c775d320 to your computer and use it in GitHub Desktop.
Simple Slack WebHook Client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// dependancies: Newtonsoft.Json, RestSharp; | |
public interface IRpcClient<T> | |
{ | |
string AccessToken { get; } | |
string BaseUrl { get; } | |
T DataStore { get; } | |
string Host { get; } | |
string Protocal { get; } | |
string RelativeUrl { get; } | |
T ExecuteGet(); | |
void ExecutePost(T postModel); | |
} | |
public class SlackModel | |
{ | |
public class WebHook | |
{ | |
[JsonProperty("channel")] | |
public string Channel { get; set; } | |
[JsonProperty("icon_emoji")] | |
public string IconEmoji { get; set; } | |
[JsonProperty("text")] | |
public string Text { get; set; } | |
[JsonProperty("mrkdwn")] | |
public bool UserMarkDown { get; set; } | |
[JsonProperty("username")] | |
public string Username { get; set; } | |
} | |
} | |
public class SlackWebHookService : IRpcClient<SlackModel.WebHook> | |
{ | |
private Func<string, string> _config; | |
public SlackWebHookService(Func<string, string> config) | |
{ | |
_config = config; | |
} | |
public string AccessToken | |
{ | |
get | |
{ | |
return _config("Slack.WebHook.AccessToken"); | |
} | |
} | |
public string BaseUrl | |
{ | |
get | |
{ | |
return Protocal + Host; | |
} | |
} | |
public SlackModel.WebHook DataStore | |
{ | |
get | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
public string Host | |
{ | |
get | |
{ | |
return _config("Slack.WebHook.Host"); | |
} | |
} | |
public string Protocal | |
{ | |
get | |
{ | |
return _config("Slack.WebHook.Protocal"); | |
} | |
} | |
public string RelativeUrl | |
{ | |
get | |
{ | |
return string.Format("{0}{1}", _config("Slack.WebHook.Path"), | |
_config("Slack.WebHook.AccessToken")); | |
} | |
} | |
public SlackModel.WebHook ExecuteGet() | |
{ | |
throw new NotImplementedException(); | |
} | |
public void ExecutePost(SlackModel.WebHook postModel) | |
{ | |
var client = new RestClient(BaseUrl); | |
var request = new RestSharp.RestRequest(RelativeUrl, Method.POST); | |
request.RequestFormat = DataFormat.Json; | |
request.AddParameter("application/json", JsonConvert.SerializeObject(postModel), ParameterType.RequestBody); | |
var response = client.Execute(request); | |
if (response.StatusCode != System.Net.HttpStatusCode.OK) | |
{ | |
throw new Exception(string.Format("Slack webhook failed when posting to '{0}' returned an error", postModel.Channel)); | |
} | |
} | |
} | |
public class SlackWebHook | |
{ | |
protected Func<string, string> _config; | |
protected string _message; | |
protected IRpcClient<SlackModel.WebHook> _slack; | |
public SlackWebHook(IRpcClient<SlackModel.WebHook> slack, string message, Func<string, string> config) | |
{ | |
_slack = slack; | |
_config = config; | |
_message = message; | |
} | |
/// <summary> | |
/// If no model is provided the default slack channel logging configuration will be used | |
/// </summary> | |
/// <param name="model"></param> | |
public virtual void Post(SlackModel.WebHook model = null) | |
{ | |
var slackModel = model; | |
if (slackModel == null) | |
{ | |
slackModel = new SlackModel.WebHook | |
{ | |
Username = _config("Slack.WebHook.Username"), | |
UserMarkDown = Convert.ToBoolean(_config("Slack.WebHook.UseMarkDown")), | |
Channel = _config("Slack.WebHook.Channel"), | |
IconEmoji = _config("Slack.WebHook.Emoji"), | |
Text = string.Format("{0}\n\n{1}", _config("Slack.WebHook.Greeting"), _message) | |
}; | |
} | |
try | |
{ | |
// Avoid slack rate limiting by only posting once every n minutes | |
var cache = MemoryCache.Default; | |
var key = string.Format("{0}-{1}", slackModel.Channel, slackModel.Text.Substring(0, 20)); | |
var expires = DateTime.Now.AddMinutes(int.Parse(_config("Slack.WebHook.CacheMinutes"))); | |
if (cache[key] == null) | |
{ | |
cache.Add(key, slackModel.Text, expires); | |
_slack.ExecutePost(slackModel); | |
} | |
} | |
catch (Exception ex) | |
{ | |
// logit | |
// An error with Slack logging has occurred | |
} | |
} | |
} | |
// call example | |
var Func<string, string> GetString = (config) => return ... // return web config or the like... | |
new SlackWebHook(slack, "some message", GetString).Post(); // can also pass in an overiding model to Post() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment