I'm having trouble posting to the slack endpoint through a ruby script I'm writing:
#!/usr/bin/env ruby
#Notification Script Test
def send_slack_message
slack_rooms = [ '#test_channel_notify' ]
slack_token_file = (File.join(ENV['HOME'], '.slack_api_token'))
slack_api_token = (File.open(slack_token_file).readlines)[0].chomp
msg = 'This is a test message send'
slack_url = "https://slack.com/api/chat.postMessage"
%x{curl -X POST -d 'token=#{slack_api_token}\&channel=#{slack_rooms}\&text=#{msg}' '#{slack_url}'}
end
send_slack_message
The curl command with all the parameters hardcoded in the command line works properly and my message gets posted:
curl -X POST -d 'token=xxxxx-11111111111&channel=#test_channel_notify&text=This is a test' 'https://slack.com/api/chat.postMessage'
However from the script, I just get the following returned:
Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 154 100 40 100 114 289 825 --:--:-- --:--:-- --:--:-- 832
If anyone knows what I'm doing wrong would be much appreciated! Also I do not want to have to require any modules in order to do this, nor should I have to.
You're specifying your channel as an array, so if you don't specify which value, or index it'll be added as an array in your request. If you have more than one try iterating over every value within your slack_rooms array or just specifying the first element "slack_rooms.first".
%x{curl -X POST -d 'token=#{slack_api_token}&channel=#{slack_rooms.first}&text=#{msg}' #{slack_url}}
Note the slack_url is also a variable but in a curl request it doesn't need to be specified with quotes.
And you don't need the backslash-es to join the parameters, just the &.
The problem was that I was specifying an array for my channel, but only passing in a single channel into my command. When I removed the array and tested as:
slack_rooms = '#test-notification-channel'
It worked as expected.
Related
sorry for the noob question. I'm trying to write a simple bash script, based on newsbeuter. Basically I'm trying to get the first 5 articles I haven't read yet, once I got them, I send them to my phone with pushover and I need so set them as read on newsbeuter.
#!/bin/bash --
urls=$( sqlite3 /home/pi/.newsbeuter/cache.db <<END
select url from rss_item where unread = 1 limit 5;
END
)
This is the first query. I send the message variable through the pushover api.
Now I need to get how to update the table and set the articles as read.
Any ideas? (I'm totally new to bash syntax).
I tried both to recreate a query like
UPDATE rss_item set unread = 0 where url = '$url'
I looped it but it didn't work, then I tried to make
`UPDATE rss_item set unread = 0 where url in ($urls)`
but I keep getting errors I can't even understand! I really need a syntax lecture!
Try this:
#!/bin/bash --
urls="$(
sqlite3 /home/pi/.newsbeuter/cache.db \
'select url from rss_item where unread = 1 limit 5' \
)"
for url in $urls; do
sqlite3 /home/pi/.newsbeuter/cache.db \
"UPDATE rss_item set unread = 0 where url = '$url'"
done
I use Github API V3 to get forks count for a repository, i use:
GET /repos/:owner/:repo/forks
The request bring me only 30 results even if a repository contain more, I googled a little and I found that due to the memory restrict the API return only 30 results per page, and if I want next results I have to specify the number of page.
Only me I don't need all this information, all I need is the number of forks.
Is there any way to get only the number of forks?
Because If I start to loop page per page my script risque to crash if a repository contain thousand results.
You can try and use a search query.
For instance, for my repo VonC/b2d, I would use:
https://api.github.com/search/repositories?q=user%3AVonC+repo%3Ab2d+b2d
The json answer gives me a "forks_count": 5
Here is one with more than 4000 forks (consider only the first result, meaning the one whose "full_name" is actually "strongloop/express")
https://api.github.com/search/repositories?q=user%3Astrongloop+repo%3Aexpress+express
"forks_count": 4114,
I had a job where I need to get all forks as git-remotes of a github project.
I wrote the simple python script https://gist.github.com/urpylka/9a404991b28aeff006a34fb64da12de4
At the base of the program is recursion function for getting forks of a fork. And I met same problem (GitHub API was returning me only 30 items).
I solved it with add increment of ?page=1 and add check for null response from server.
def get_fork(username, repo, forks, auth=None):
page = 1
while 1:
r = None
request = "https://api.github.com/repos/{}/{}/forks?page={}".format(username, repo, page)
if auth is None: r = requests.get(request)
else: r = requests.get(request, auth=(auth['login'], auth['secret']))
j = r.json()
r.close()
if 'message' in j:
print("username: {}, repo: {}".format(username, repo))
print(j['message'] + " " + j['documentation_url'])
if str(j['message']) == "Not Found": break
else: exit(1)
if len(j) == 0: break
else: page += 1
for item in j:
forks.append({'user': item['owner']['login'], 'repo': item['name']})
if auth is None:
get_fork(item['owner']['login'], item['name'], forks)
else:
get_fork(item['owner']['login'], item['name'], forks, auth)
I wrote a basic program to test the ruby metriks gem
require 'metriks'
require 'metriks/reporter/logger'
#registry = Metriks::Registry.new
#logger = Logger.new('/tmp/metrics.log')
#reporter = Metriks::Reporter::Logger.new(:logger => #logger)
#reporter.start
#registry.meter('tasks').mark
print "Hello"
#registry.meter('tasks').mark
#reporter.stop
After i execute the program, there is nothing in the log other than it got created.
$ cat /tmp/metrics.log
# Logfile created on 2015-06-15 14:23:40 -0700 by logger.rb/44203
You should either pass in your own registry while instantiating Metriks::Reporter::Logger or use the deafult registry (Metrics::Resgitry.default) if you are using a logger to log metrics.
Also the default log write interval is 60 seconds, your code completes before that so even if everything is setup okay it won't get recorded. So, since you want to use your own registry, this should work for you (I'm adding a little sleep since I'm gonna use an interval of 1 second) :
require 'metriks'
require 'metriks/reporter/logger'
#registry = Metriks::Registry.new
#logger = Logger.new('/tmp/metrics.log')
#reporter = Metriks::Reporter::Logger.new(:logger => #logger,
:registry => #registry
:interval => 1)
#reporter.start
#registry.meter('tasks').mark
print "Hello"
#registry.meter('tasks').mark
# Just giving it a little time so the metrics will be recorded.
sleep 2
#reporter.stop
But I don't really think short intervals are good.
UPDATE : Also I think #reporter.write will help you write down the logs instantly regardless of the time interval. So you don't have to use sleep (better).
I´m trying to work out a way in Puppet to get the current zpool capacity numbers for my FreeBSD storage servers, storing them in custom facts and to generate alert if capacity reaches a "too high" level. Closest match to my problem that I´ve found so far is:
Returning multiple custom facts with puppet Facter
That pointed me to this solution:
operatingsystem = Facter.value('operatingsystem')
case operatingsystem
when "FreeBSD"
present_zpools = IO.popen('zpool list -H -o name').read.chomp
if ! present_zpools.empty?
Facter.add(:zpools) do
setcode do
zpools = IO.popen('for i in $(zpool list -H -o name); do echo $i; done').read.chomp.split("\n")
end
end
def addZpoolCapacityFact(zpool)
zpool_capacity = IO.popen('zpool get -H -o value capacity #{zpool}').read.tr('%','').chomp
Facter.add("capacity_" + zpool) do
setcode do
zpool_capacity
end
end
end
zpools = Facter.value(:zpools)
zpools.each do |zpool|
addZpoolCapacityFact(zpool)
end
end
end
But doesn´t quite produce the result I was expecting, e.g:
capacity_pool1: 10 30
capacity_pool2: 10 30
When I was really expecting:
capacity_pool1: 10
capacity_pool2: 30
What am I doing wrong?
OK, solved!
The problem was using IO.popen two times in same script, even though I tried nil'ing the variables, the first split function applied to variable 'zpools' was also run on 'zpool_capacity', I think, which made the result look like:
"capacity_pool1":"10\n12","capacity_pool2":"10\n12"
Notice the '\n' between the numbers? I´m sure there´s a Ruby way to be able to use IO.popen multiple times but I don´t know how, so I just changed the commands to execute with plain backticks (`) and here´s the working code:
operatingsystem = Facter.value('operatingsystem')
case operatingsystem
when "FreeBSD"
present_zpools = `zpool list -H -o name`.chomp
if ! present_zpools.empty?
Facter.add(:zpools) do
setcode do
zpools = `for i in $(zpool list -H -o name); do echo $i; done`.chomp.split("\n")
end
end
def addZpoolCapacityFact(zpool)
zpool_capacity = `zpool get -H -o value capacity #{zpool}`.tr('%','').chomp
Facter.add(zpool + "_capacity") do
setcode do
zpool_capacity
end
end
end
zpools = Facter.value(:zpools)
zpools.each do |zpool|
addZpoolCapacityFact(zpool)
end
end
end
Now result looks like I´d expect:
pool1_capacity: 10
pool2_capacity: 30
I created a bash script file:
#!/bin/bash
default_card=`head -1 /proc/asound/modules`
echo $default_card
if [ ! -e /etc/modprobe.d/sound.blacklist.conf ] ; then
echo "Default sound card(snd_hda_intel) is not added in black list"
/usr/bin/expect <<delim
exp_internal 0
set timeout 20
spawn sudo sh -c "echo 'blacklist snd_hda_intel' > /etc/modprobe.d/sound.blacklist.conf"
expect "password for ubuntu:"
send "1234\n"
expect eof
delim
else
echo "Default sound cardis already added in black list";
fi
I am creating a black list file in "/etc/modprobe.d". Creating or deleting any file from "/etc" requires sudo access.
I want to implement the same functionality in Ruby using a Rake task. I created the task as:
desc "Check/creates soundcard blacklist"
task :create_blacklist do
begin
if !File.exists?("/etc/modprobe.d/sound.blacklist.conf")
# code for creating new file and write into it
......
......
else
puts "Sound-card blacklist file is present at /etc/modprobe.d/sound.blacklist.conf"
end
rescue Exception => e
puts "problem creating file #{e.message}"
end
end
I don't know how to create new file using sudo, and write into it.
I am using Ruby 1.9.3 (without RVM).
Look at https://stackoverflow.com/a/18366155/128421, https://stackoverflow.com/a/18398804/128421, and "communicating w/ command-line program (OR ruby expect)" for more information.
Ruby's IO class implements expect but it's not too full-featured:
=== Implementation from IO
------------------------------------------------------------------------------
IO#expect(pattern,timeout=9999999) -> Array
IO#expect(pattern,timeout=9999999) { |result| ... } -> nil
------------------------------------------------------------------------------
Reads from the IO until the given pattern matches or the timeout is over.
It returns an array with the read buffer, followed by the matches. If a block
is given, the result is yielded to the block and returns nil.
When called without a block, it waits until the input that matches the given
pattern is obtained from the IO or the time specified as the timeout passes.
An array is returned when the pattern is obtained from the IO. The first
element of the array is the entire string obtained from the IO until the
pattern matches, followed by elements indicating which the pattern which
matched to the anchor in the regular expression.
The optional timeout parameter defines, in seconds, the total time to wait for
the pattern. If the timeout expires or eof is found, nil is returned or
yielded. However, the buffer in a timeout session is kept for the next expect
call. The default timeout is 9999999 seconds.