Slack – HoNoSoFt https://blog.honosoft.com Blog & Roll Fri, 24 May 2019 12:48:29 +0000 en-CA hourly 1 https://wordpress.org/?v=6.8.10 https://blog.honosoft.com/wp-content/uploads/2018/06/logo.png Slack – HoNoSoFt https://blog.honosoft.com 32 32 #Slack |> App |> Smee |> My Local App |> #Slack Reply : How to interact when you’re behind Firewall/Proxy https://blog.honosoft.com/2019/05/24/slack-app-smee-my-local-app-slack-reply-how-to-interact-when-youre-behind-firewall-proxy/?utm_source=rss&utm_medium=rss&utm_campaign=slack-app-smee-my-local-app-slack-reply-how-to-interact-when-youre-behind-firewall-proxy https://blog.honosoft.com/2019/05/24/slack-app-smee-my-local-app-slack-reply-how-to-interact-when-youre-behind-firewall-proxy/#respond Fri, 24 May 2019 12:48:27 +0000 https://blog.honosoft.com/?p=562 Continue Reading]]> Introduction

All I wanted to do is simply have a way to connect to my local server on the network and then when receiving a specific request from #Slack. Once received act on it, do a some background work or send reports. This server is obviously not exposed on the internet and reside behind a firewall/proxy. For that reason, I had to be a bit more creative and think out of the box.

In the past I resolved this by using a WebSocket to an Heroku WebSite. It works but it was not perfect. So, I started to look around for a better way to stream a service where I a simple Webhook would be forwarded. In that manner, I could watch a service where it send me back the data. I recently came across Smee.io which use the Server Side Events (SSE) but as a streaming service on the HTTP port. Following is a story of how to make all that working together.

Before going further, I would have loved a solution like
ngrok, but it’s not possible behind a proxy/firewall such as where I work.

Step 1. Grab a new Smee URL

To get the URI, it’s deadly simple. Simply go on Smee.io and then click on create the big button in order to create a new Webhook. Keep the Webhook URL for the next step.

Step 2. Configure the #Slack App/Bot

In that App, we will setup a bot, a hook and a bot for commands.

Configure the App

Open your #Slack page and add an App and if you don’t know how, simply go on https://api.slack.com/ and click on Start Building button and fill the form. It should look like this:

Once you have created your app, you will need to enable “Bot” and give him a name, and then go into the Create a new command page and then add a new command like the following:

Install your app

For that, you go for example in OAuth & Permissions and click install app To Workspace. (Note, you might also have to add a permission File.Upload.User)

You can see the beginning of the token. The 4 first characters indicate what kind of token it is. (Documentation in slack documentation exists for more details)

Step 3. Keep it simple with a sample app in NodeJS or Dotnet Core

Due to some missing implementation in the original repository/server, I’ve added what’s missing in my fork within GitHub. I then use my Heroku account to generate automatically my Docker container with the service. In the future, the issues should be fixed (PR currently waiting to be approved).

The main issue with the Smee.IO website is that it does not yet forward the content if it’s using x-www-form-urlencoded. If you use my branch, for now you will be ok. You can even use it for building your docker service on heroku.

Sample receiving data using NodeJS (index.js + smee-client & express packages)

const SmeeClient = require('smee-client')

/// Smee client (websocket)
const smee = new SmeeClient({
  source: 'https://smee.io/5sFasdasdukH5VQidvpGv', // In case Smee is not updated, please use my repository + an heroku deployment. It is that easy.
  target: 'http://localhost:3000/events',
  logger: console
})
const events = smee.start()
/// WebServer
const express = require('express');
const app = express();
const router = express.Router();

