rodbot 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f32541e2113ba1425a81da6374fc3353d578ba5fd0b9b1905f5eeae95fab0180
4
- data.tar.gz: ad474b634ffa0fb96fe23cb7602b9de81df2367636cb0327cce578901237615d
3
+ metadata.gz: 0bf9f1ee8fd09d93797a5ba276aa6fec09be9620e540f118240525c73a6fda6b
4
+ data.tar.gz: b36fdd850e38596aaf7da805107d0cbbbcb46de823e76cad151676fbcc14dd9c
5
5
  SHA512:
6
- metadata.gz: 45fc1790e2d559610ebca8ce834bcaf245f6fb922e18edd56d55f2ee307fbf2daffe2db10b507efc1944d27e4c562577108013c48186e6a743bf2e5cd1dfe67b
7
- data.tar.gz: 9787f11da1619228e571644be1643e66d3b4b65f46ed14d2782b9b20a73b35f98f33bce02bd26c5dd7677e377e09874945412155cca9e55e220363cd41776e4a
6
+ metadata.gz: 37a9346640167dc0543d9361b1d53789e363d27e6c57129fde777897f7e8ec3fff51e735129accdfaf8caee943a29fa19daae2ea5acdab6023d11d7dbf4ebaaa
7
+ data.tar.gz: 6fec833877807a7b6dc85e19682c5bf88172ad2ff32ce0d0c5e83565cecbf60e54517f1aaeda451e17ee610f5338969bd05ffe5a8c002b649c28c3e35f25949b
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  Nothing so far
4
4
 
5
+ ## 0.3.2
6
+
7
+ #### Additions
8
+ * Simple /healthz route e.g. for deployments on render.com
9
+ * Deploy templates for render.com
10
+
11
+ #### Changes
12
+ * Switch from httparty to httpx
13
+
5
14
  ## 0.3.1
6
15
 
7
16
  #### Fixes
data/README.md CHANGED
@@ -302,13 +302,13 @@ overmind start
302
302
 
303
303
  ## Request
304
304
 
