Example #1
0
 protected override async Task Send(NotificationMessage model, MattermostNotificationSettings settings)
 {
     try
     {
         var body = new MattermostMessage
         {
             Username    = string.IsNullOrEmpty(settings.Username) ? "Ombi" : settings.Username,
             Channel     = settings.Channel,
             Text        = model.Message,
             IconUrl     = settings.IconUrl,
             Attachments = new List <MattermostAttachment>
             {
                 new MattermostAttachment
                 {
                     Title    = model.Other.ContainsKey("title") ? model.Other["title"] : string.Empty,
                     ImageUrl = model.Other.ContainsKey("image") ? model.Other["image"] : string.Empty,
                 }
             }
         };
         await Api.PushAsync(settings.WebhookUrl, body);
     }
     catch (Exception e)
     {
         Logger.LogError(LoggingEvents.MattermostNotification, e, "Failed to send Mattermost Notification");
     }
 }
Example #2
0
        public static async Task PostToMattermost(MattermostMessage message)
        {
            if (message.Channel == null)
            {
                message.Channel = _config.BotChannelDefault;
            }
            if (message.Username == null)
            {
                message.Username = _config.BotNameDefault;
            }
            if (message.IconUrl == null)
            {
                message.IconUrl = new Uri(_config.BotImageDefault);
            }
            var mc = new MatterhookClient(_config.MattermostWebhookUrl);

            var response = await mc.PostAsync(message);

            if (response == null || response.StatusCode != HttpStatusCode.OK)
            {
                throw new Exception(response != null
                    ? $"Unable to post to Mattermost.{response.StatusCode}"
                    : $"Unable to post to Mattermost.");
            }
        }
        public static void PostBasicMessage(Config config)
        {
            var client  = new MatterhookClient(config.incomingWebHookUrl);
            var message = new MattermostMessage
            {
                Text     = "Hello, I was posted using [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)",
                Channel  = config.testChannel,
                Username = "******"
            };

            Task.WaitAll(client.PostAsync(message));
        }
        public void BasicMessage()
        {
            var message = new MattermostMessage
            {
                Text     = "Hello, I was posted using [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)",
                Channel  = "testChannel",
                Username = "******"
            };
            var payload  = message.SerializeToJson();
            var expected = GetExpectedJson(nameof(BasicMessage));

            Assert.Equal(payload, expected);
        }
        public static void PostBasicMessageWithCard(Config config)
        {
            var client  = new MatterhookClient(config.incomingWebHookUrl);
            var message = new MattermostMessage
            {
                Text     = "Hello, I was posted using [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)",
                Channel  = config.testChannel,
                Username = "******",
                Props    = new MattermostProps()
                {
                    Card = "**THIS IS A CARD**\n\nIt came from [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)"
                }
            };

            Task.WaitAll(client.PostAsync(message));
        }