app.use(express.json()) // Instead of body-parser
app.use(express.urlencoded()) // Instead of body-parser
app.use(function(req, res, next) { // Allow CORS if you want.
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

console.log(app)

// from top level path e.g. localhost:3000, this response will be sent
app.get('/', (request, response) => response.send('Hello World'));
app.use('/events', router);

router.post('/', (request, response, next) => {
  console.log(request.body) // Raw data
  response.end();
});

app.listen(3000, () => console.log('Listening on port 3000'));

Sample receiving data using Dotnet Core

NuGet Package: Smee.IO.Client (That library simply do the SSE streaming for smee.io event types for you. So, if you want to use it for different SSE messages types, you will have to adapt the code).

The following code is also available in my Github repo (Demo).

using System;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Smee.IO.Client.ConsoleDemo
{
    class Program
    {
        private static CancellationTokenSource source;

        static async Task Main(string[] args)
        {
            source = new CancellationTokenSource();
            var token = source.Token;

            // This could also be done automatically, but since we expect some developer to test, let's
            // keep it this way.
            Console.WriteLine("Hi there, please get a valid url on https://smee.io/new (or your own server. In case of this demo, I will use my own instance)");
            Console.Write("Please enter a valid URI because no validation will be made: ");
            var smeeUri = new Uri(Console.ReadLine());

            Console.ForegroundColor = ConsoleColor.DarkRed;
            Console.WriteLine(" > Hit CTRL-C in order to stop everything.");
            Console.WriteLine();
            Console.ResetColor();

            var smeeCli = new SmeeClient(smeeUri);
            smeeCli.OnConnect += (sender, a) => Console.WriteLine($"Connected to Smee.io ({smeeUri}){Environment.NewLine}");
            smeeCli.OnDisconnect += (sender, a) => Console.WriteLine($"Disconnected from Smee.io ({smeeUri}){Environment.NewLine}");
            smeeCli.OnMessage += (sender, smeeEvent) =>
            {
                Console.Write("Message received: ");
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.Write(JsonConvert.SerializeObject(smeeEvent)); // This is a typed object.
                Console.ResetColor();
                Console.WriteLine();
                Console.WriteLine();
            };
            smeeCli.OnPing += (sender, a) => Console.WriteLine($"Ping from Smee{Environment.NewLine}");
            smeeCli.OnError += (sender, e) => Console.WriteLine($"Error was raised (Disconnect/Anything else: {e.Message}{Environment.NewLine}");

            Console.CancelKeyPress += (sender, eventArgs) =>
            {
                source.Cancel();
                eventArgs.Cancel = true;
            };

            await smeeCli.StartAsync(token);
            Console.WriteLine("Finish executing. Thank you!");
        }
    }
}

Example of what you can see in Smee.io console

Slack Webhook call (Command)

The command in the previous capture is using a different command, don’t worry. Anything will do.

If the payload is empty, it’s because the content type is application/x-www-form-urlencoded (Current limitation on Smee.io). If you use my branch, as said earlier, you will have the proper data.

We can receive, now let’s send

For this part, you have a few option. I will be using the Dotnet implementation from now on. However, know that you can either use a library or use raw HTTP command using the Slack API. Basically, you will do either HTTP post to a specific URL or to the response_url. The response_url is not something that stays forever. As of now, it stays 30 minutes alive, after that, normally, it won’t be usable. It can be useful to make a small dialog with options that needs to be selected. Here we will now focus to send a simple message back to say “Message received!”.

In Dotnet, but also in NodeJS, some people already have written some libraries (e.g.: SlackAPI). It’s up to you to use them. The following code will be using a raw lazy HTTP post. For that, let’s replace smeeCli.OnMessage += ... by the following (not fully completed, but you get the idea):

smeeCli.OnMessage += (sender, smeeEvent) =>
{
    IncomingMessage msgBody = null;
    if (e.Data.Body != null)
    {
        msgBody = (e.Data.Body as JObject)?.ToObject<IncomingMessage>();
    }

    // If it's for command listener, you could use a strategy pattern.
    // Some code is not in previous block, but you can easily find out what to put in order to make
    // it work.
    _slackHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _slackConfiguration.BotOAuthToken);
    var msg = new
    {
        token = _slackConfiguration.BotOAuthToken,
        channel = msgBody.UserId,
        // response_type = "ephemeral", // See doc.
        text = "Message received!"
    };
    var content = new StringContent(JsonConvert.SerializeObject(msg), Encoding.UTF8, "application/json");
    var result = await _slackHttpClient.PostAsync("chat.postMessage", content).ConfigureAwait(false);
    // https://api.slack.com/methods/im.open/test (open)
    // send message to specific channel...
    // https://api.slack.com/methods/im.close/test (open)
    // Conversation could be created, but for now let's consider no conversation.
    // e.g.: https://api.slack.com/dialogs#select_elements <== create a select box...
};

What’s next?

  • Basically, if you wish, you could also link yourself with Luis.AI, TensorFlow or anything in order to make a Chat Bot more alive and more intelligent.
  • Create some command to interact with your servers
  • Link your slack account with some of your service in order to be notified when some jobs are completed for example.
  • Link/Sync/Send stuff between your #Slack and your MS Team
  • …the sky is the limit…

The limits are actually your limits and how secure you want your stuff to be (as usual).

Conclusion

I hope you’ve enjoyed that article ;). I don’t have much time recently, so it’s hard to write more often.

]]>
https://blog.honosoft.com/2019/05/24/slack-app-smee-my-local-app-slack-reply-how-to-interact-when-youre-behind-firewall-proxy/feed/ 0
Intégration Continue (CI) > GitHub + AppVeyor + SonarQube (cloud) + BadgeIt https://blog.honosoft.com/2018/09/24/integration-continue-ci-github-appveyor-sonarqube-cloud-badgeit/?utm_source=rss&utm_medium=rss&utm_campaign=integration-continue-ci-github-appveyor-sonarqube-cloud-badgeit https://blog.honosoft.com/2018/09/24/integration-continue-ci-github-appveyor-sonarqube-cloud-badgeit/#respond Mon, 24 Sep 2018 13:59:16 +0000 https://blog.honosoft.com/?p=247 Continue Reading]]> Voici un premier article sur de l’intégration continue. Pour ceci, nous allons utiliser tous les outils “gratuit” disponible sur le web. Dans le futur, nous allons sans doute aussi traiter de GitLab. GitLab comprend déjà 2 des points mentionné dans le titre. C’est-à-dire la gestion du code source, le “build” ainsi que le déploiement.

