Skip to content

Instantly share code, notes, and snippets.

@michaelbramwell
Created June 14, 2016 00: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 michaelbramwell/2ed8094a9c00369806f185b2c775d320 to your computer and use it in GitHub Desktop.
Save michaelbramwell/2ed8094a9c00369806f185b2c775d320 to your computer and use it in GitHub Desktop.
Simple Slack WebHook Client
// 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