Example #6
0
        private static MattermostMessage BaseMessageForRepo(string repoName)
        {
            var mmc = Util.GetMattermostDetails(_config.DefaultMattermostConfig, _config.RepoList, repoName);

            //set matterHook Client to correct webhook.
            _matterHook = new MatterhookClient.MatterhookClient(mmc.WebhookUrl);

            var retVal = new MattermostMessage
            {
                Channel  = mmc.Channel,
                Username = mmc.Username,
                IconUrl  = mmc.IconUrl != null ? new Uri(mmc.IconUrl) : null
            };

            return(retVal);
        }
        public void BasicMessageWithCard()
        {
            var message = new MattermostMessage
            {
                Text     = "Hello, I was posted using [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)",
                Channel  = "testChannel",
                Username = "******",
                Props    = new MattermostProps()
                {
                    Card = "**THIS IS A CARD**\n\nIt came from [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)"
                }
            };
            var payload  = message.SerializeToJson();
            var expected = GetExpectedJson(nameof(BasicMessageWithCard));

            Assert.Equal(payload, expected);
        }
        public void ButtonsMessage()
        {
            var message = new MattermostMessage
            {
                Text     = "Message Text Example",
                Channel  = "testChannel",
                Username = "******",
                IconUrl  =
                    "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Robot_icon.svg/2000px-Robot_icon.svg.png",
                Attachments = new List <MattermostAttachment>
                {
                    new MattermostAttachment
                    {
                        Text    = "Attachment Text Example",
                        Actions = new List <IMattermostAction>
                        {
                            new MattermostAction
                            {
                                Name        = "Merge",
                                Integration = new MattermostIntegration("https://notarealoutgoingwebhook.justfortests",
                                                                        new Dictionary <string, object>
                                {
                                    { "pr", 1234 },
                                    { "action", "merge" }
                                })
                            },
                            new MattermostAction
                            {
                                Name        = "Notify",
                                Integration = new MattermostIntegration("https://notarealoutgoingwebhook.justfortests",
                                                                        new Dictionary <string, object>
                                {
                                    { "text", "code was pushed." }
                                })
                            }
                        }
                    }
                }
            };

            var payload  = message.SerializeToJson();
            var expected = GetExpectedJson(nameof(ButtonsMessage));

            Assert.Equal(payload, expected);
        }
        public void MenuMessage()
        {
            var message = new MattermostMessage
            {
                Text =
                    "This is a menu message posted using [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)",
                Channel  = "testChannel",
                Username = "******",
                IconUrl  =
                    "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Robot_icon.svg/2000px-Robot_icon.svg.png",

                Attachments = new List <MattermostAttachment>
                {
                    new MattermostAttachment
                    {
                        Pretext = "This is optional pretext that shows above the attachment.",
                        Text    = "This is the text of the attachment. ",
                        Actions = new List <IMattermostAction>
                        {
                            new MattermostMessageMenu
                            {
                                Integration = new MattermostIntegration("https://notarealoutgoingwebhook.justfortests",
                                                                        new Dictionary <string, object>
                                {
                                    { "text", "Some data to send always." }
                                }),
                                Name    = "Test",
                                Options = new List <MessageMenuOption>
                                {
                                    new MessageMenuOption("Option1", "value1"),
                                    new MessageMenuOption("Option2", "value2"),
                                    new MessageMenuOption("Option3", "value3")
                                }
                            }
                        }
                    }
                }
            };

            var payload  = message.SerializeToJson();
            var expected = GetExpectedJson(nameof(MenuMessage));

            Assert.Equal(payload, expected);
        }
        public static void PostButtonsMessage(Config config)
        {
            var client  = new MatterhookClient(config.incomingWebHookUrl);
            var message = new MattermostMessage
            {
                Text     = "Message Text Example",
                Channel  = config.testChannel,
                Username = "******",
                IconUrl  =
                    "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Robot_icon.svg/2000px-Robot_icon.svg.png",
                Attachments = new List <MattermostAttachment>
                {
                    new MattermostAttachment
                    {
                        Text    = "Attachment Text Example",
                        Actions = new List <IMattermostAction>
                        {
                            new MattermostAction
                            {
                                Name        = "Merge",
                                Integration = new MattermostIntegration(config.outgoingWebHookUrl,
                                                                        new Dictionary <string, object>
                                {
                                    { "pr", 1234 },
                                    { "action", "merge" }
                                })
                            },
                            new MattermostAction
                            {
                                Name        = "Notify",
                                Integration = new MattermostIntegration(config.outgoingWebHookUrl,
                                                                        new Dictionary <string, object>
                                {
                                    { "text", "code was pushed." }
                                })
                            }
                        }
                    }
                }
            };

            Task.WaitAll(client.PostAsync(message));
        }
        public static void PostMenuMessage(Config config)
        {
            var client  = new MatterhookClient(config.incomingWebHookUrl);
            var message = new MattermostMessage
            {
                Text =
                    "This is a menu message posted using [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)",
                Channel  = config.testChannel,
                Username = "******",
                IconUrl  =
                    "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Robot_icon.svg/2000px-Robot_icon.svg.png",

                Attachments = new List <MattermostAttachment>
                {
                    new MattermostAttachment
                    {
                        Pretext = "This is optional pretext that shows above the attachment.",
                        Text    = "This is the text of the attachment. ",
                        Actions = new List <IMattermostAction>
                        {
                            new MattermostMessageMenu
                            {
                                Integration = new MattermostIntegration(config.outgoingWebHookUrl,
                                                                        new Dictionary <string, object>
                                {
                                    { "text", "Some data to send always." }
                                }),
                                Name    = "Test",
                                Options = new List <MessageMenuOption>
                                {
                                    new MessageMenuOption("Option1", "value1"),
                                    new MessageMenuOption("Option2", "value2"),
                                    new MessageMenuOption("Option3", "value3")
                                }
                            }
                        }
                    }
                }
            };

            Task.WaitAll(client.PostAsync(message));
        }
        public void ChannelsMenuMessage()
        {
            var message = new MattermostMessage
            {
                Text =
                    "This is a message menu with channels source posted using [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)",
                Channel  = "testChannel",
                Username = "******",
                IconUrl  =
                    "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Robot_icon.svg/2000px-Robot_icon.svg.png",

                Attachments = new List <MattermostAttachment>
                {
                    new MattermostAttachment
                    {
                        Pretext = "This is optional pretext that shows above the attachment.",
                        Text    = "This is the text of the attachment. ",
                        Actions = new List <IMattermostAction>
                        {
                            new MattermostMessageMenuChannels
                            {
                                Name        = "channels",
                                Integration = new MattermostIntegration("https://notarealoutgoingwebhook.justfortests",
                                                                        new Dictionary <string, object>
                                {
                                    { "active", "false" }
                                })
                            }
                        }
                    }
                }
            };

            var payload  = message.SerializeToJson();
            var expected = GetExpectedJson(nameof(ChannelsMenuMessage));

            Assert.Equal(payload, expected);
        }