Pour le moment, concentrons nous sur le scénario suivant:

  • GitHub : Gestion de code source
  • AppVeyor : Build automatisé tout particulièrement pour les application .Net, sinon comme alternative, vous pouvez utiliser Travis. Travis est plutôt bien, mais j’ai eu quelques problème par le passé concernant les applications .Net. Peut-être que c’est revenu à la normal depuis le temps.
  • SonarQube (Cloud) : Ici on prend la version cloud, cependant, vous pouvez l’installer sur un serveur local tout dépendant de votre usage.
  • BadgeIt : Projet créé par HoNoSoFt qui à pour but d’utiliser l’API de SonarQube ainsi que Shields.io afin de générer vos badges.
  • #Slack (Optionel) : Envoie des notifications avec Webhook lors de fin de build et d’analyse.

GitHub – Création de votre repo.

Si vous n’avez pas déjà un compte Github, shame on you :). Enfin, je dis ça, mais c’est plutôt pour vous aider à faire les étapes suivantes où vous n’aurez qu’un login ;). Du coup créez votre compte et continuez les étapes.

  1. Une fois connecté, allez sur votre image en haut et cliquez sur “Your repositories”
  2. De là simplement cliquer sur “New” après avoir bien entendu remplis le champ contenant le nom de votre projet.
    • Alternativement, dans le cas où vous êtes très paresseux, simplement dupliquer un projet existant que vous voulez faire le build et ajouter peut-être quelques fonctionnalités, pourquoi pas.
  3. Si vous avez créer votre nouveau repository, veuillez suivres les étapes afin d’ajouter votre code déjà existant. Ce sera d’ailleurs indiqué par défaut sur la page de tout votre nouveau projet.