305
- To query the **app service**, you can either use the bundled [HTTParty](https://rubygems.org/gems/httparty) gem or the following convenience wrapper:
305
+ To query the **app service**, you can either use the bundled [HTTPX](https://rubygems.org/gems/httpx) gem or the following convenience wrapper:
306
306
 
307
307
  ```ruby
308
- response = Rodbot.request('/time', query: { zone: 'UTC' })
308
+ response = Rodbot.request('/time', params: { zone: 'UTC' })
309
309
  ```
310
310
 
311
- This uses the default `method: :get` and the default `timeout: 10` seconds, it returns an instance of [HTTParty::Response](https://www.rubydoc.info/gems/httparty/HTTParty/Response):
311
+ This uses the default `method: :get` and the default `timeout: 10` seconds, it returns an instance of [HTTPX::Response](https://www.rubydoc.info/gems/httpx/HTTPX/Response):
312
312
 
313
313
  ```ruby
314
314
  response.code # => 200
@@ -0,0 +1 @@
1
+ 3704bffdb0e27a9544bbdc7538051a9253eeefe81bbbfeea14e1f486e36c701ae200a1b6da151306a96d8e8ccb154236cf18ce4cb27821cd42cbc165a6bc79e6
@@ -22,7 +22,7 @@ module Rodbot
22
22
  class Generator
23
23
 
24
24
  # Glob to filter relevant template files
25
- GLOB = "**/{*,.ruby-version,.gitignore,.keep}"
25
+ GLOB = "**/{*,.ruby-version*,.gitignore,.keep}"
26
26
 
27
27
  # Colors used by +info+ to color part of the output
28
28
  TAG_COLORS = {
@@ -38,8 +38,9 @@ module Rodbot
38
38
 
39
39
  # Print the interpolated template to STDOUT
40
40
  def display
41
+ puts
41
42
  each_template_path do |template_path, target_path, content|
42
- puts "# #{target_path}", (content || template_path.read)
43
+ puts "### #{target_path} ###", (content || template_path.read), nil
43
44
  end
44
45
  end
45
46
 
@@ -71,9 +71,7 @@ module Rodbot
71
71
 
72
72
  def on_message(message)
73
73
  if message.content[:msgtype] == 'm.text' && message.content[:body].start_with?('!')
74
- html = 'pong' if message.content[:body] == '!ping'
75
- html ||= reply_to(message)
76
- room.send_html(html)
74
+ room.send_html(reply_to(message))
77
75
  end
78
76
  end
79
77
 
@@ -42,7 +42,11 @@ module Rodbot
42
42
  body = remote.gets("\x04")
43
43
  remote.close
44
44
  body.force_encoding('UTF-8')
45
- client.web_client.chat_postMessage(channel: channel_id, text: body, as_user: true)
45
+ client.web_client.chat_postMessage(
46
+ channel: channel_id,
47
+ text: md_to_slack_text(body),
48
+ as_user: true
49
+ )
46
50
  end
47
51
  end
48
52
  end
@@ -56,23 +60,34 @@ module Rodbot
56
60
 
57
61
  def on_message(message)
58
62
  if message.text.start_with?('!')
59
- md = 'pong' if message.text == '!ping'
60
- md ||= reply_to(message)
61
- client.web_client.chat_postMessage(channel: message.channel, text: md, as_user: true)
63
+ client.web_client.chat_postMessage(
64
+ channel: message.channel,
65
+ text: reply_to(message),
66
+ as_user: true
67
+ )
62
68
  end
63
69
  end
64
70
 
65
71
  def reply_to(message)
66
72
  command(*message.text[1..].split(/\s+/, 2)).
67
- psub(placeholders(message.user))
73
+ psub(placeholders(message.user)).
74
+ then { md_to_slack_text(_1) }
68
75
  end
69
76
 
77
+ # @see https://api.slack.com/reference/surfaces/formatting
70
78
  def placeholders(sender)
71
79
  {
72
80
  sender: "<@#{sender}>"
73
81
  }
74
82
  end
75
83
 
84
+ # @see https://api.slack.com/reference/surfaces/formatting
85
+ def md_to_slack_text(md)
86
+ md.
87
+ gsub(/\[(.+?)\]\((.+?)\)/, '<\2|\1>'). # convert links
88
+ gsub(/^\s*[*-]\s+/, '• ') # convert bullet lists
89
+ end
90
+
76
91
  end
77
92
  end
78
93
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'httparty'
3
+ require 'httpx'
4
4
 
5
5
  module Rodbot
6
6
  class Plugins
@@ -24,11 +24,11 @@ module Rodbot
24
24
 
25
25
  class Today
26
26
  def initialize
27
- @response = HTTParty.get('https://www.merriam-webster.com/word-of-the-day')
27
+ @response = HTTPX.with(timeout: { request_timeout: 60 }).get('https://www.merriam-webster.com/word-of-the-day')
28
28
  end
29
29
 
30
30
  def message
31
- if @response.success?
31
+ if @response.status == 200
32
32
  "Word of the day: [#{word}](#{url})"
33
33
  else
34
34
  "Sorry, there was a problem fetching the word of the day."
@@ -38,11 +38,11 @@ module Rodbot
38
38
  private
39
39
 
40
40
  def word
41
- @response.body.match(/<h2 class="word-header-txt">(.+?)</).captures.first
41
+ @response.body.to_s.match(/<h2 class="word-header-txt">(.+?)</).captures.first
42
42
  end
43
43
 
44
44
  def url
45
- @response.body.match(/<meta property="og:url" content="(.+?)"/).captures.first
45
+ @response.body.to_s.match(/<meta property="og:url" content="(.+?)"/).captures.first
46
46
  end
47
47
  end
48
48
 
data/lib/rodbot/rack.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- require 'httparty'
3
+ require 'httpx'
4
4
 
5
5
  using Rodbot::Refinements
6
6
 
@@ -36,12 +36,11 @@ module Rodbot
36
36
  # Send request to the app service
37
37
  #
38
38
  # @param path [String] path e.g. +/help+
39
- # @param query [Hash] query hash e.g. +{ search: 'foobar' }+
40
- # @param method [Symbol, String] HTTP method
39
+ # @param params [Hash] params hash e.g. +{ search: 'foobar' }+
41
40
  # @param timeout [Integer] max seconds to wait for response
42
- # @return [HTTParty::Response]
43
- def request(path, query: {}, method: :get, timeout: 10)
44
- HTTParty.send(method, Rodbot::Services::App.url.uri_concat(path), query: query, timeout: timeout)
41
+ # @return [HTTPX::Response]
42
+ def request(path, params: {}, timeout: 10)
43
+ HTTPX.with(timeout: { request_timeout: timeout }).get(Rodbot::Services::App.url.uri_concat(path), params: params)
45
44
  end
46
45
 
47
46
  end
data/lib/rodbot/relay.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'digest'
4
4
  require 'socket'
5
- require 'httparty'
5
+ require 'httpx'
6
6
 
7
7
  module Rodbot
8
8
 
@@ -84,15 +84,28 @@ module Rodbot
84
84
  ]
85
85
  end
86
86
 
87
- # Perform the command on the app using a GET request
87
+ # Perform the built-in command or fall back to the app using +request+
88
88
  #
89
89
  # @param command [String] command to perform
90
90
  # @param argument [String, nil] optional arguments
91
91
  # @return [String] response as Markdown
92
92
  def command(command, argument=nil)
93
- response = Rodbot.request(command, query: { argument: argument })
94
- case response.code
95
- when 200 then response.body
93
+ case command
94
+ when 'ping' then 'pong'
95
+ when 'version' then "rodbot-#{Rodbot::VERSION}"
96
+ else request(command, argument)
97
+ end
98
+ end
99
+
100
+ # Perform the command on the app using a GET request
101
+ #
102
+ # @param command [String] command to perform
103
+ # @param argument [String, nil] optional arguments
104
+ # @return [String] response as Markdown
105
+ def request(command, argument=nil)
106
+ response = Rodbot.request(command, params: { argument: argument })
107
+ case response.status
108
+ when 200 then response.body.to_s
96
109
  when 404 then "[[SENDER]] I don't know what do do with `!#{command}`. 🤔"
97
110
  else fail
98
111
  end
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  require 'readline'
4
- require 'httparty'
4
+ require 'httpx'
5
5
  require 'pastel'
6
6
  require 'tty-markdown'
7
7
 
@@ -16,6 +16,7 @@ module Rodbot
16
16
  # @param raw [Boolean] whether to display raw Markdown
17
17
  def initialize(sender, raw: false)
18
18
  @sender, @raw = sender, raw
19
+ @relay = Rodbot::Relay.new
19
20
  @pastel = Pastel.new
20
21
  end
21
22
 
@@ -33,17 +34,7 @@ module Rodbot
33
34
  def reply_to(message)
34
35
  return "(no command given)" unless message.match?(/^!/)
35
36
  command, argument = message[1..].split(/\s+/, 2)
36
- body = begin
37
- response = Rodbot.request(command, query: { argument: argument })
38
- case response.code
39
- when 200 then response.body
40
- when 404 then "[[SENDER]] I've never heard of `!#{command}`, try `!help` instead. 🤔"
41
- else fail
42
- end
43
- rescue
44
- "[[SENDER]] I'm having trouble talking to the app. 💣"
45
- end
46
- text_for body.psub(placeholders)
37
+ text_for @relay.send(:command, command, argument).psub(placeholders)
47
38
  end
48
39
 
49
40
  def placeholders
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
- VERSION = "0.3.1"
4
+ VERSION = "0.3.2"
5
5
  end
@@ -4,7 +4,7 @@ x-defaults: &defaults
4
4
  build:
5
5
  context: .
6
6
  dockerfile_inline: |
7
- FROM ruby:3.2-alpine
7
+ FROM ruby:[%= RUBY_VERSION.sub(/\.\d+$/, '') %]-alpine
8
8
  RUN apk update && apk --no-cache add build-base
9
9
  ENV RODBOT_ENV="production"
10
10
  ENV RACK_ENV="production"
@@ -4,7 +4,7 @@ x-defaults: &defaults
4
4
  build:
5
5
  context: .
6
6
  dockerfile_inline: |
7
- FROM ruby:3.2-alpine
7
+ FROM ruby:[%= RUBY_VERSION.sub(/\.\d+$/, '') %]-alpine
8
8
  RUN apk update && apk --no-cache add build-base
9
9
  ENV RODBOT_ENV="production"
10
10
  ENV RACK_ENV="production"
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ echo "--> Checking environment"
5
+ echo "RODBOT_ENV: $RODBOT_ENV"
6
+ echo "RODBOT_PLUGINS: $RODBOT_PLUGINS"
7
+
8
+ echo "--> Installing bundle"
9
+ bundle config set with $RODBOT_PLUGINS
10
+ bundle install
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+
3
+ export RODBOT_APP_HOST=0.0.0.0
4
+ bundle exec rodbot start
5
+ sleep infinity
@@ -0,0 +1,19 @@
1
+ services:
2
+ - type: web
3
+ name: bot
4
+ domains:
5
+ - bot.example.com # TODO: use a domain name of your own
6
+ runtime: ruby
7
+ buildCommand: render-build.sh
8
+ startCommand: render-start.sh
9
+ healthCheckPath: /healthz
10
+ autoDeploy: true
11
+ envVars:
12
+ - key: PORT
13
+ value: 7200
14
+ - key: PRODUCTION_CREDENTIALS_KEY
15
+ value:
16
+ - key: RODBOT_ENV
17
+ value: production
18
+ - key: RODBOT_PLUGINS
19
+ value: matrix # TODO: update space separated list of plugins
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ echo "--> Checking environment"
5
+ echo "RODBOT_ENV: $RODBOT_ENV"
6
+ echo "RODBOT_PLUGINS: $RODBOT_PLUGINS"
7
+
8
+ echo "--> Installing bundle"
9
+ bundle config set with $RODBOT_PLUGINS
10
+ bundle install
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+
3
+ case 1 in
4
+ "app")
5
+ export RODBOT_APP_HOST=0.0.0.0
6
+ bundle exec rodbot start app
7
+ ;;
8
+ "relay")
9
+ bundle exec rodbot start relay
10
+ ;;
11
+ "schedule")
12
+ bundle exec rodbot start schedule
13
+ ;;
14
+ *)
15
+ echo "Invalid argument"
16
+ exit 1
17
+ ;;
18
+ esac
@@ -0,0 +1,42 @@
1
+ services:
2
+ - type: web
3
+ name: bot-app
4
+ domains:
5
+ - bot.example.com # TODO: use a domain name of your own
6
+ runtime: ruby
7
+ buildCommand: render-build.sh
8
+ startCommand: render-start.sh app
9
+ healthCheckPath: /healthz
10
+ autoDeploy: true
11
+ envVars:
12
+ - fromGroup: bot
13
+ - key: PORT
14
+ value: 7200
15
+ - type: worker
16
+ name: bot-relay
17
+ runtime: ruby
18
+ buildCommand: render-build.sh
19
+ startCommand: render-start.sh relay
20
+ autoDeploy: true
21
+ envVars:
22
+ - fromGroup: bot
23
+ - type: worker
24
+ name: bot-schedule
25
+ runtime: ruby
26
+ buildCommand: render-build.sh
27
+ startCommand: render-start.sh schedule
28
+ autoDeploy: true
29
+ envVars:
30
+ - fromGroup: bot
31
+
32
+ envVarGroups:
33
+ - name: bot
34
+ envVars:
35
+ - key: PRODUCTION_CREDENTIALS_KEY
36
+ value:
37
+ - key: RODBOT_ENV
38
+ value: production
39
+ - key: RODBOT_PLUGINS
40
+ value: "matrix" # TODO: update space separated list of plugins
41
+ - key: RODBOT_APP_URL
42
+ value: https://bot.example.com # TODO: use the above service domain name
@@ -0,0 +1 @@
1
+ [%= RUBY_VERSION.sub(/\.\d+$/, '') %]
@@ -7,5 +7,6 @@ class App < Roda
7
7
  r.root { view :root }