Example #13
0
        private static MattermostMessage MattermostMessage(RssFeed rssFeedConfig, string title, string link, string attText, string author)
        {
            var converter = new Converter();

            var message = new MattermostMessage
            {
                Channel     = rssFeedConfig.BotChannelOverride == "" ? null : rssFeedConfig.BotChannelOverride,
                Username    = rssFeedConfig.BotNameOverride == "" ? null : rssFeedConfig.BotNameOverride,
                IconUrl     = rssFeedConfig.BotImageOverride == "" ? null : new Uri(rssFeedConfig.BotImageOverride),
                Attachments = new List <MattermostAttachment>
                {
                    new MattermostAttachment
                    {
                        Pretext    = rssFeedConfig.FeedPretext,
                        Title      = title ?? "",
                        TitleLink  = link == null ? null : new Uri(link),
                        Text       = converter.Convert(attText),
                        AuthorName = author
                    }
                }
            };

            return(message);
        }
        public static void PostChannelsMenuMessage(Config config)
        {
            var client  = new MatterhookClient(config.incomingWebHookUrl);
            var message = new MattermostMessage
            {
                Text =
                    "This is a message menu with channels source posted using [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)",
                Channel  = config.testChannel,
                Username = "******",
                IconUrl  =
                    "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Robot_icon.svg/2000px-Robot_icon.svg.png",

                Attachments = new List <MattermostAttachment>
                {
                    new MattermostAttachment
                    {
                        Pretext = "This is optional pretext that shows above the attachment.",
                        Text    = "This is the text of the attachment. ",
                        Actions = new List <IMattermostAction>
                        {
                            new MattermostMessageMenuChannels
                            {
                                Name        = "channels",
                                Integration = new MattermostIntegration(config.outgoingWebHookUrl,
                                                                        new Dictionary <string, object>
                                {
                                    { "active", "false" }
                                })
                            }
                        }
                    }
                }
            };

            Task.WaitAll(client.PostAsync(message));
        }