Une fois complété, ça ressemblera à ce qui suit:

#Slack – Configuration de notification

Dans cet article, nous utiliserons Slack. Cependant, dans la vrai vie, n’importe quel system comportant un Webhook peut être utilisé. Étant donné que Slack est déjà prêt à être utilisé par toutes les applications de cet article, utilisons le. Si vous désirez, vous pouvez choisir un autre outil.

  1. Aller sur le site de #Slack
  2. Créer votre espace, ou bien utiliser un déjà existant
  3. Connectez vous à votre espace (web ou par l’application windows)
  4. Créez vous un channel qui s’appelle par exemple #ContinuousIntegration et invitez vos amis ;). Très utile si vous travaillez à plusieurs sur un projet.
  5. Sur le menu à gauche, vous trouverez une options appelé “Apps”. Appuyez sur ce bouton
  6. Dans la recherche, veuillez indiquer “Webhook” et sélectionnez “Incoming Webhook“
  7. Ajoutez le Webhook et changez la configuration à bon vous semble, cependant veuillez prendre en note le “Webhook URL“. Cet URL est utilisé afin de poussez vos notifications sur votre channel #Slack.

AppVeyor – Création de votre premier build, ou peut-être pas

Peut-être que vous avez déjà quelques build sur cette plateforme. Si c’est le cas, veuillez sauter dans la prochaine section, ou tout simplement lire en diagonale.

Ici on prendra pour acquis que vous allez builder une application .Net Core 2.1. Si vous avez un autre type d’application à bâtir, veuillez changer les choix afin de mieux vous accommoder.

  1. Accéder le site d’AppVeyor
  2. Vous connecter en utilisant votre compte GitHub
  3. Ajouter un projet existant (le bouton est plutôt évident et si vous n’avez pas trouvé, contactez moi je modifierai l’article).
  4. Avant de lancer votre build, vous devez impérativement configurer ce dernier.
    • Si vous n’êtes pas déjà sur votre projet, veuillez y accéder
    • Choisir le menu “Settings” > Onglet “General” sur la gauche (défaut)
      • Validez que le nom de votre projet est bien le bon ainsi que les options suivantes
    • Choisir le menu “Settings” > “Build”
      • Modifiez la configuration à “Release” si votre build est pour les mises en productions
      • Modifiez le “Before build script” et choisissez “CMD”
        • Insérrer “dotnet restore” (Sinon, votre restauration Nuget ne fonctionnera pas).
      • Appuyez sur “Save“
    • Choisir le menu “Settings” > “Environment”
      • Choisir Visual Studio 2017 au lieu du choix par défaut Visual Studio 2015
      • Appuyez sur “Save”
    • Choisir le menu “Settings” > “Notifications”
      • Choisir comme nouvelle notification “Slack“.
        • Insérez votre “Webhook URL” récupéré dans l’étape précédente (#Slack).
        • Choisir les événements désiré (Succès, …)
      • Appuyez sur “Save“
  5. Revenir sur le menu “Latest build”
    1. Lancer le “Build” en appuyant sur “New Build“
    2. Si le résultat est bon ou mauvais, vous devriez recevoir votre notification sur #Slack

Résultat une fois le build complété avec succès (notez le vert sur la gauche)

Résultat sur #Slack

SonarQube (Cloud) – Intégration pour valider votre qualité de code

Pour cette partie, je vais intégrer une partie de l’article AppVeyor+SonarQube disponible sur le site officiel de AppVeyor. Notez que SonarQube Cloud est gratuit pour les projet qui sont “publique” sur “GitHub”.

Important: Avec SonarCloud sous la version gratuite, les résultats seront publique et tout le monde pourra y accéder. Dans la plupart des scénario d’entreprise, ce ne sera pas le cas et vous aurez des soucis pour afficher les badges. Par soucis de sécurité, la prochaine section sera pour vous. Les badges pouvant être généré par votre propre système ou du moins sur votre réseau privé (subnet privé sur azure par exemple). Vous comprenez sans doutes où je veux en venir ;).

  1. Accéder au site de SonarQube Cloud
  2. Connectez-vous avec votre compte Github (pour la simplicité de la chose)
  3. Une fois connecté, veuillez aller sur votre profil (icône en haut à droite) et choisir “My account“
  4. Choisissez le menu “Security” afin de créer un nouveau Token qui sera ensuite utilisé par l’application BadgeIt.
    • Donnez un nom à votre token, e.g. “BadgeIt“
    • Appuyez sur “Generate“
    • Copiez et collez votre Token dans un fichier local sécuritaire ou un endroit afin de ne pas perdre cette information. Elle ne sera accessible qu’une fois, sinon vous devrez régénérer un nouveau Token.
  5. Créer un nouveau projet
  6. À ce moment, vous avez 2 choix, utiliser une nouvelle clé pour pouvoir pousser les résultats ou bien utiliser une clé existante. Je vous conseille ici de créer une clé seulement pour AppVeyor. Du coup, votre clé sera seulement pour cette application et la clé précédemment créé sera utilisé par la section qui suivre (BadgeIt).
    • Notez le nouveau Token
  7. Retour vers AppVeyor pour terminer la configuration du build.

