yl_chat 0.1.0

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.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +45 -0
  4. data/Rakefile +37 -0
  5. data/app/controllers/yl_chat/application_controller.rb +22 -0
  6. data/app/controllers/yl_chat/notifications_controller.rb +22 -0
  7. data/app/controllers/yl_chat/rooms/connection_controller.rb +20 -0
  8. data/app/controllers/yl_chat/rooms/creation_controller.rb +20 -0
  9. data/app/controllers/yl_chat/users/authorization_controller.rb +13 -0
  10. data/app/performers/yl_chat/base_connect_user_to_room.rb +13 -0
  11. data/app/performers/yl_chat/base_create_room.rb +12 -0
  12. data/app/performers/yl_chat/base_identify_user.rb +7 -0
  13. data/app/performers/yl_chat/base_notify.rb +8 -0
  14. data/app/performers/yl_chat/base_performer.rb +21 -0
  15. data/app/performers/yl_chat/disconnect_user.rb +27 -0
  16. data/app/validators/yl_chat/base_validator.rb +20 -0
  17. data/app/validators/yl_chat/identity_validator.rb +18 -0
  18. data/app/validators/yl_chat/room_validator.rb +11 -0
  19. data/config/routes.rb +10 -0
  20. data/lib/generators/yl_chat/initializer_generator.rb +17 -0
  21. data/lib/generators/yl_chat/performers_generator.rb +27 -0
  22. data/lib/generators/yl_chat/templates/initializer.rb +11 -0
  23. data/lib/generators/yl_chat/templates/performers/connect_user_to_room.rb +18 -0
  24. data/lib/generators/yl_chat/templates/performers/create_room.rb +25 -0
  25. data/lib/generators/yl_chat/templates/performers/identify_user.rb +26 -0
  26. data/lib/generators/yl_chat/templates/performers/notify.rb +16 -0
  27. data/lib/tasks/yl_chat_tasks.rake +4 -0
  28. data/lib/yl_chat.rb +26 -0
  29. data/lib/yl_chat/engine.rb +5 -0
  30. data/lib/yl_chat/version.rb +3 -0
  31. metadata +100 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d74d52377a7fe70f0787a51552b7e2ffdb463a4df1d7486ff4fe3af7c8a4fdf9
