<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Raphael Noriode</title>
    <description>The latest articles on DEV Community by Raphael Noriode (@oghenebrume50).</description>
    <link>https://dev.to/oghenebrume50</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F263073%2Fded680f2-423b-4752-96fb-6d24aa392d00.jpeg</url>
      <title>DEV Community: Raphael Noriode</title>
      <link>https://dev.to/oghenebrume50</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oghenebrume50"/>
    <language>en</language>
    <item>
      <title>Building a Slack bot with Nodejs </title>
      <dc:creator>Raphael Noriode</dc:creator>
      <pubDate>Sun, 19 Apr 2020 19:27:07 +0000</pubDate>
      <link>https://dev.to/oghenebrume50/building-a-slack-bot-with-nodejs-3g40</link>
      <guid>https://dev.to/oghenebrume50/building-a-slack-bot-with-nodejs-3g40</guid>
      <description>&lt;p&gt;Building  a Slack bot is actually easy and straightforward, unfortunately, a lot of tutorials covering this topic are fairly outdated now, in this article, I would walk you through on how to build a simple one with Nodejs and the &lt;a href="https://github.com/slackapi/bolt"&gt;Bolt library&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First, you would need to create a slack workspace &lt;a href="https://slack.com/intl/en-ng/create#teamname"&gt;here&lt;/a&gt;&lt;br&gt;
after creating a team&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d3eKTogw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587317035/tutorials/1createbot_psl1ek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d3eKTogw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587317035/tutorials/1createbot_psl1ek.png" alt="create team"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;head over to &lt;a href="https://api.slack.com/apps"&gt;api.slack.com/apps&lt;/a&gt; to create a new bot app. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fBizdbUL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587317036/tutorials/createapp2_gbb3ij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fBizdbUL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587317036/tutorials/createapp2_gbb3ij.png" alt="create app"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click on &lt;code&gt;Create app&lt;/code&gt; button, type in a name and select a workspace, ideally the one you initially created, then create the app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Glu9XHnX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587317036/tutorials/configurebot_fkhkcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Glu9XHnX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587317036/tutorials/configurebot_fkhkcb.png" alt="Setup bot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From this window, you get to set up what the app needs, for this app, we only care about "Event subscription", "Bots" and "Permissions".&lt;/p&gt;

&lt;h3&gt;
  
  
  Event Subscription
&lt;/h3&gt;

&lt;p&gt;Click on &lt;code&gt;Event subscription&lt;/code&gt; button and turn it on &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ldFfFlqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587317688/tutorials/eventsub_wsv1dw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ldFfFlqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587317688/tutorials/eventsub_wsv1dw.png" alt="Event setup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we can set up the event, we need to get our request URL, this is easy using the bolt library.&lt;/p&gt;
&lt;h4&gt;
  
  
  First install bot to your workspace
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Click on &lt;code&gt;Oauth and permissions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click on &lt;code&gt;Install App to Workspace&lt;/code&gt; button&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ideally, you should select the bot scopes before adding the app to your Workspace, for every added scope you would have to reinstall the app to the workspace.&lt;br&gt;
For the app, we used the &lt;code&gt;app:mention&lt;/code&gt; bot scope, basically, we want to listen for when the app is mentioned. &lt;/p&gt;

&lt;p&gt;N:B The difference between the bot scope and the user scope is that the user scope allows the bot to act on behalf of a slack user when given the permission to.  &lt;/p&gt;

&lt;p&gt;Now you should see your &lt;code&gt;Bot User OAuth Access Token&lt;/code&gt; this would be needed to configure the app.&lt;/p&gt;

&lt;p&gt;The needed code to generate the request URL goes below; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create app folder&lt;/li&gt;
&lt;li&gt;create index.js file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;npm install @slack/bolt dotenv&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;copy the below code into the index.js file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require('dotenv').config();
const { App } = require('@slack/bolt');

const bot = new App({
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  token: process.env.SLACK_BOT_TOKEN,
});