Re-AppVeyor

Retour vers AppVeyor, allons re-configurer les événements de build ainsi que d’ajouter des variables d’environnement.

  1. Retour sur votre Project -> Settings -> Environment
  2. Ajoutez les 3 variables suivantes. Elles seront utilisé pour un script powershell. Ça évitera d’afficher publiquement certaines informations privées.
    • sonar_project_key: Déterminé lors de la création du projet dans SonarCloud. Cette clé doit normalement être unique.
    • solution: Nom de votre solution (peut contenir un “path” et non seulement le nom de la solution. Dans mon cas, c’est à la racine de mon repo. git)
    • sonar_api_key: Créé lors de l’étape précédente. Seulement coller votre valeur ici. N’oubliez pas de sauvegarder une fois que c’est fait ;).

Vous avez enfin les variables d’environnements, maintenant retournons sur la page de configuration du build.

  1. Retour sur votre Project -> Settings -> Build
  2. Allez au bas de la page de configuration et ensuite entrer ce qui suit dans “After build script“. Choisissez PS Core (ou powershell).
    • choco install "msbuild-sonarqube-runner" -y
      
      # Votre-organization vient aussi de SonarCloud. Du coup, veuillez renseigner le champ. Dans un SonarQube normal, vous n'aurez pas besoin de cette configuration.
      # Vous pouvez aussi ajouter cette variable d'environnement en tant que variable globale d'environnement sur AppVeyor
      $cmd = "MSBuild.SonarQube.Runner.exe begin /k:""${env:sonar_project_key}"" /d:sonar.organization=""VOTRE-ORGANISATION"" /d:""sonar.host.url=https://sonarcloud.io"" /d:""sonar.login=${env:sonar_api_key}"""
      Invoke-Expression $cmd
      
      msbuild $env:solution
      $cmd = "MSBuild.SonarQube.Runner.exe end /d:""sonar.login=${env:sonar_api_key}"""
      Invoke-Expression $cmd
    • Notez que le script peut aussi être modifié afin d’ajouter le numéro de version automatiquement et du coup synchronisez vos versions entre Sonar et AppVeyor.
  3. Sauvegarder

Relancer votre build et voilà, au rafraîchissement de la page Sonar vous devriez voir apparaître quelque chose comme ce qui suit:

