vkontakte 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/README.rdoc +18 -16
- data/lib/vkontakte.rb +7 -6
- data/lib/vkontakte/api/base.rb +5 -5
- data/lib/vkontakte/api/friends.rb +11 -11
- data/lib/vkontakte/api/groups.rb +23 -9
- data/lib/vkontakte/api/likes.rb +28 -0
- data/lib/vkontakte/api/secure.rb +20 -20
- data/lib/vkontakte/app/base.rb +36 -37
- data/lib/vkontakte/app/iframe.rb +17 -16
- data/lib/vkontakte/app/secure.rb +2 -2
- data/lib/vkontakte/app/user.rb +5 -5
- data/lib/vkontakte/version.rb +1 -1
- data/spec/api/friends_spec.rb +27 -26
- data/spec/api/groups_spec.rb +47 -26
- data/spec/api/likes_spec.rb +25 -0
- data/spec/api/photos_spec.rb +8 -7
- data/spec/api/profile_spec.rb +13 -8
- data/spec/api/secure_spec.rb +47 -46
- data/spec/apps/base_spec.rb +1 -0
- data/spec/apps/iframe_spec.rb +1 -0
- data/spec/apps/user_spec.rb +6 -5
- data/spec/spec_helper.rb +1 -0
- data/spec/vkontakte_spec.rb +1 -0
- metadata +62 -82
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
= Vkontakte
|
2
2
|
|
3
|
-
The easiest way to access Vkontakte API and some other utils.
|
3
|
+
The easiest way to access Vkontakte API and some other utils.
|
4
4
|
More info about API:
|
5
5
|
|
6
|
-
1. http://
|
6
|
+
1. http://vk.com/developers.php?oid=-1&p=%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F
|
7
7
|
|
8
|
-
2. http://
|
8
|
+
2. http://vk.com/developers.php?oid=-1&p=%D0%92%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2_%D0%BA_API
|
9
9
|
|
10
10
|
3. http://vk.com/developers.php?oid=-1&p=%D0%9F%D1%80%D0%B0%D0%B2%D0%B0_%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%B0_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9
|
11
11
|
|
12
12
|
== Install
|
13
|
-
|
13
|
+
|
14
14
|
gem 'vkontakte'
|
15
15
|
|
16
16
|
== Configure
|
@@ -22,7 +22,7 @@ More info about API:
|
|
22
22
|
config.debug = false
|
23
23
|
config.logger = File.open(Rails.root.join('log', 'vkontakte.log'), "a")
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
== Usage
|
27
27
|
|
28
28
|
=== User API by access_token
|
@@ -31,27 +31,29 @@ More info about API:
|
|
31
31
|
user.fetch # {"response"=>[{"uid"=>2592709, ...
|
32
32
|
|
33
33
|
Profile
|
34
|
-
|
35
|
-
user.profile.isAppUser
|
36
|
-
user.profile.getUserBalance
|
37
|
-
user.profile.getUserSettings
|
34
|
+
|
35
|
+
user.profile.isAppUser # {"response"=>"1"}
|
36
|
+
user.profile.getUserBalance
|
37
|
+
user.profile.getUserSettings
|
38
38
|
user.profile.likesGetList(:type => 'post')
|
39
39
|
|
40
40
|
Photos
|
41
41
|
|
42
|
-
user.photos.getAlbums
|
43
|
-
user.photos.getAlbumsCount
|
42
|
+
user.photos.getAlbums
|
43
|
+
user.photos.getAlbumsCount
|
44
44
|
user.photos.get(:aid => 'album_id')
|
45
45
|
|
46
46
|
Groups
|
47
47
|
|
48
|
-
user.groups.get
|
48
|
+
user.groups.get
|
49
49
|
user.groups.isMember(:gid => 'group_id')
|
50
|
+
user.groups.join(:gid => 1)
|
51
|
+
user.groups.leave(:gid => 1)
|
50
52
|
|
51
53
|
Friends
|
52
|
-
|
53
|
-
user.friends.get
|
54
|
-
user.friends.getOnline
|
54
|
+
|
55
|
+
user.friends.get
|
56
|
+
user.friends.getOnline
|
55
57
|
|
56
58
|
=== Secure API
|
57
59
|
|
@@ -66,7 +68,7 @@ Check if auth_key is valid:
|
|
66
68
|
def index
|
67
69
|
@app = Vkontakte::App::Iframe.new
|
68
70
|
@app.params = params
|
69
|
-
|
71
|
+
|
70
72
|
if @app.valid_auth_key?
|
71
73
|
session[:viewer_id] = params[:viewer_id]
|
72
74
|
else
|
data/lib/vkontakte.rb
CHANGED
@@ -5,26 +5,27 @@ require 'active_support/core_ext/string'
|
|
5
5
|
module Vkontakte
|
6
6
|
autoload :Config, 'vkontakte/config'
|
7
7
|
autoload :Utils, 'vkontakte/utils'
|
8
|
-
|
8
|
+
|
9
9
|
module App
|
10
10
|
autoload :Base, 'vkontakte/app/base'
|
11
11
|
autoload :Iframe, 'vkontakte/app/iframe'
|
12
12
|
autoload :Secure, 'vkontakte/app/secure'
|
13
13
|
autoload :User, 'vkontakte/app/user'
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
module Api
|
17
17
|
autoload :Base, 'vkontakte/api/base'
|
18
|
-
autoload :Photos, 'vkontakte/api/photos'
|
19
18
|
autoload :Friends, 'vkontakte/api/friends'
|
20
19
|
autoload :Groups, 'vkontakte/api/groups'
|
21
|
-
autoload :
|
20
|
+
autoload :Likes, 'vkontakte/api/likes'
|
21
|
+
autoload :Photos, 'vkontakte/api/photos'
|
22
22
|
autoload :Profile, 'vkontakte/api/profile'
|
23
|
+
autoload :Secure, 'vkontakte/api/secure'
|
23
24
|
end
|
24
|
-
|
25
|
+
|
25
26
|
mattr_accessor :config
|
26
27
|
@@config = Config.new
|
27
|
-
|
28
|
+
|
28
29
|
def self.setup(&block)
|
29
30
|
yield config
|
30
31
|
end
|
data/lib/vkontakte/api/base.rb
CHANGED
@@ -2,20 +2,20 @@ module Vkontakte
|
|
2
2
|
module Api
|
3
3
|
class Base
|
4
4
|
attr_accessor :app, :default_params
|
5
|
-
|
5
|
+
|
6
6
|
delegate :call, :to => :app
|
7
|
-
|
7
|
+
|
8
8
|
def initialize(base)
|
9
9
|
@app = base
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def default_params
|
13
13
|
@default_params ||= {}
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def call(method_name, params = {})
|
17
17
|
params = default_params.merge(params)
|
18
|
-
@app.call(method_name, params)
|
18
|
+
@app.call(method_name, params)['response']
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Vkontakte
|
2
2
|
module Api
|
3
3
|
module Friends
|
4
|
-
|
4
|
+
|
5
5
|
def self.included(base)
|
6
6
|
base.class_eval do
|
7
7
|
define_method :friends do
|
@@ -9,29 +9,29 @@ module Vkontakte
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
class Standart < Api::Base
|
14
|
-
# Возвращает список идентификаторов друзей пользователя или
|
15
|
-
# расширенную информацию о друзьях пользователя (при использовании параметра fields).
|
16
|
-
# http://
|
14
|
+
# Возвращает список идентификаторов друзей пользователя или
|
15
|
+
# расширенную информацию о друзьях пользователя (при использовании параметра fields).
|
16
|
+
# http://vk.com/developers.php?oid=-1&p=friends.get
|
17
17
|
#
|
18
18
|
def get(options = {})
|
19
19
|
call('friends.get', options)
|
20
20
|
end
|
21
|
-
|
22
|
-
# Возвращает список идентификаторов друзей текущего пользователя, которые установили данное приложение.
|
21
|
+
|
22
|
+
# Возвращает список идентификаторов друзей текущего пользователя, которые установили данное приложение.
|
23
23
|
#
|
24
24
|
def getAppUsers(options = {})
|
25
25
|
call('friends.getAppUsers', options)
|
26
26
|
end
|
27
|
-
|
28
|
-
# Возвращает список идентификаторов, находящихся на сайте друзей, текущего пользователя.
|
27
|
+
|
28
|
+
# Возвращает список идентификаторов, находящихся на сайте друзей, текущего пользователя.
|
29
29
|
#
|
30
30
|
def getOnline(options = {})
|
31
31
|
call('friends.getOnline', options)
|
32
32
|
end
|
33
|
-
|
34
|
-
# Возвращает список идентификаторов общих друзей между парой пользователей.
|
33
|
+
|
34
|
+
# Возвращает список идентификаторов общих друзей между парой пользователей.
|
35
35
|
#
|
36
36
|
def getMutual(options = {})
|
37
37
|
call('friends.getMutual', options)
|
data/lib/vkontakte/api/groups.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Vkontakte
|
2
2
|
module Api
|
3
3
|
module Groups
|
4
|
-
|
4
|
+
|
5
5
|
def self.included(base)
|
6
6
|
base.class_eval do
|
7
7
|
define_method :groups do
|
@@ -9,32 +9,46 @@ module Vkontakte
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
class Standart < Api::Base
|
14
14
|
# Возвращает список групп указанного пользователя.
|
15
|
-
# http://
|
15
|
+
# http://vk.com/developers.php?oid=-1&p=groups.get
|
16
16
|
#
|
17
17
|
def get(options = {})
|
18
18
|
call('groups.get', options)
|
19
19
|
end
|
20
|
-
|
21
|
-
# Возвращает информацию о заданной группе или о нескольких группах.
|
20
|
+
|
21
|
+
# Возвращает информацию о заданной группе или о нескольких группах.
|
22
22
|
#
|
23
23
|
def getById(options = {})
|
24
24
|
call('groups.getById', options)
|
25
25
|
end
|
26
|
-
|
27
|
-
# Возвращает информацию о том является ли пользователь участником заданной группы.
|
26
|
+
|
27
|
+
# Возвращает информацию о том является ли пользователь участником заданной группы.
|
28
28
|
#
|
29
29
|
def isMember(options = {})
|
30
30
|
call('groups.isMember', options)
|
31
31
|
end
|
32
|
-
|
33
|
-
# Возвращает список участников группы.
|
32
|
+
|
33
|
+
# Возвращает список участников группы.
|
34
34
|
#
|
35
35
|
def getMembers(options = {})
|
36
36
|
call('groups.getMembers', options)
|
37
37
|
end
|
38
|
+
|
39
|
+
# Добавляет как участника группы
|
40
|
+
# http://vk.com/developers.php?o=-1&p=groups.join
|
41
|
+
#
|
42
|
+
def join(options = {})
|
43
|
+
call('groups.join', options)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Добавляет как участника группы
|
47
|
+
# http://vk.com/developers.php?o=-1&p=groups.leave
|
48
|
+
#
|
49
|
+
def leave(options = {})
|
50
|
+
call('groups.leave', options)
|
51
|
+
end
|
38
52
|
end
|
39
53
|
end
|
40
54
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Vkontakte
|
2
|
+
module Api
|
3
|
+
module Likes
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
define_method :likes do
|
8
|
+
@likes ||= Standart.new(self)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Standart < Api::Base
|
14
|
+
# http://vk.com/developers.php?oid=-1&p=likes.getList
|
15
|
+
#
|
16
|
+
def getList(options = {})
|
17
|
+
call('likes.getList', options)
|
18
|
+
end
|
19
|
+
|
20
|
+
# http://vk.com/developers.php?o=-1&p=likes.isLiked
|
21
|
+
#
|
22
|
+
def isLiked(options = {})
|
23
|
+
call('likes.isLiked', options)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/vkontakte/api/secure.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Vkontakte
|
2
2
|
module Api
|
3
3
|
module Secure
|
4
|
-
|
4
|
+
|
5
5
|
def self.included(base)
|
6
6
|
base.class_eval do
|
7
7
|
define_method :secure do
|
@@ -9,62 +9,62 @@ module Vkontakte
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
class Standart < Api::Base
|
14
|
-
|
14
|
+
|
15
15
|
def default_options
|
16
|
-
{
|
17
|
-
:timestamp => Time.now.utc.to_i,
|
16
|
+
{
|
17
|
+
:timestamp => Time.now.utc.to_i,
|
18
18
|
:random => Kernel.rand(10000),
|
19
|
-
:client_secret => Vkontakte.config.app_secret
|
19
|
+
:client_secret => Vkontakte.config.app_secret
|
20
20
|
}
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Отправляет уведомление пользователю.
|
24
|
-
# http://
|
24
|
+
# http://vk.com/developers.php?oid=-1&p=secure.sendNotification
|
25
25
|
#
|
26
26
|
def sendNotification(options = {})
|
27
27
|
options = default_options.merge(options)
|
28
28
|
call('secure.sendNotification', options)
|
29
29
|
end
|
30
|
-
|
31
|
-
# Возвращает платежный баланс (счет) приложения в сотых долях голоса.
|
30
|
+
|
31
|
+
# Возвращает платежный баланс (счет) приложения в сотых долях голоса.
|
32
32
|
#
|
33
33
|
def getAppBalance(options = {})
|
34
34
|
options = default_options.merge(options)
|
35
35
|
call("secure.getAppBalance", options)
|
36
36
|
end
|
37
|
-
|
38
|
-
# Возвращает баланс пользователя на счету приложения в сотых долях голоса.
|
37
|
+
|
38
|
+
# Возвращает баланс пользователя на счету приложения в сотых долях голоса.
|
39
39
|
#
|
40
40
|
def getBalance(options = {})
|
41
41
|
options = default_options.merge(options)
|
42
42
|
call("secure.getBalance", options)
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
# Списывает голоса со счета пользователя на счет приложения (в сотых долях).
|
46
46
|
#
|
47
47
|
def withdrawVotes(options = {})
|
48
48
|
options = default_options.merge(options)
|
49
49
|
call("secure.withdrawVotes", options)
|
50
50
|
end
|
51
|
-
|
52
|
-
# Выводит историю транзакций по переводу голосов между пользователями и приложением.
|
51
|
+
|
52
|
+
# Выводит историю транзакций по переводу голосов между пользователями и приложением.
|
53
53
|
#
|
54
54
|
def getTransactionsHistory(options = {})
|
55
55
|
options = default_options.merge(options)
|
56
56
|
call("secure.getTransactionsHistory", options)
|
57
57
|
end
|
58
|
-
|
59
|
-
# Поднимает пользователю рейтинг от имени приложения.
|
58
|
+
|
59
|
+
# Поднимает пользователю рейтинг от имени приложения.
|
60
60
|
#
|
61
61
|
def addRating(options = {})
|
62
62
|
options = default_options.merge(options)
|
63
63
|
call("secure.addRating", options)
|
64
64
|
end
|
65
|
-
|
66
|
-
# Устанавливает счетчик, который выводится пользователю жирным шрифтом в левом меню.
|
67
|
-
# Это происходит только в том случае, если пользователь добавил приложение в левое меню со страницы приложения,
|
65
|
+
|
66
|
+
# Устанавливает счетчик, который выводится пользователю жирным шрифтом в левом меню.
|
67
|
+
# Это происходит только в том случае, если пользователь добавил приложение в левое меню со страницы приложения,
|
68
68
|
# списка приложений или настроек.
|
69
69
|
#
|
70
70
|
def setCounter(options = {})
|
data/lib/vkontakte/app/base.rb
CHANGED
@@ -4,84 +4,83 @@ module Vkontakte
|
|
4
4
|
module App
|
5
5
|
class Base
|
6
6
|
include ::HTTParty
|
7
|
-
|
8
|
-
base_uri "https://api.
|
7
|
+
|
8
|
+
base_uri "https://api.vk.com"
|
9
9
|
format Vkontakte.config.format
|
10
10
|
debug_output Vkontakte.config.logger
|
11
|
-
|
11
|
+
|
12
12
|
attr_accessor :auth
|
13
|
-
|
13
|
+
|
14
14
|
def initialize(app_id = nil, app_secret = nil)
|
15
15
|
@config = {
|
16
|
-
:app_id => (app_id || Vkontakte.config.app_id),
|
16
|
+
:app_id => (app_id || Vkontakte.config.app_id),
|
17
17
|
:app_secret => (app_secret || Vkontakte.config.app_secret)
|
18
18
|
}
|
19
19
|
end
|
20
|
-
|
21
|
-
# http://
|
20
|
+
|
21
|
+
# http://vk.com/developers.php?oid=-1&p=%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F
|
22
22
|
# Site auth:
|
23
|
-
# https://
|
23
|
+
# https://oauth.vk.com/access_token?
|
24
24
|
# client_id=APP_ID&
|
25
25
|
# client_secret=APP_SECRET&
|
26
26
|
# code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a
|
27
27
|
#
|
28
28
|
# Server auth:
|
29
|
-
# https://
|
30
|
-
# client_id=' + APP_ID + '&client_secret=' + APP_SECRET + '&grant_type=client_credentials'
|
29
|
+
# https://oauth.vk.com/access_token?client_id=' + APP_ID + '&client_secret=' + APP_SECRET + '&grant_type=client_credentials'
|
31
30
|
#
|
32
31
|
# Response:
|
33
32
|
# {"access_token":"533bacf01e11f55b536a565b57531ac114461ae8736d6506a3", "expires_in":43200, "user_id":6492}
|
34
33
|
#
|
35
|
-
def authorize(code = nil,
|
36
|
-
|
37
|
-
:client_id => @config[:app_id],
|
34
|
+
def authorize(code = nil, params = {})
|
35
|
+
params = {
|
36
|
+
:client_id => @config[:app_id],
|
38
37
|
:client_secret => @config[:app_secret],
|
39
38
|
:code => code
|
40
|
-
}.merge(
|
41
|
-
|
39
|
+
}.merge(params)
|
40
|
+
|
42
41
|
# Server auth
|
43
|
-
if
|
44
|
-
|
45
|
-
|
42
|
+
if params[:code].blank?
|
43
|
+
params.delete(:code)
|
44
|
+
params[:grant_type] = 'client_credentials'
|
46
45
|
end
|
47
|
-
|
48
|
-
@auth = get("/
|
46
|
+
|
47
|
+
@auth = get("/access_token", {:query => params, :base_uri => "https://oauth.vk.com"})
|
49
48
|
end
|
50
|
-
|
49
|
+
|
51
50
|
# Check if app is authorized
|
52
51
|
#
|
53
52
|
def authorized?
|
54
53
|
auth && auth['access_token']
|
55
54
|
end
|
56
|
-
|
57
|
-
# Выполнение запросов к API
|
58
|
-
# https://api.
|
55
|
+
|
56
|
+
# Выполнение запросов к API
|
57
|
+
# https://api.vk.com/method/METHOD_NAME?PARAMETERS&access_token=ACCESS_TOKEN
|
59
58
|
# METHOD_NAME – название метода из списка функций API,
|
60
59
|
# PARAMETERS – параметры соответствующего метода API,
|
61
|
-
# ACCESS_TOKEN – ключ доступа, полученный в результате успешной авторизации приложения.
|
60
|
+
# ACCESS_TOKEN – ключ доступа, полученный в результате успешной авторизации приложения.
|
62
61
|
# Example:
|
63
|
-
# https://api.
|
62
|
+
# https://api.vk.com/method/getProfiles?uid=66748&access_token=533bacf01e11f55b536a565b57531ac114461ae8736d6506a3
|
64
63
|
#
|
65
|
-
# More info: http://
|
64
|
+
# More info: http://vk.com/developers.php?oid=-1&p=%D0%92%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2_%D0%BA_API
|
66
65
|
#
|
67
66
|
def call(method_name, params = {})
|
68
67
|
params[:access_token] ||= @auth['access_token'] if authorized?
|
69
|
-
|
68
|
+
|
70
69
|
unless params[:access_token].blank?
|
71
|
-
get("/method/#{method_name}", params)
|
70
|
+
get("/method/#{method_name}", {:query => params, :base_uri => "https://api.vk.com"})
|
72
71
|
else
|
73
72
|
raise VkException.new(method_name, {
|
74
|
-
:error => 'access_token is blank',
|
73
|
+
:error => 'access_token is blank',
|
75
74
|
:error_description => 'You need first authorize app before call API methods.'
|
76
75
|
})
|
77
76
|
end
|
78
77
|
end
|
79
|
-
|
78
|
+
|
80
79
|
protected
|
81
|
-
|
80
|
+
|
82
81
|
def get(method_name, options = {})
|
83
|
-
response = self.class.get(method_name,
|
84
|
-
|
82
|
+
response = self.class.get(method_name, options)
|
83
|
+
|
85
84
|
if response['error']
|
86
85
|
raise VkException.new(method_name, response)
|
87
86
|
else
|
@@ -89,7 +88,7 @@ module Vkontakte
|
|
89
88
|
end
|
90
89
|
end
|
91
90
|
end
|
92
|
-
|
91
|
+
|
93
92
|
# Errors
|
94
93
|
# {"error":"invalid_grant","error_description":"Code is expired."}
|
95
94
|
# {"error":{"error_code":5,"error_msg":"User authorization failed: invalid application type","request_params":[{"key":"oauth","value":"1"},{"key":"method","value":"getProfiles"},{"key":"uid","value":"66748"},{"key":"access_token","value":"533bacf01e11f55b536a565b57531ac114461ae8736d6506a3"}]}}
|
@@ -98,13 +97,13 @@ module Vkontakte
|
|
98
97
|
def initialize(method_name, options)
|
99
98
|
error_hash = options.symbolize_keys
|
100
99
|
@message = "Error in #{method_name}: "
|
101
|
-
|
100
|
+
|
102
101
|
if error_hash[:error].is_a?(Hash)
|
103
102
|
@message += error_hash[:error].inspect
|
104
103
|
else
|
105
104
|
@message += [error_hash[:error], error_hash[:error_description]].join('-')
|
106
105
|
end
|
107
|
-
|
106
|
+
|
108
107
|
super @message
|
109
108
|
end
|
110
109
|
end
|