4
+ data.tar.gz: 9a470963007311ee2175cd3a11d79a53f7bae8859195f0909fe27f54a26a35d0
5
+ SHA512:
6
+ metadata.gz: d1b5e86897174ef27068967790fc73a7c53add3bba0558a2cbda91ee5c431de3cd7d4b059434c760b26f533e1862a5776e093c7a2f0f0833813f64a4bfeb7053
7
+ data.tar.gz: f32e876efaa90bb1c1d440f7471e1e58984ef76c1e27a6bbb5d65b47e3abd84e9568059c28bf85abcb19b32f7fdd9aa51e5ea789e46d5ff066ccb3140f873710
@@ -0,0 +1,20 @@
1
+ Copyright 2017 Bohdan Nikolaienko
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,45 @@
1
+ # YlChat
2
+ This gem provides integration of the "YlChat" messenger service with your main
3
+ RoR application.
4
+
5
+ ## Installation
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'yl_chat',
10
+ git: 'https://git.yalantis.com/bohdan.nikolaienko/yl_chat_gem.git'
11
+ ```
12
+
13
+ And then execute:
14
+ ```bash
15
+ $ bundle
16
+ ```
17
+
18
+ Or install it yourself as:
19
+ ```bash
20
+ $ gem install yl_chat
21
+ ```
22
+
23
+ Create an initializer:
24
+ ```bash
25
+ $ rails g yl_chat:initializer
26
+ ```
27
+
28
+ Generate a list of performers:
29
+ ```bash
30
+ $ rails g yl_chat:performers
31
+ ```
32
+ Inside performers implement needed methods following tips in comments.
33
+ Notice, that by default performers method 'authorized?' returns :true and
34
+ 'perform' do nothing and returns nil.
35
+
36
+ Inside the routes.rb file mount needed routes
37
+ ```ruby
38
+ mount YlChat::Engine => "api/chat"
39
+ ```
40
+
41
+ ## User disconnection
42
+ The next method provides an ability to disconnect a user from all chat channels:
43
+ ```ruby
44
+ YlChat::DisconnectUser.perform("user_uid")
45
+ ```
@@ -0,0 +1,37 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'YlChat'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ require 'bundler/gem_tasks'
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+
37
+ task default: :test
@@ -0,0 +1,22 @@
1
+ module YlChat
2
+ class ApplicationController < ActionController::Base
3
+ before_action :authorize_ip, if: -> { YlChat.trust_ips.present?}
4
+
5
+ rescue_from YlChat::Unauthorized do |_|
6
+ head :unauthorized
7
+ end
8
+
9
+ def room_meta
10
+ YlChat.room_meta
11
+ end
12
+
13
+ def identity_meta
14
+ YlChat.identity_meta
15
+ end
16
+
17
+ def authorize_ip
18
+ ip_authorized = YlChat.trust_ips.include? request.remote_ip
19
+ raise YlChat::Unauthorized unless ip_authorized
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module YlChat
2
+ class NotificationsController < YlChat::ApplicationController
3
+
4
+ def handle
5
+ ::Notify.perform(notification_params.to_h)
6
+ head :ok
7
+ end
8
+
9
+ private
10
+
11
+ def notification_params
12
+ params.require(:notification)
13
+ .permit(recipient_uids: [],
14
+ message: [:type, :sent_at, :room_uid, :id, :client_id,
15
+ body: [:text, :uid, :type, :title, :description,
16
+ meta: room_meta,
17
+ participants: [:uid, meta: identity_meta]],
18
+ author: [:uid, meta: identity_meta]]
19
+ )
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ module YlChat
2
+ module Rooms
3
+ class ConnectionController < YlChat::ApplicationController
4
+ def authorize
5
+ authenticate_with_http_token do |token, options|
6
+ ::ConnectUserToRoom.perform(token, connection_params.to_h)
7
+ end
8
+ head :ok
9
+ end
10
+
11
+ private
12
+
13
+ def connection_params
14
+ params.require(:data)
15
+ .permit(:uid, :type, :title, :description, meta: room_meta,
16
+ participants: [:uid, meta: identity_meta])
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module YlChat
2
+ module Rooms
3
+ class CreationController < YlChat::ApplicationController
4
+ def authorize
5
+ room_data = authenticate_with_http_token do |token, options|
6
+ ::CreateRoom.perform(token, authorization_params.to_h)
7
+ end
8
+ YlChat::RoomValidator.new(room_data).validate!
9
+ render json: { data: room_data }
10
+ end
11
+
12
+ private
13
+
14
+ def authorization_params
15
+ params.permit(:type, :title, :description, participants: [],
16
+ meta: room_meta)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module YlChat
2
+ module Users
3
+ class AuthorizationController < YlChat::ApplicationController
4
+ def authorize
5
+ user_data = authenticate_with_http_token do |token, options|
6
+ ::IdentifyUser.perform(token)
7
+ end
8
+ YlChat::IdentityValidator.new(user_data).validate!
9
+ render json: { data: user_data }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module YlChat
2
+ class BaseConnectUserToRoom < YlChat::BasePerformer
3
+ def initialize(user_token, room_params)
4
+ @user_token = user_token
5
+ @uid = room_params[:uid]
6
+ @type = room_params[:type]
7
+ @participants = room_params[:participants]
8
+ @meta = room_params[:meta]
9
+ @title = room_params[:title]
10
+ @description = room_params[:description]
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ module YlChat
2
+ class BaseCreateRoom < YlChat::BasePerformer
3
+ def initialize(user_token, room_params)
4
+ @user_token = user_token
5
+ @type = room_params[:type]
6
+ @participant_uids = room_params[:participants]
7
+ @meta = room_params[:meta]
8
+ @title = room_params[:title]
9
+ @description = room_params[:description]
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ module YlChat
2
+ class BaseIdentifyUser < YlChat::BasePerformer
3
+ def initialize(user_token)
4
+ @user_token = user_token
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ module YlChat
2
+ class BaseNotify < YlChat::BasePerformer
3
+ def initialize(notification_params)
4
+ @recipient_uids = notification_params[:recipient_uids]
5
+ @message = notification_params[:message]
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ module YlChat
2
+ class BasePerformer
3
+ def self.perform(*args)
4
+ performer = new(*args)
5
+ performer.authorize!
6
+ performer.perform
7
+ end
8
+
9
+ def perform
10
+ # do nothing
11
+ end
12
+
13
+ def authorized?
14
+ true
15
+ end
16
+
17
+ def authorize!
18
+ raise YlChat::Unauthorized unless authorized?
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module YlChat
5
+ class DisconnectUser
6
+ attr_reader :user_uid
7
+ DISCONNECTION_ENDPOINT = '/main_server/socket/disconnect'
8
+ CONTENT_TYPE = { 'Content-Type' => 'application/json' }
9
+
10
+ def initialize(user_uid)
11
+ @user_uid = user_uid
12
+ end
13
+
14
+ def self.perform(user_uid)
15
+ new(user_uid).perform
16
+ end
17
+
18
+ def perform
19
+ uri = URI(YlChat.yl_chat_url + DISCONNECTION_ENDPOINT)
20
+ Net::HTTP.start(uri.host, uri.port) do |http|
21
+ request = Net::HTTP::Post.new(uri, CONTENT_TYPE)
22
+ request.body = { uid: user_uid }.to_json
23
+ http.request request
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ module YlChat
2
+ class BaseValidator
3
+ include ActiveModel::Model
4
+ include ActiveModel::Validations
5
+
6
+ def initialize(attributes)
7
+ begin
8
+ super
9
+ rescue ActiveModel::UnknownAttributeError => e
10
+ raise InvalidData.new("Unknown attribute #{e.attribute}")
11
+ rescue ArgumentError => e
12
+ raise InvalidData.new('Data should be a Hash')
13
+ end
14
+ end
15
+
16
+ def validate!
17
+ raise InvalidData.new(self.errors.full_messages.join(', ')) unless valid?
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ module YlChat
2
+ class IdentityValidator < YlChat::BaseValidator
3
+ attr_accessor :uid, :meta
4
+
5
+ validates_presence_of :uid, :meta
6
+
7
+ validate :uid_type
8
+ validate :meta_type
9
+
10
+ def uid_type
11
+ errors.add(:uid, "is not a string") unless uid.is_a? String
12
+ end
13
+
14
+ def meta_type
15
+ errors.add(:meta, "is not a hash") unless meta.is_a? Hash
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module YlChat
2
+ class RoomValidator < YlChat::BaseValidator
3
+ attr_accessor :meta
4
+
5
+ validate :meta_type, if: 'meta.present?'
6
+
7
+ def meta_type
8
+ errors.add(:meta, "is not a hash") unless meta.is_a? Hash
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ YlChat::Engine.routes.draw do
2
+ post '/notifications', to: 'notifications#handle'
3
+ namespace :users do
4
+ get '/authorization', to: 'authorization#authorize'
5
+ end
6
+ namespace :rooms do
7
+ post '/creation', to: 'creation#authorize'
8
+ post '/connection', to: 'connection#authorize'
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ module YlChat
2
+ class InitializerGenerator < Rails::Generators::Base
3
+
4
+ INITIALIZER_PATH = 'config/initializers/yl_chat.rb'
5
+ TEMPLATE_PATH = '../templates/initializer.rb'
6
+
7
+ def create_initializer_file
8
+ create_file INITIALIZER_PATH, template
9
+ end
10
+
11
+ private
12
+
13
+ def template
14
+ @template ||= File.read(File.expand_path(TEMPLATE_PATH, __FILE__))
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ module YlChat
2
+ class PerformersGenerator < Rails::Generators::Base
3
+
4
+ PERFORMERS_PATH = 'app/yl_chat/'
5
+ TEMPLATE_PATH = '../templates/performers/'
6
+
7
+ def create_performers
8
+ create_performer 'connect_user_to_room.rb'
9
+ create_performer 'create_room.rb'
10
+ create_performer 'identify_user.rb'
11
+ create_performer 'notify.rb'
12
+ end
13
+
14
+ private
15
+
16
+ def create_performer(file_name)
17
+ path = PERFORMERS_PATH + file_name
18
+ template = performer_template(file_name)
19
+ create_file path, template
20
+ end
21
+
22
+ def performer_template(file_name)
23
+ path = TEMPLATE_PATH + file_name
24
+ File.read(File.expand_path(path, __FILE__))
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ YlChat.setup do |config|
2
+ # configure structure of meta here
3
+ config.identity_meta = [:name, :avatar]
4
+ config.room_meta = [:key]
5
+
6
+ # configure IP of a chat server to restrict access for other
7
+ config.trust_ips = []
8
+
9
+ # configure a URL of yl_chat application
10
+ config.yl_chat_url = 'http://yl_chat'
11
+ end
@@ -0,0 +1,18 @@
1
+ # This performer will be called every time when a user try to connect to a chat
2
+ # room.
3
+ #
4
+ # Implement the "authorized" method to return :true if this connection is
5
+ # allowed or :falce if forbidden.
6
+
7
+ class ConnectUserToRoom < YlChat::BaseConnectUserToRoom
8
+ attr_reader :user_token, :uid, :type, :participants, :meta, :title, :description
9
+ =begin
10
+ def authorized?
11
+ begin
12
+ TokenAuth::AuthenticationToken.find(user_token).entity.present?
13
+ rescue TokenAuth::FindEntityException => e
14
+ false
15
+ end
16
+ end
17
+ =end
18
+ end
@@ -0,0 +1,25 @@
1
+ # This performer will be called every time before a new chat room creation.
2
+ #
3
+ # Implement the "authorized" method to return :true if creation is allowed
4
+ # or :falce if forbidden.
5
+ #
6
+ # Implement the "perform" method to return a hash with the next schema:
7
+ # { meta: Hash }, where 'meta' is a set of data which will be attached to a
8
+ # created room.
9
+
10
+ class CreateRoom < YlChat::BaseCreateRoom
11
+ attr_reader :user_token, :type, :participant_uids, :meta, :title, :description
12
+ =begin
13
+ def authorized?
14
+ begin
15
+ TokenAuth::AuthenticationToken.find(user_token).entity.present?
16
+ rescue TokenAuth::FindEntityException => e
17
+ false
18
+ end
19
+ end
20
+
21
+ def perform
22
+ { meta: { key: 'value' } }
23
+ end
24
+ =end
25
+ end
@@ -0,0 +1,26 @@
1
+ # This performer will be called every time when a user try to connect to a chat.
2
+ #
3
+ # Implement the "authorized" method to return :true if this connection
4
+ # is allowed or :falce if forbidden.
5
+ #
6
+ # Implement the "perform" method to return a hash with the next schema:
7
+ # { uid: String, meta: Hash }, where 'uid' is the unique identifier of a
8
+ # current user and 'meta' is a set of user data which will be used in a chat.
9
+
10
+ class IdentifyUser < YlChat::BaseIdentifyUser
11
+ attr_reader :user_token
12
+ =begin
13
+ def authorized?
14
+ begin
15
+ @user = TokenAuth::AuthenticationToken.find(user_token).entity
16
+ @user.present?
17
+ rescue TokenAuth::FindEntityException => e
18
+ false
19
+ end
20
+ end
21
+
22
+ def perform
23
+ { uid: @user.id.to_s, meta: { name: @user.name } }
24
+ end
25
+ =end
26
+ end
@@ -0,0 +1,16 @@
1
+ # This performer will be called every time when offline recipients receive a
2
+ # new message.
3
+ #
4
+ # Implement the "perform" method to notify recipients about a new message in
5
+ # properly way.
6
+
7
+ class Notify < YlChat::BaseNotify
8
+ attr_reader :recipient_uids, :message
9
+ =begin
10
+ def perform
11
+ recipient_uids.each do |recipient_uid|
12
+ UserNotification::NewMessage.new(recipient_uid, message).notify_user
13
+ end
14
+ end
15
+ =end
16
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :yl_chat do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,26 @@
1
+ require "yl_chat/engine"
2
+
3
+ module YlChat
4
+ class Unauthorized < StandardError; end
5
+ class InvalidData < StandardError; end
6
+
7
+ @identity_meta = []
8
+ @room_meta = []
9
+ @trust_ips = []
10
+ @yl_chat_url = ''
11
+
12
+ class << self
13
+ attr_accessor :identity_meta
14
+ attr_accessor :room_meta
15
+ attr_accessor :trust_ips
16
+ attr_accessor :yl_chat_url
17
+
18
+ def setup
19
+ yield self
20
+ end
21
+
22
+ def routes(application)
23
+ application.mount YlChat::Engine => "/notifications"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ module YlChat
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace YlChat
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module YlChat
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yl_chat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Bohdan Nikolaienko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Description of YlChat.
42
+ email:
43
+ - bohdan.nikolaienko@yalantis.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - MIT-LICENSE
49
+ - README.md
50
+ - Rakefile
51
+ - app/controllers/yl_chat/application_controller.rb
52
+ - app/controllers/yl_chat/notifications_controller.rb
53
+ - app/controllers/yl_chat/rooms/connection_controller.rb
54
+ - app/controllers/yl_chat/rooms/creation_controller.rb
55
+ - app/controllers/yl_chat/users/authorization_controller.rb
56
+ - app/performers/yl_chat/base_connect_user_to_room.rb
57
+ - app/performers/yl_chat/base_create_room.rb
58
+ - app/performers/yl_chat/base_identify_user.rb
59
+ - app/performers/yl_chat/base_notify.rb
60
+ - app/performers/yl_chat/base_performer.rb
61
+ - app/performers/yl_chat/disconnect_user.rb
62
+ - app/validators/yl_chat/base_validator.rb
63
+ - app/validators/yl_chat/identity_validator.rb
64
+ - app/validators/yl_chat/room_validator.rb
65
+ - config/routes.rb
66
+ - lib/generators/yl_chat/initializer_generator.rb
67
+ - lib/generators/yl_chat/performers_generator.rb
68
+ - lib/generators/yl_chat/templates/initializer.rb
69
+ - lib/generators/yl_chat/templates/performers/connect_user_to_room.rb
70
+ - lib/generators/yl_chat/templates/performers/create_room.rb
71
+ - lib/generators/yl_chat/templates/performers/identify_user.rb
72
+ - lib/generators/yl_chat/templates/performers/notify.rb
73
+ - lib/tasks/yl_chat_tasks.rake
74
+ - lib/yl_chat.rb
75
+ - lib/yl_chat/engine.rb
76
+ - lib/yl_chat/version.rb
77
+ homepage:
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubygems_version: 3.0.2
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Summary of YlChat.
100
+ test_files: []