Example #15
0
        public async Task <IActionResult> Receive()
        {
            _matterhook = new MatterhookClient(_config.MmConfig.WebhookUrl);
            try
            {
                GhWebhook hook;
                try
                {
                    hook = new GhWebhook(Request, _config.Secret); //Signature validation has been moved to GithubWebhookLibrary
                }
                catch (Exception e)
                {
                    return(StatusCode(400, e.Message));
                }

                var message = new MattermostMessage
                {
                    Channel  = _config.MmConfig.Channel,
                    Username = _config.MmConfig.Username,
                    IconUrl  = _config.MmConfig.IconUrl != null ? _config.MmConfig.IconUrl : null
                };

                switch (hook.Event)
                {
                case PullRequestEvent.EventString:
                {
                    var pr = (PullRequestEvent)hook.PayloadObject;

                    if (pr.Action == "closed")
                    {
                        if (pr.PullRequest.Merged != null && (bool)pr.PullRequest.Merged)
                        {
                            var user = pr.PullRequest.User.Login;

                            if (_config.IgnoredUsers_Detailed == null)
                            {
                                _config.IgnoredUsers_Detailed = new List <Code.IgnoredUser>();
                            }

                            if (_config.IgnoredUsers_Detailed.Exists(x => x.UserName == user))
                            {
                                return(StatusCode(200, $"{user} is already in my list!"));
                            }

                            message.Text += "#users-first-contribution\n";

                            var usrMd = $"[{user}]({pr.PullRequest.User.HtmlUrl})";

                            if (_config.CelebrationEmoji != null)
                            {
                                message.Text += $"{_config.CelebrationEmoji} ";
                            }

                            message.Text += $"A User has had a pull request merged for the first time!";

                            if (_config.CelebrationEmoji != null)
                            {
                                message.Text += $" {_config.CelebrationEmoji}";
                            }

                            message.Text += $"\n\nUser: {usrMd}\nPull: {pr.PullRequest.HtmlUrl}";

                            if (_config.CustomString != null)
                            {
                                message.Text += $"\n\n {_config.CustomString}";
                            }

                            var response = await _matterhook.PostAsync(message);

                            if (response == null || response.StatusCode != HttpStatusCode.OK)
                            {
                                return(StatusCode(500, response != null
                                            ? $"Unable to post to Mattermost: {response.StatusCode}"
                                            : "Unable to post to Mattermost"));
                            }

                            _config.IgnoredUsers_Detailed.Add(new Code.IgnoredUser {
                                    UserName         = user,
                                    PullRequestUrl   = pr.PullRequest.HtmlUrl,
                                    ContributionDate = $"{pr.PullRequest.ClosedAt:dd MMMM yyyy HH:mm:ss}"
                                });
                            _config.Save("/config/config.json");

                            return(StatusCode(200, "Succesfully posted to Mattermost"));
                        }
                    }
Example #16
0
        internal static async Task PeriodicRssAsync(TimeSpan interval, List <RssFeed> rssFeeds)
        {
            while (true)
            {
                foreach (var rssFeedConfig in rssFeeds)
                {
                    var sbOut = new StringBuilder();
                    sbOut.Append($"\n{DateTime.Now}\nFetching RSS URL: {rssFeedConfig.Url}");

                    Feed newFeed;

                    //Get Feed from URL
                    try
                    {
                        newFeed = await FeedReader.ReadAsync(rssFeedConfig.Url);
                    }
                    catch (Exception e)
                    {
                        sbOut.Append($"\n Unable to get newFeed. Exception: {e.Message}");
                        Console.WriteLine(sbOut.ToString());
                        continue;
                    }

                    sbOut.Append($"\nFeed Title: {newFeed.Title}");

                    var itemCount = newFeed.Items.Count;
                    var procCount = 0;

                    //Fallback mode is for feeds that don't properly use published date.
                    //If we're in fallback mode, then check for previously saved copy of feed, load it into memory and then overwrite it with newest copy
                    Feed oldFeed = null;
                    if (rssFeedConfig.FallbackMode)
                    {
                        var filename = $"/config/{newFeed.Title.Replace(" ", "_")}.xml";

                        sbOut.Append($"\nFallback Mode Enabled, checking for {filename}");
                        if (System.IO.File.Exists(filename))
                        {
                            sbOut.Append($"\nLoading old feed from {filename}");
                            oldFeed = FeedReader.ReadFromFile(filename);
                        }

                        sbOut.Append($"\nWriting new feed to {filename}");
                        System.IO.File.WriteAllText(filename, newFeed.OriginalDocument);
                    }

                    //Loop through new items just downloaded
                    foreach (var newFeedItem in newFeed.Items.OrderBy(x => x.PublishingDate))
                    {
                        //if we're in fallback mode and we have an old feed, does the new item exist in that?
                        IEnumerable <BaseFeedItem> dupeItems = null;
                        if (oldFeed != null)
                        {
                            dupeItems = oldFeed.SpecificFeed.Items.Where(x => x.Title == newFeedItem.Title);
                        }

                        if (rssFeedConfig.FallbackMode && (dupeItems != null && dupeItems.Any()))
                        {
                            continue;                                                                     //Item exists in old file
                        }
                        if (!rssFeedConfig.FallbackMode && (newFeedItem.PublishingDate <= rssFeedConfig.LastProcessedItem || newFeedItem.PublishingDate == null))
                        {
                            continue;                                                                                                                                       // Item was previously processed or has no published date
                        }
                        var content          = "";
                        MattermostMessage mm = null;
                        switch (newFeed.Type)
                        {
                        case FeedType.Atom:
                            var tmpAf = (AtomFeedItem)newFeedItem.SpecificItem;
                            content = !rssFeedConfig.IncludeContent || tmpAf.Content == null
                                        ? (tmpAf.Summary != null
                                        ? (tmpAf.Summary.Length < 500 ? tmpAf.Summary : "")
                                        : "")
                                    : tmpAf.Content;
                            //content = rssFeedConfig.IncludeContent ? tmpAf.Content ?? tmpAf.Summary ?? "": tmpAf.Summary ?? "";

                            var link = tmpAf.Links.FirstOrDefault(x => x.Relation == "alternate");
                            var url  = link == null ? tmpAf.Link : link.Href;

                            mm = MattermostMessage(rssFeedConfig, tmpAf.Title, url, content,
                                                   tmpAf.Author.Name);
                            mm.Text = tmpAf.Title;
                            break;

                        case FeedType.Rss_0_91:
                            break;

                        case FeedType.Rss_0_92:
                            break;

                        case FeedType.Rss_1_0:
                            break;

                        case FeedType.Rss_2_0:
                            var tmpR2 = (Rss20FeedItem)newFeedItem.SpecificItem;
                            content = !rssFeedConfig.IncludeContent || tmpR2.Content == null
                                    ? (tmpR2.Description != null
                                        ? (tmpR2.Description.Length < 500 ? tmpR2.Description : "")
                                        : "")
                                    : tmpR2.Content;
                            mm = MattermostMessage(rssFeedConfig, tmpR2.Title, tmpR2.Link, content,
                                                   tmpR2.Author);
                            break;

                        case FeedType.Rss:
                            break;

                        case FeedType.Unknown:
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }

                        if (mm == null)
                        {
                            continue;
                        }

                        await Program.PostToMattermost(mm);

                        if (!rssFeedConfig.FallbackMode)
                        {
                            rssFeedConfig.LastProcessedItem = newFeedItem.PublishingDate;
                        }
                        procCount++;
                    }

                    var tmp = rssFeedConfig.FallbackMode
                        ? "exist in file from previous run"
                        : "previously processed or have no publish date";
                    sbOut.Append($"\nProcessed {procCount}/{itemCount} items. ({itemCount - procCount} {tmp})");

                    Console.WriteLine(sbOut.ToString());
                }
                //update config file with lastprocesed date
                Program.SaveConfigSection(rssFeeds);
                await Task.Delay(interval).ConfigureAwait(false);
            }
        }
Example #17
0
        public async Task <IActionResult> Receive()
        {
            var stuffToLog = new List <string>();

            try
            {
                string payloadText;
                //Generate DiscourseHook object for easier reading
                stuffToLog.Add($"DockerHub Hook received: {DateTime.Now}");

                Request.Headers.TryGetValue("X-Request-Id", out StringValues requestId);
                stuffToLog.Add($"Hook Id: {requestId}");
                using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
                {
                    payloadText = await reader.ReadToEndAsync().ConfigureAwait(false);
                }

                //No fancy checksumming on this hook. I'll keep an eye on it in future...
                var dockerhubHook = new DockerHubHook(payloadText);

                var mm = Util.GetMattermostDetails(_config.DefaultMattermostConfig,
                                                   _config.RepoList, dockerhubHook.payload.Repository.RepoName);

                var matterHook = new MatterhookClient.MatterhookClient(mm.WebhookUrl);

                var reponame = dockerhubHook.payload.Repository.RepoName;
                var repoMd   = $"[{reponame}]({dockerhubHook.payload.Repository.RepoUrl})";

                var msg = new MattermostMessage
                {
                    Channel  = mm.Channel,
                    Username = mm.Username,
                    IconUrl  = mm.IconUrl != null ? new Uri(mm.IconUrl) : null,
                    Text     = $"New image built and pushed to {repoMd} with tag `{dockerhubHook.payload.PushData.Tag}`"
                };

                stuffToLog.Add(msg.Text);

                var response = await matterHook.PostAsync(msg);

                if (response == null || response.StatusCode != HttpStatusCode.OK)
                {
                    stuffToLog.Add(response != null
                        ? $"Unable to post to Mattermost {response.StatusCode}"
                        : "Unable to post to Mattermost");

                    return(StatusCode(500, response != null
                        ? $"Unable to post to Mattermost: {response.StatusCode}"
                        : "Unable to post to Mattermost"));
                }

                if (!_config.LogOnlyErrors)
                {
                    stuffToLog.Add(msg.Text);
                    stuffToLog.Add("Succesfully posted to Mattermost");
                    Util.LogList(stuffToLog);
                }

                return(StatusCode(200, "Succesfully posted to Mattermost"));
            }
            catch (Exception e)
            {
                stuffToLog.Add(e.Message);
                Util.LogList(stuffToLog);
                return(StatusCode(500, e.Message));
            }
        }
Example #18
0
        public async Task <IActionResult> Receive()
        {
            var stuffToLog = new List <string>();

            try
            {
                string payloadText;

                //Generate GithubHook Object
                //Generate DiscourseHook object for easier reading

                stuffToLog.Add($"Github Hook received: {DateTime.Now}");

                Request.Headers.TryGetValue("X-GitHub-Event", out var strEvent);
                Request.Headers.TryGetValue("X-Hub-Signature", out var signature);
                Request.Headers.TryGetValue("X-GitHub-Delivery", out var delivery);
                Request.Headers.TryGetValue("Content-type", out var content);

                stuffToLog.Add($"Hook Id: {delivery}");
                stuffToLog.Add($"X-Github-Event: {strEvent}");

                if (content != "application/json")
                {
                    const string error = "Invalid content type. Expected application/json";
                    stuffToLog.Add(error);
                    Util.LogList(stuffToLog);
                    return(StatusCode(400, error));
                }

                using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
                {
                    payloadText = await reader.ReadToEndAsync().ConfigureAwait(false);
                }

                if (_config.DebugSavePayloads)
                {
                    System.IO.File.WriteAllText($"/config/payloads/{delivery}", $"Signature: {signature}\n");
                    System.IO.File.AppendAllText($"/config/payloads/{delivery}", $"Event: {strEvent}\nPayload:\n");
                    System.IO.File.AppendAllText($"/config/payloads/{delivery}", payloadText);
                }


                var calcSig = Util.CalculateSignature(payloadText, signature, _config.Secret, "sha1=");


                if (signature == calcSig)
                {
                    var githubHook = new GithubHook(strEvent, signature, delivery, payloadText);

                    HttpResponseMessage response = null;
                    MattermostMessage   message  = null;
                    switch (githubHook.Event)
                    {
                    case "pull_request":
                        message  = GetMessagePullRequest((PullRequestEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;

                    case "issues":
                        message  = GetMessageIssues((IssuesEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;

                    case "issue_comment":
                        message  = GetMessageIssueComment((IssueCommentEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;

                    case "repository":
                        message  = GetMessageRepository((RepositoryEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;

                    case "create":
                        message  = GetMessageCreate((CreateEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;

                    case "delete":
                        message  = GetMessageDelete((DeleteEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;

                    case "pull_request_review":
                        message  = GetMessagePullRequestReview((PullRequestReviewEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;

                    case "pull_request_review_comment":
                        message = GetMessagePullRequestReviewComment(
                            (PullRequestReviewCommentEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;

                    case "push":
                        message  = GetMessagePush((PushEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;

                    case "commit_comment":
                        message  = GetMessageCommitComment((CommitCommentEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;

                    case "status":
                        message  = GetMessageStatus((StatusEvent)githubHook.Payload);
                        response = await _matterHook.PostAsync(message);

                        break;
                    }

                    if (response == null || response.StatusCode != HttpStatusCode.OK)
                    {
                        stuffToLog.Add(response != null
                            ? $"Unable to post to Mattermost {response.StatusCode}"
                            : "Unable to post to Mattermost");

                        return(StatusCode(500, response != null
                            ? $"Unable to post to Mattermost: {response.StatusCode}"
                            : "Unable to post to Mattermost"));
                    }

                    if (!_config.LogOnlyErrors)
                    {
                        if (message != null)
                        {
                            stuffToLog.Add(message.Text);
                        }
                        stuffToLog.Add("Succesfully posted to Mattermost");
                        Util.LogList(stuffToLog);
                    }

                    return(StatusCode(200, "Succesfully posted to Mattermost"));
                }
                stuffToLog.Add("Invalid Signature!");
                stuffToLog.Add($"Expected: {signature}");
                stuffToLog.Add($"Calculated: {calcSig}");
                Util.LogList(stuffToLog);
                return(StatusCode(401, "Invalid signature. Please check your secret values in the config and on Github."));
            }
            catch (Exception e)
            {
                stuffToLog.Add(e.Message);
                Util.LogList(stuffToLog);
                return(StatusCode(e is NotImplementedException ? 501 : e is WarningException ? 202 : 500, e.Message));
            }
        }
        public static void PostAdvancedMessage(Config config)
        {
            var client  = new MatterhookClient(config.incomingWebHookUrl);
            var message = new MattermostMessage
            {
                Text     = "Hello, I was posted using [Matterhook.NET.MatterhookClient](https://github.com/promofaux/Matterhook.NET.MatterhookClient)",
                Channel  = config.testChannel,
                Username = "******",
                IconUrl  =
                    "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Robot_icon.svg/2000px-Robot_icon.svg.png",

                Attachments = new List <MattermostAttachment>
                {
                    new MattermostAttachment
                    {
                        Fallback = "test",
                        Color    = "#FF8000",
                        Pretext  = "This is optional pretext that shows above the attachment.",
                        Text     =
                            "This is the text of the attachment. It should appear just above an image of the Mattermost logo. The left border of the attachment should be colored orange, and below the image it should include additional fields that are formatted in columns. At the top of the attachment, there should be an author name followed by a bolded title. Both the author name and the title should be hyperlinks.",
                        AuthorName = "Mattermost",
                        AuthorIcon = "http://www.mattermost.org/wp-content/uploads/2016/04/icon_WS.png",
                        AuthorLink = "http://www.mattermost.org/",
                        Title      = "Example Attachment",
                        TitleLink  = "http://docs.mattermost.com/developer/message-attachments.html",

                        Fields = new List <MattermostField>
                        {
                            new MattermostField
                            {
                                Short = false,
                                Title = "Long Field.",
                                Value =
                                    "Testing with a very long piece of text that will take up the whole width of the table. And then some more text to make it extra long."
                            },
                            new MattermostField
                            {
                                Short = true,
                                Title = "Column One",
                                Value = "Testing"
                            },
                            new MattermostField
                            {
                                Short = true,
                                Title = "Column Two",
                                Value = "Testing"
                            },
                            new MattermostField
                            {
                                Short = false,
                                Title = "Another Field",
                                Value = "Testing"
                            }
                        },
                        ImageUrl = "http://www.mattermost.org/wp-content/uploads/2016/03/logoHorizontal_WS.png"
                    }
                }
            };

            Task.WaitAll(client.PostAsync(message));
        }
        private MattermostMessage PostCreated(PostPayload payload)
        {
            var p = payload.post;

            if (_config.IgnoredTopicTitles.Contains(p.topic_title))
            {
                throw new WarningException("Post title matches an ignored title");
            }

            if (_config.IgnorePrivateMessages)
            {
                //We're not really doing anything here yet
                //TODO: Revisit in the future
                try
                {
                    JObject.Parse(
                        new WebClient().DownloadString($"{_discourseUrl}/t/{p.topic_id}.json"));
                }
                catch
                {
                    throw new WarningException("Unable to retrieve topic, possibly a PM so we should ignore this.");
                }
            }

            if (p.cooked == "")
            {
                throw new WarningException("Body empty, nothing to post.");
            }


            var retVal = new MattermostMessage
            {
                Channel  = _config.MattermostConfig.Channel,
                IconUrl  = new Uri(_config.MattermostConfig.IconUrl),
                Username = _config.MattermostConfig.Username,


                Attachments = new List <MattermostAttachment>
                {
                    new MattermostAttachment
                    {
                        Fallback   = "New Post in Discourse Topic",
                        Title      = p.topic_title,
                        TitleLink  = new Uri($"{_discourseUrl}/t/{p.topic_id}/{p.post_number}"),
                        Text       = new Converter().Convert(ExpandDiscourseUrls(p.cooked, _discourseUrl)),
                        AuthorName = p.username,
                        AuthorLink = new Uri($"{_discourseUrl}/u/{p.username}"),
                        AuthorIcon = new Uri($"{_discourseUrl}{p.avatar_template.Replace("{size}","16")}")
                    }
                }
            };

            if (p.post_number.ToString() == "1")
            {
                retVal.Text = "#NewTopic\n";
            }

            retVal.Text += $"#{p.topic_slug}";

            return(retVal);
        }
        public async Task <IActionResult> Receive()
        {
            var stuffToLog = new List <string>();

            try
            {
                string payloadText;
                //Generate DiscourseHook object for easier reading
                stuffToLog.Add($"Discourse Hook received: {DateTime.Now}");

                Request.Headers.TryGetValue("X-Discourse-Event-Id", out StringValues eventId);
                Request.Headers.TryGetValue("X-Discourse-Event-Type", out StringValues eventType);
                Request.Headers.TryGetValue("X-Discourse-Event", out StringValues eventName);
                Request.Headers.TryGetValue("X-Discourse-Event-Signature", out StringValues signature);
                Request.Headers.TryGetValue("X-Discourse-Instance", out StringValues discourseUrl);
                Request.Headers.TryGetValue("Content-type", out var content);

                _discourseUrl = discourseUrl;

                stuffToLog.Add($"Hook Id: {eventId}");

                if (content != "application/json")
                {
                    const string error = "Invalid content type. Expected application/json";
                    stuffToLog.Add(error);
                    Util.LogList(stuffToLog);
                    return(StatusCode(400, error));
                }

                using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
                {
                    payloadText = await reader.ReadToEndAsync().ConfigureAwait(false);
                }

                var calcSig = Util.CalculateSignature(payloadText, signature, _config.Secret, "sha256=");


                if (signature == calcSig)
                {
                    var discourseHook            = new DiscourseHook(eventId, eventType, eventName, signature, payloadText);
                    var matterHook               = new MatterhookClient.MatterhookClient(_config.MattermostConfig.WebhookUrl);
                    HttpResponseMessage response = null;
                    MattermostMessage   message  = null;
                    if (discourseHook.EventName == "post_created")
                    {
                        message  = PostCreated((PostPayload)discourseHook.Payload);
                        response = await matterHook.PostAsync(message);
                    }

                    if (response == null || response.StatusCode != HttpStatusCode.OK)
                    {
                        stuffToLog.Add(response != null
                            ? $"Unable to post to Mattermost {response.StatusCode}"
                            : "Unable to post to Mattermost");

                        return(StatusCode(500, response != null
                            ? $"Unable to post to Mattermost: {response.StatusCode}"
                            : "Unable to post to Mattermost"));
                    }

                    if (!_config.LogOnlyErrors)
                    {
                        if (message != null)
                        {
                            stuffToLog.Add(message.Text);
                        }
                        stuffToLog.Add("Succesfully posted to Mattermost");
                        Util.LogList(stuffToLog);
                    }

                    return(StatusCode(200, "Succesfully posted to Mattermost"));
                }

                stuffToLog.Add("Invalid Signature!");
                stuffToLog.Add($"Expected: {signature}");
                stuffToLog.Add($"Calculated: {calcSig}");
                Util.LogList(stuffToLog);
                return(StatusCode(401, "Invalid signature. Please check your secret values in the config and Discourse"));
            }
            catch (Exception e)
            {
                stuffToLog.Add(e.Message);
                Util.LogList(stuffToLog);
                return(StatusCode(e is NotImplementedException ? 501 : e is WarningException? 202: 500, e.Message));
            }
        }
        public static async Task PeriodicRedditAsync(TimeSpan interval, List <RedditJsonFeed> redditFeeds)
        {
            while (true)
            {
                foreach (var feed in redditFeeds)
                {
                    using (var wc = new WebClient())
                    {
                        var outputString = new StringBuilder();
                        outputString.Append($"\n{DateTime.Now}\nFetching Reddit URL: {feed.Url}");

                        string json;
                        try
                        {
                            json = wc.DownloadString(feed.Url);
                        }
                        catch (Exception e)
                        {
                            outputString.Append($"\nUnable to get feed, exception: {e.Message}");
                            Console.WriteLine(outputString.ToString());
                            return;
                        }

                        //only get items we have not already processed


                        var items = JsonConvert.DeserializeObject <RedditJson>(json).RedditJsonData.RedditJsonChildren
                                    .Where(y => y.Data.Created > feed.LastProcessedItem).OrderBy(x => x.Data.Created);

                        var itemCount = items.Count();
                        var procCount = 0;

                        foreach (var item in items)
                        {
                            var message = new MattermostMessage
                            {
                                Channel  = feed.BotChannelOverride == "" ? null : feed.BotChannelOverride,
                                Username = feed.BotNameOverride == "" ? null : feed.BotNameOverride,
                                IconUrl  = feed.BotImageOverride == "" ? null : new Uri(feed.BotImageOverride)
                            };

                            if (item.Kind == "t3")
                            {
                                var content = item.Data.PostHint == "link" ? $"Linked Content: {item.Data.Url}" : item.Data.Selftext;

                                message.Attachments = new List <MattermostAttachment>
                                {
                                    new MattermostAttachment
                                    {
                                        AuthorName = $"/u/{item.Data.Author}",
                                        AuthorLink = new Uri($"https://reddit.com/u/{item.Data.Author}"),
                                        Title      = item.Data.Title,
                                        TitleLink  = new Uri($"https://reddit.com{item.Data.Permalink}"),
                                        Text       = content,
                                        Pretext    = feed.FeedPretext
                                    }
                                };
                                message.Text =
                                    $"#{Regex.Replace(item.Data.Title.Replace(" ", "-"), "[^0-9a-zA-Z-]+", "")}";
                            }
                            else if (item.Kind == "t4")
                            {
                                message.Attachments = new List <MattermostAttachment>
                                {
                                    new MattermostAttachment
                                    {
                                        AuthorName = $"/u/{item.Data.Author}",
                                        AuthorLink = new Uri($"https://reddit.com/u/{item.Data.Author}"),
                                        Title      = item.Data.Subject,
                                        TitleLink  = new Uri($"https://reddit.com{item.Data.Permalink}"),
                                        Text       =
                                            item.Data.Body.Replace("](/r/",
                                                                   "](https://reddit.com/r/"), //expand /r/ markdown links
                                        Pretext = feed.FeedPretext
                                    }
                                };
                            }


                            try
                            {
                                await Program.PostToMattermost(message);

                                feed.LastProcessedItem = item.Data.Created;
                                procCount++;
                            }
                            catch (Exception e)
                            {
                                outputString.Append($"\nException: {e.Message}");
                            }
                        }

                        outputString.Append($"\nProcessed {procCount}/{itemCount} items.");
                        Console.WriteLine(outputString.ToString());
                    }
                }
                Program.SaveConfigSection(redditFeeds);
                await Task.Delay(interval).ConfigureAwait(false);
            }
        }
Example #23
0
 public async Task PushAsync(string webhook, MattermostMessage message)
 {
     var client = new MatterhookClient(webhook);
     await client.PostAsync(_api, message);
 }