(async () =&amp;gt; {
  // Start the app
  await bot.start(process.env.PORT || 3000);

  console.log('⚡️ Bolt app is running!');
})();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;check out how to use &lt;code&gt;dotenv&lt;/code&gt; if you don't know already, but you want to use it to hide these credentials.&lt;br&gt;
Get the &lt;code&gt;Signing Secret&lt;/code&gt; from the "Basic Information" page&lt;/p&gt;

&lt;p&gt;Run the program and route localhost to a live server like ngrok, now copy the link and paste as shown below;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u2WTcJSO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587320202/tutorials/ngrok_qge7zi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u2WTcJSO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587320202/tutorials/ngrok_qge7zi.png" alt="request URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the bolt library listens on the slack/events endpoint, hence why you should add it to your URL, if it is verified as seen above you are good to go. &lt;br&gt;
The Basic information page should look like this&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1CQ19I5T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587320742/tutorials/basic_kouw1p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1CQ19I5T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587320742/tutorials/basic_kouw1p.png" alt="basic one"&gt;&lt;/a&gt;&lt;br&gt;
Features and functionalities&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NxxPqE2p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587320744/tutorials/basic2_xdtchh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NxxPqE2p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587320744/tutorials/basic2_xdtchh.png" alt="Basic2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We would not be covering distribution in this article, I'll link another article for that. &lt;/p&gt;

&lt;p&gt;Now in your slack workspace, the bot should show up under Apps&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--erTghkDq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587321309/tutorials/appshow_fkhkb5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--erTghkDq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587321309/tutorials/appshow_fkhkb5.png" alt="see apps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But no action is performed by the bot yet &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--erTghkDq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587321309/tutorials/appshow_fkhkb5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--erTghkDq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587321309/tutorials/appshow_fkhkb5.png" alt="no action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;N:B we would need to respond to mentions, so go to the &lt;code&gt;OAuth and Permissions&lt;/code&gt; tab add &lt;code&gt;chat:write&lt;/code&gt; to the bot scope.&lt;/p&gt;

&lt;p&gt;Add this code to your index.js file just after declaring the initializing APP&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bot.event("app_mention", async ({ context, event }) =&amp;gt; {

  try{
    await bot.client.chat.postMessage({
    token: context.botToken,
    channel: event.channel,
    text: `Hey yoo &amp;lt;@${event.user}&amp;gt; you mentioned me`
  });
  }
  catch (e) {
    console.log(`error responding ${e}`);
  }

});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://api.slack.com/events/app_mention"&gt;see here&lt;/a&gt; to read more on the app mention API&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add app to a channel and mention the app
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AvCxuFeO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587322779/tutorials/response_xstkz5.png" alt="see response"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that is it right there, simple way to build a slack bot with the @slack/bolt library and Nodejs. For more insight on what is possible check out this &lt;a href="https://github.com/Oghenebrume50/slack-readExport"&gt;Github repository&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;After building your Slack app, distributing it is necessary for visibility but it can get really tricky, I will be writing on that next.  &lt;/p&gt;

</description>
      <category>node</category>
      <category>bot</category>
      <category>slack</category>
    </item>
    <item>
      <title>Web scraping with Ruby and Watir</title>
      <dc:creator>Raphael Noriode</dc:creator>
      <pubDate>Sun, 19 Apr 2020 10:32:52 +0000</pubDate>
      <link>https://dev.to/oghenebrume50/web-scraping-with-ruby-and-watir-46ga</link>
      <guid>https://dev.to/oghenebrume50/web-scraping-with-ruby-and-watir-46ga</guid>
      <description>&lt;p&gt;Ruby is a popular object-oriented programming language that is well suited for scriptwriting and creating complex web applications, but in this article, we would focus on writing scripts like web scrapers.&lt;br&gt;