8
8
  end
9
9
 
10
+ run :healthz, Routes::Healthz
10
11
  run :help, Routes::Help
11
12
  end
@@ -0,0 +1,15 @@
1
+ module Routes
2
+ class Healthz < App
3
+
4
+ route do |r|
5
+
6
+ # GET /healthz
7
+ r.root do
8
+ response['Content-Type'] = 'text/plain; charset=utf-8'
9
+ 'alive and kicking'
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
data/rodbot.gemspec CHANGED
@@ -46,7 +46,7 @@ Gem::Specification.new do |spec|
46
46
  spec.add_runtime_dependency 'dry-credentials', '~> 0'
47
47
  spec.add_runtime_dependency 'tty-markdown', '~> 0'
48
48
  spec.add_runtime_dependency 'pastel', '~> 0'
49
- spec.add_runtime_dependency 'httparty', '~> 0'
49
+ spec.add_runtime_dependency 'httpx', '~> 1'
50
50
  spec.add_runtime_dependency 'puma', '~> 6', '>= 6.2'
51
51
  spec.add_runtime_dependency 'roda', '~> 3'
52
52
  spec.add_runtime_dependency 'tilt', '~> 2'
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Schwyn
@@ -29,7 +29,7 @@ cert_chain:
29
29
  kAyiRqgxF4dJviwtqI7mZIomWL63+kXLgjOjMe1SHxfIPo/0ji6+r1p4KYa7o41v