Mon projet n’est pas parfait, mais ce n’est pas bien grave. Là plupart des “erreurs” sont dû à du HTML/JavaScript ou du code mort créé lors de refactoring récent. Je corrigerai, mais pour le moment ça montre que les chiffres ne sont pas tous à 0 et que ça a bien marché! 😀

BadgeIt – Configuration

Ici vous avez plusieurs choix. Je vous recommande votre environnement locale, mais SI vous ne pouvez pas, tournez vous vers votre hébergement favoris (Google, AWS, Azure, Heroku ou autre). Je vais donner quelques détails pour Azure, cependant ici nous allons nous attarder à la façon Heroku histoire de montrer comment déployer .Net Core 2.1 sous un container.

Azure (WebApp)

Pour ceux qui désire prendre le choix Azure, ce sera trivial:

  • Déploiement dans sur une WebApp ou similaire
  • Affecter les variables d’environnements
    • SonarQubeApi.ApiKey: Votre clée d’API créé lors de l’étape SonarQube (Cloud) et qui porte le nom de BadgeIt.
    • SonarQubeApi.BaseUri: Dans le cas ici présent: “https://sonarcloud.io/api/” ou sinon ce sera votre SonarQube privé.
    • BadgeApi.BaseUri: Par défaut, je vous recommande “https://img.shields.io/badge/”, mais si vous voulez un peu plus d’intimité et de performance, veuillez tout simplement installer le serveur Shields.IO localement. Veuillez vous référer au site Github de Shields.IO afin d’obtenir plus de détails.
  • Démarrer votre WebApp et voilà, vous pourrez suivre un peu plus loin comment utiliser l’API, sinon tout simplement charger la page principale de la WebApp, vous aurez un exemple et vous pourrez tester.

Azure (Docker container)

Veuillez suivre l’article MSDN afin de déployer votre application.

Heroku

Si vous n’avez pas déjà un compte Heroku, créez en un. Vous devrez aussi installer Heroku-Cli, car ce sera à partir de cette application que votre déploiement se fera. Sinon en générale, ce sera plutôt trivial. (Article Heroku à ce sujet)

  • Cloner le repo. HoNoSoFt.BadgeIt.SonarQube
  • Validez que vous avez bien le fichier “Dockerfile” dans le répertoire de l’application web (Dans notre cas: HoNoSoFt.BadgeIt.SonarQube.Web).
  • Connectez-vous au serveur de conteneurs Heroku
    • > heroku container:login
      • OU
    • > docker login –username=_ –password=$(heroku auth:token) registry.heroku.com
  • Poussez votre image
    • heroku container:push <process-type>
      • OU, si votre image existe déjà (tag plus push)
      • Exemple: > heroku container:push web –recursive -a badgeit
        • Important: La commande d’exécution doit absolument passer par CMD et non ENTRYPOINT.
    • docker tag <imageregistry.heroku.com/<app>/<process-type>
  • Vous pouvez ensuite faire une release de votre image
    • Exemple > heroku container:release web -a badgeit
  • N’oubliez pas d’aller configurer votre application heroku, car vous devrez mettre à jour les variables d’environnements.
    • Exemple:

Résultat:

Et voilà! Vous avez le tout de fonctionnel. Ce n’est pas bien de ne pas tout avoir dans le vert, mais ce n’est qu’une première version.

Possibilité de faire mieux (Oui, évidemment ;))

Petit exercice au cas où vous voulez vous amuser:

  1. Créer un docker-compose
    • Ajouter l’image de conteneur de Badgeit
    • Ajouter l’image de conteneur de Shields.io
    • Configurez le tout
    • Et testez
  2. Changer le message après le build afin d’envoyer un message personalisé à Slack en utilisant une image de votre badge service (badgeIt) ou autre.

À la prochaine!

]]>
https://blog.honosoft.com/2018/09/24/integration-continue-ci-github-appveyor-sonarqube-cloud-badgeit/feed/ 0