A quick google search on web scraping with Ruby would bring up the Nokogiri gem, So, it obviously has to be the best tool out there, &lt;em&gt;well, No&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Nokogiri is great but it has a big flaw, it doesn't fill forms which obviously means, things like authentication cannot be done with it, and if you are going to scrap a dynamic web site you most likely need to authenticate, &lt;em&gt;enter Watir&lt;/em&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--stmSK2vJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587259649/tutorials/enterwatir_aeih8g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--stmSK2vJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587259649/tutorials/enterwatir_aeih8g.gif" alt="enter Watir"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check out Watir &lt;a href="http://watir.com/"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  How to scrap Facebook :XD
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Create a ruby file &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basically, just create any file and end it with .rb, that is pretty much a ruby file. Ideally, this has to be in a folder, then open it in your favourite text editor. (Go VS code)&lt;/p&gt;

&lt;p&gt;in that folder&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a Gemfile&lt;br&gt;
Just create a file with the name 'Gemfile' &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the below code into the Gemfile&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    source 'https://rubygems.org/'

    gem 'watir', '~&amp;gt; 6.16', '&amp;gt;= 6.16.5'
    gem 'headless', '~&amp;gt; 2.2', '&amp;gt;= 2.2.3'
    gem 'webdrivers', '~&amp;gt; 4.2'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Now run &lt;code&gt;bundle install&lt;/code&gt;
This should install all the above stated dependencies, I would explain why 'headless' and 'webdrivers' is needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In your ruby file, require the needed gem&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    require 'watir'
    require 'webdrivers'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I really like to modularize my code, so we will need to create another ruby file, call it login.rb&lt;br&gt;
This file would hold our authentication code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Login
  attr_reader :email, :password

  def initialize(user)
    @email = user[:email]
    @password = user[:pass]
    $browser = Watir::Browser.new :chrome, headless: true

    $browser.goto 'http://facebook.com/'
  end

  def auth
    form = $browser.form(id: 'login_form')
    form.text_field(name: 'email').set(email)
    form.text_field(name: 'pass').set(password)
    form.button(text: 'Log In').click

    sleep(2)
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A couple of things to note from the above code, I hid my Facebook login credentials in environment variables, because, well you are not supposed to know them, LOL. &lt;/p&gt;

&lt;p&gt;Breaking down the code; &lt;br&gt;
I created a login class that initializes the Watir on a chrome instance and makes it run in the background, this is the point of &lt;code&gt;headless: true&lt;/code&gt;.  Because, Watir already has a way to start up headless browsers we would not need the headless gem, feel free to delete it from the Gemfile. &lt;/p&gt;

&lt;p&gt;The auth function finds a form on Facebook.com with the id equal to &lt;code&gt;login_form&lt;/code&gt; and the input fields in the form with names equal to &lt;code&gt;email&lt;/code&gt; and &lt;code&gt;pass&lt;/code&gt; respectively, setting them to the email and password you have initially passed in. This would authenticate and log your scraper into Facebook. &lt;/p&gt;

&lt;p&gt;Now go to the first ruby file you created, this should be your entry point, put in this code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require 'watir'
require 'webdrivers'
require 'dotenv'
Dotenv.load

require_relative 'login.rb'

#login to Facebook
user = Login.new(:pass =&amp;gt; ENV['password'], :email =&amp;gt; ENV['email'])
user.auth 


timeline = $browser.spans(class: ['oi732d6d', 'ik7dh3pa', 'd2edcug0', 'qv66sw1b', 'c1et5uql', 'a8c37x1j', 'muag1w35', 'enqfppq2', 'jq4qci2q', 'a3bd9o3v', 'knj5qynh', 'oo9gr5id', 'hzawbc8m'])

timeline.each do |event|
  p event.children[0].inner_html
  puts ' '
end

$browser.close
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, we are not doing anything fancy, just scraping through our unread notification(s) and timeline and spitting out what we can find in plain sight. The output would contain both HTML tags but, this is to show you what the scraper does and the trick behind web scraping, so basically, you need to study how the elements on the site you are scraping are named, this is how you can interact with the website. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fRnTovc7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587283316/tutorials/output_timeline_pqovpx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fRnTovc7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/raphaelnoriode/image/upload/v1587283316/tutorials/output_timeline_pqovpx.png" alt="output"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;What you choose to do with this information afterwards is up to you, but you could access the div and neatly output the text in each of them, that would be a good test.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>webscraping</category>
    </item>
  </channel>
</rss>