30
30
  fwIwU1MKlFBdsjkd
31
31
  -----END CERTIFICATE-----
32
- date: 2023-10-11 00:00:00.000000000 Z
32
+ date: 2023-10-18 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: zeitwerk
@@ -102,19 +102,19 @@ dependencies:
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  - !ruby/object:Gem::Dependency
105
- name: httparty
105
+ name: httpx
106
106
  requirement: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: '1'
111
111
  type: :runtime
112
112
  prerelease: false
113
113
  version_requirements: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: '1'
118
118
  - !ruby/object:Gem::Dependency
119
119
  name: puma
120
120
  requirement: !ruby/object:Gem::Requirement
@@ -451,6 +451,7 @@ files:
451
451
  - checksums/rodbot-0.2.0.gem.sha512
452
452
  - checksums/rodbot-0.3.0.gem.sha512
453
453
  - checksums/rodbot-0.3.1.gem.sha512
454
+ - checksums/rodbot-0.3.2.gem.sha512
454
455
  - doc/rodbot.afphoto
455
456
  - doc/rodbot.avif
456
457
  - exe/rodbot
@@ -509,12 +510,17 @@ files:
509
510
  - lib/templates/deploy/docker/compose.yaml.gerb
510
511
  - lib/templates/deploy/procfile-split/Procfile.gerb
511
512
  - lib/templates/deploy/procfile/Procfile.gerb
513
+ - lib/templates/deploy/render-split/render-build.sh
514
+ - lib/templates/deploy/render-split/render-start.sh
512
515
  - lib/templates/deploy/render-split/render.yaml.gerb
516
+ - lib/templates/deploy/render/render-build.sh
517
+ - lib/templates/deploy/render/render-start.sh
513
518
  - lib/templates/deploy/render/render.yaml.gerb
514
519
  - lib/templates/new/.gitignore
515
- - lib/templates/new/.ruby-version
520
+ - lib/templates/new/.ruby-version.gerb
516
521
  - lib/templates/new/README.md
517
522
  - lib/templates/new/app/app.rb
523
+ - lib/templates/new/app/routes/healthz.rb
518
524
  - lib/templates/new/app/routes/help.rb
519
525
  - lib/templates/new/app/views/layout.erb
520
526
  - lib/templates/new/app/views/root.erb
@@ -563,7 +569,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
563
569
  - !ruby/object:Gem::Version
564
570
  version: '0'
565
571
  requirements: []
566
- rubygems_version: 3.4.20
572
+ rubygems_version: 3.4.21
567
573
  signing_key:
568
574
  specification_version: 4
569
575
  summary: Minimalistic framework to build chat bots on top of a Roda backend
metadata.gz.sig CHANGED
Binary file
@@ -1 +0,0 @@
1
- 3.2