matrix_sdk 2.1.2 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -41,9 +41,13 @@ module MatrixSdk
41
41
  end
42
42
 
43
43
  class MatrixNotAuthorizedError < MatrixRequestError; end
44
+
44
45
  class MatrixForbiddenError < MatrixRequestError; end
46
+
45
47
  class MatrixNotFoundError < MatrixRequestError; end
48
+
46
49
  class MatrixConflictError < MatrixRequestError; end
50
+
47
51
  class MatrixTooManyRequestsError < MatrixRequestError; end
48
52
 
49
53
  # An error raised when errors occur in the connection layer
@@ -12,7 +12,7 @@ module MatrixSdk
12
12
 
13
13
  # TODO: Community-as-a-Room / Profile-as-a-Room, in case they're going for room aliases
14
14
  @sigil = identifier[0]
15
- @localpart, @domain, @port = identifier[1..-1].split(':')
15
+ @localpart, @domain, @port = identifier[1..].split(':')
16
16
  @port = @port.to_i if @port
17
17
 
18
18
  raise ArgumentError, 'Identifier is not a valid MXID' unless valid?
@@ -32,13 +32,13 @@ module MatrixSdk
32
32
  #
33
33
  # @return [String]
34
34
  def homeserver
35
- port_s = port ? ':' + port.to_s : ''
35
+ port_s = port ? ":#{port}" : ''
36
36
  domain ? domain + port_s : ''
37
37
  end
38
38
 
39
39
  # Gets the homserver part of the ID as a suffix (':homeserver')
40
40
  def homeserver_suffix
41
- ':' + homeserver if domain
41
+ ":#{homeserver}" if domain
42
42
  end
43
43
 
44
44
  def to_s
@@ -49,18 +49,13 @@ module MatrixSdk
49
49
  #
50
50
  # @return [Symbol] The MXID type, one of (:user_id, :room_id, :event_id, :group_id, or :room_alias)
51
51
  def type
52
- case sigil
53
- when '@'
54
- :user_id
55
- when '!'
56
- :room_id
57
- when '$'
58
- :event_id
59
- when '+'
60
- :group_id
61
- when '#'
62
- :room_alias
63
- end
52
+ {
53
+ '@' => :user_id,
54
+ '!' => :room_id,
55
+ '$' => :event_id,
56
+ '+' => :group_id,
57
+ '#' => :room_alias
58
+ }[sigil]
64
59
  end
65
60
 
66
61
  # Checks if the ID is valid
@@ -105,5 +100,45 @@ module MatrixSdk
105
100
  def room_alias?
106
101
  type == :room_alias
107
102
  end
103
+
104
+ # Converts the MXID to a matrix: URI according to MSC2312
105
+ # @param event_id [String,MXID] An event ID to append to the URI (only valid for rooms)
106
+ # @param action [String,Symbol] The action that should be requested
107
+ # @param via [Array[String]] The list of servers to use for a join
108
+ # @see https://github.com/matrix-org/matrix-doc/blob/master/proposals/2312-matrix-uri.md
109
+ def to_uri(event_id: nil, action: nil, via: nil)
110
+ uri = ''
111
+
112
+ case sigil
113
+ when '@'
114
+ raise ArgumentError, "can't provide via for user URIs" if via
115
+ raise ArgumentError, "can't provide event_id for user URIs" if event_id
116
+
117
+ uri += 'u'
118
+ when '#'
119
+ uri += 'r'
120
+ when '!'
121
+ uri += 'roomid'
122
+ else
123
+ raise ArgumentError, "this MXID can't be converted to a URI"
124
+ end
125
+
126
+ uri = "matrix:#{uri}/#{localpart}#{homeserver_suffix}"
127
+
128
+ uri += "/e/#{event_id.to_s.delete_prefix('$')}" if event_id
129
+ query = []
130
+ query << "action=#{action}" if action
131
+ [via].flatten.compact.each { |v| query << "via=#{v}" }
132
+
133
+ uri += "?#{query.join('&')}" unless query.empty?
134
+
135
+ URI(uri)
136
+ end
137
+
138
+ # Check if two MXIDs are equal
139
+ # @return [Boolean]
140
+ def ==(other)
141
+ to_s == other.to_s
142
+ end
108
143
  end
109
144
  end
@@ -584,7 +584,7 @@ module MatrixSdk::Protocols::CS
584
584
  }
585
585
  content.merge!(params.fetch(:extra_content)) if params.key? :extra_content
586
586
 
587
- send_message_event(room_id, 'm.room.message', content, params)
587
+ send_message_event(room_id, 'm.room.message', content, **params)
588
588
  end
589
589
 
590
590
  # Send a geographic location to a room
@@ -610,7 +610,7 @@ module MatrixSdk::Protocols::CS
610
610
  content[:info][:thumbnail_url] = params.delete(:thumbnail_url) if params.key? :thumbnail_url
611
611
  content[:info][:thumbnail_info] = params.delete(:thumbnail_info) if params.key? :thumbnail_info
612
612
 
613
- send_message_event(room_id, 'm.room.message', content, params)
613
+ send_message_event(room_id, 'm.room.message', content, **params)
614
614
  end
615
615
 
616
616
  # Send a plaintext message to a room
@@ -628,7 +628,7 @@ module MatrixSdk::Protocols::CS
628
628
  msgtype: params.delete(:msg_type) { 'm.text' },
629
629
  body: message
630
630
  }
631
- send_message_event(room_id, 'm.room.message', content, params)
631
+ send_message_event(room_id, 'm.room.message', content, **params)
632
632
  end
633
633
 
634
634
  # Send a plaintext emote to a room
@@ -646,7 +646,7 @@ module MatrixSdk::Protocols::CS
646
646
  msgtype: params.delete(:msg_type) { 'm.emote' },
647
647
  body: emote
648
648
  }
649
- send_message_event(room_id, 'm.room.message', content, params)
649
+ send_message_event(room_id, 'm.room.message', content, **params)
650
650
  end
651
651
 
652
652
  # Send a plaintext notice to a room
@@ -664,7 +664,7 @@ module MatrixSdk::Protocols::CS
664
664
  msgtype: params.delete(:msg_type) { 'm.notice' },
665
665
  body: notice
666
666
  }
667
- send_message_event(room_id, 'm.room.message', content, params)
667
+ send_message_event(room_id, 'm.room.message', content, **params)
668
668
  end
669
669
 
670
670
  # Report an event in a room
@@ -702,7 +702,7 @@ module MatrixSdk::Protocols::CS
702
702
  # @return [Response] A response hash with the message information containing :start, :end, and :chunk fields
703
703
  # @see https://matrix.org/docs/spec/client_server/latest.html#get-matrix-client-r0-rooms-roomid-messages
704
704
  # The Matrix Spec, for more information about the call and response
705
- def get_room_messages(room_id, token, direction, limit: 10, **params)
705
+ def get_room_messages(room_id, token, direction:, limit: 10, **params)
706
706
  query = {
707
707
  from: token,
708
708
  dir: direction,
@@ -767,6 +767,30 @@ module MatrixSdk::Protocols::CS
767
767
  request(:get, :client_r0, "/rooms/#{room_id}/state", query: query)
768
768
  end
769
769
 
770
+ # Retrieves number of events that happened just before and after the specified event
771
+ #
772
+ # @param room_id [MXID,String] The room to get events from.
773
+ # @param event_id [MXID,String] The event to get context around.
774
+ # @option params [Integer] :limit (10) The limit of messages to retrieve
775
+ # @option params [String] :filter A filter to limit the retrieval to
776
+ # @return [Response] A response hash with contextual event information
777
+ # @see https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-rooms-roomid-context-eventid
778
+ # The Matrix Spec, for more information about the call and response
779
+ # @example Find event context with filter and limit specified
780
+ # api.get_room_event_context('#room:example.com', '$event_id:example.com', filter: { types: ['m.room.message'] }.to_json, limit: 20)
781
+ def get_room_event_context(room_id, event_id, **params)
782
+ query = {}
783
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
784
+
785
+ query[:limit] = params.fetch(:limit) if params.key? :limit
786
+ query[:filter] = params.fetch(:filter) if params.key? :filter
787
+
788
+ room_id = ERB::Util.url_encode room_id.to_s
789
+ event_id = ERB::Util.url_encode event_id.to_s
790
+
791
+ request(:get, :client_r0, "/rooms/#{room_id}/context/#{event_id}", query: query)
792
+ end
793
+
770
794
  ## Specialized getters for specced state
771
795
  #
772
796
 
@@ -780,7 +804,7 @@ module MatrixSdk::Protocols::CS
780
804
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-name
781
805
  # The Matrix Spec, for more information about the event and data
782
806
  def get_room_name(room_id, **params)
783
- get_room_state(room_id, 'm.room.name', params)
807
+ get_room_state(room_id, 'm.room.name', **params)
784
808
  end
785
809
 
786
810
  # Sets the display name of a room
@@ -795,7 +819,7 @@ module MatrixSdk::Protocols::CS
795
819
  content = {
796
820
  name: name
797
821
  }
798
- send_state_event(room_id, 'm.room.name', content, params)
822
+ send_state_event(room_id, 'm.room.name', content, **params)
799
823
  end
800
824
 
801
825
  # Gets the current topic of a room
@@ -808,7 +832,7 @@ module MatrixSdk::Protocols::CS
808
832
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-topic
809
833
  # The Matrix Spec, for more information about the event and data
810
834
  def get_room_topic(room_id, **params)
811
- get_room_state(room_id, 'm.room.topic', params)
835
+ get_room_state(room_id, 'm.room.topic', **params)
812
836
  end
813
837
 
814
838
  # Sets the topic of a room
@@ -823,7 +847,7 @@ module MatrixSdk::Protocols::CS
823
847
  content = {
824
848
  topic: topic
825
849
  }
826
- send_state_event(room_id, 'm.room.topic', content, params)
850
+ send_state_event(room_id, 'm.room.topic', content, **params)
827
851
  end
828
852
 
829
853
  # Gets the current avatar URL of a room
@@ -836,7 +860,7 @@ module MatrixSdk::Protocols::CS
836
860
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-avatar
837
861
  # The Matrix Spec, for more information about the event and data
838
862
  def get_room_avatar(room_id, **params)
839
- get_room_state(room_id, 'm.room.avatar', params)
863
+ get_room_state(room_id, 'm.room.avatar', **params)
840
864
  end
841
865
 
842
866
  # Sets the avatar URL for a room
@@ -851,7 +875,7 @@ module MatrixSdk::Protocols::CS
851
875
  content = {
852
876
  url: url
853
877
  }
854
- send_state_event(room_id, 'm.room.avatar', content, params)
878
+ send_state_event(room_id, 'm.room.avatar', content, **params)
855
879
  end
856
880
 
857
881
  # Gets a list of current aliases of a room
@@ -878,7 +902,7 @@ module MatrixSdk::Protocols::CS
878
902
  # .compact
879
903
  # # => ["#synapse:im.kabi.tk", "#synapse:matrix.org", "#synapse-community:matrix.org", "#synapse-ops:matrix.org", "#synops:matrix.org", ...
880
904
  def get_room_aliases(room_id, **params)
881
- get_room_state(room_id, 'm.room.aliases', params)
905
+ get_room_state(room_id, 'm.room.aliases', **params)
882
906
  end
883
907
 
884
908
  # Gets a list of pinned events in a room
@@ -891,7 +915,7 @@ module MatrixSdk::Protocols::CS
891
915
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-pinned-events
892
916
  # The Matrix Spec, for more information about the event and data
893
917
  def get_room_pinned_events(room_id, **params)
894
- get_room_state(room_id, 'm.room.pinned_events', params)
918
+ get_room_state(room_id, 'm.room.pinned_events', **params)
895
919
  end
896
920
 
897
921
  # Sets the list of pinned events in a room
@@ -906,7 +930,7 @@ module MatrixSdk::Protocols::CS
906
930
  content = {
907
931
  pinned: events
908
932
  }
909
- send_state_event(room_id, 'm.room.pinned_events', content, params)
933
+ send_state_event(room_id, 'm.room.pinned_events', content, **params)
910
934
  end
911
935
 
912
936
  # Gets the configured power levels for a room
@@ -918,7 +942,7 @@ module MatrixSdk::Protocols::CS
918
942
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-power-levels
919
943
  # The Matrix Spec, for more information about the event and data
920
944
  def get_room_power_levels(room_id, **params)
921
- get_room_state(room_id, 'm.room.power_levels', params)
945
+ get_room_state(room_id, 'm.room.power_levels', **params)
922
946
  end
923
947
  alias get_power_levels get_room_power_levels
924
948
 
@@ -932,7 +956,7 @@ module MatrixSdk::Protocols::CS
932
956
  # The Matrix Spec, for more information about the event and data
933
957
  def set_room_power_levels(room_id, content, **params)
934
958
  content[:events] = {} unless content.key? :events
935
- send_state_event(room_id, 'm.room.power_levels', content, params)
959
+ send_state_event(room_id, 'm.room.power_levels', content, **params)
936
960
  end
937
961
  alias set_power_levels set_room_power_levels
938
962
 
@@ -945,7 +969,7 @@ module MatrixSdk::Protocols::CS
945
969
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-join-rules
946
970
  # The Matrix Spec, for more information about the event and data
947
971
  def get_room_join_rules(room_id, **params)
948
- get_room_state(room_id, 'm.room.join_rules', params)
972
+ get_room_state(room_id, 'm.room.join_rules', **params)
949
973
  end
950
974
 
951
975
  # Sets the join rules for a room
@@ -961,7 +985,7 @@ module MatrixSdk::Protocols::CS
961
985
  join_rule: join_rule
962
986
  }
963
987
 
964
- send_state_event(room_id, 'm.room.join_rules', content, params)
988
+ send_state_event(room_id, 'm.room.join_rules', content, **params)
965
989
  end
966
990
 
967
991
  # Gets the guest access settings for a room
@@ -973,7 +997,7 @@ module MatrixSdk::Protocols::CS
973
997
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-guest-access
974
998
  # The Matrix Spec, for more information about the event and data
975
999
  def get_room_guest_access(room_id, **params)
976
- get_room_state(room_id, 'm.room.guest_access', params)
1000
+ get_room_state(room_id, 'm.room.guest_access', **params)
977
1001
  end
978
1002
 
979
1003
  # Sets the guest access settings for a room
@@ -989,7 +1013,7 @@ module MatrixSdk::Protocols::CS
989
1013
  guest_access: guest_access
990
1014
  }
991
1015
 
992
- send_state_event(room_id, 'm.room.guest_access', content, params)
1016
+ send_state_event(room_id, 'm.room.guest_access', content, **params)
993
1017
  end
994
1018
 
995
1019
  # Gets the creation configuration object for a room
@@ -1001,7 +1025,7 @@ module MatrixSdk::Protocols::CS
1001
1025
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-create
1002
1026
  # The Matrix Spec, for more information about the event and data
1003
1027
  def get_room_creation_info(room_id, **params)
1004
- get_room_state(room_id, 'm.room.create', params)
1028
+ get_room_state(room_id, 'm.room.create', **params)
1005
1029
  end
1006
1030
 
1007
1031
  # Gets the encryption configuration for a room
@@ -1013,7 +1037,7 @@ module MatrixSdk::Protocols::CS
1013
1037
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-encryption
1014
1038
  # The Matrix Spec, for more information about the event and data
1015
1039
  def get_room_encryption_settings(room_id, **params)
1016
- get_room_state(room_id, 'm.room.encryption', params)
1040
+ get_room_state(room_id, 'm.room.encryption', **params)
1017
1041
  end
1018
1042
 
1019
1043
  # Sets the encryption configuration for a room
@@ -1032,7 +1056,7 @@ module MatrixSdk::Protocols::CS
1032
1056
  rotation_period_ms: rotation_period_ms,
1033
1057
  rotation_period_msgs: rotation_period_msgs
1034
1058
  }
1035
- send_state_event(room_id, 'm.room.encryption', content, params)
1059
+ send_state_event(room_id, 'm.room.encryption', content, **params)
1036
1060
  end
1037
1061
 
1038
1062
  # Gets the history availabiilty for a room
@@ -1044,7 +1068,7 @@ module MatrixSdk::Protocols::CS
1044
1068
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-history-visibility
1045
1069
  # The Matrix Spec, for more information about the event and data
1046
1070
  def get_room_history_visibility(room_id, **params)
1047
- get_room_state(room_id, 'm.room.history_visibility', params)
1071
+ get_room_state(room_id, 'm.room.history_visibility', **params)
1048
1072
  end
1049
1073
 
1050
1074
  # Sets the history availability for a room
@@ -1060,7 +1084,7 @@ module MatrixSdk::Protocols::CS
1060
1084
  history_visibility: visibility
1061
1085
  }
1062
1086
 
1063
- send_state_event(room_id, 'm.room.history_visibility', content, params)
1087
+ send_state_event(room_id, 'm.room.history_visibility', content, **params)
1064
1088
  end
1065
1089
 
1066
1090
  # Gets the server ACLs for a room
@@ -1072,7 +1096,7 @@ module MatrixSdk::Protocols::CS
1072
1096
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-server-acl
1073
1097
  # The Matrix Spec, for more information about the event and data
1074
1098
  def get_room_server_acl(room_id, **params)
1075
- get_room_state(room_id, 'm.room.server_acl', params)
1099
+ get_room_state(room_id, 'm.room.server_acl', **params)
1076
1100
  end
1077
1101
 
1078
1102
  # Sets the server ACL configuration for a room
@@ -1085,14 +1109,14 @@ module MatrixSdk::Protocols::CS
1085
1109
  # @return [Response] The resulting state event
1086
1110
  # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-guest-server-acl
1087
1111
  # The Matrix Spec, for more information about the event and data
1088
- def set_room_server_acl(room_id, allow_ip_literals: false, allow:, deny:, **params)
1112
+ def set_room_server_acl(room_id, allow:, deny:, allow_ip_literals: false, **params)
1089
1113
  content = {
1090
1114
  allow_ip_literals: allow_ip_literals,
1091
1115
  allow: allow,
1092
1116
  deny: deny
1093
1117
  }
1094
1118
 
1095
- send_state_event(room_id, 'm.room.server_acl', content, params)
1119
+ send_state_event(room_id, 'm.room.server_acl', content, **params)
1096
1120
  end
1097
1121
 
1098
1122
  def leave_room(room_id, **params)
@@ -1411,7 +1435,7 @@ module MatrixSdk::Protocols::CS
1411
1435
  # api.set_avatar_url(api.whoami?[:user_id], mxc)
1412
1436
  #
1413
1437
  # @param [String,MXID] user_id The ID of the user to set the avatar for
1414
- # @param [String,URI::MATRIX] url The new avatar URL, should be a mxc:// URL
1438
+ # @param [String,URI::MXC] url The new avatar URL, should be a mxc:// URL
1415
1439
  # @return [Response] An empty response hash if the change was successful
1416
1440
  # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-profile-userid-avatar-url
1417
1441
  # The Matrix Spec, for more information about the event and data
@@ -1521,7 +1545,7 @@ module MatrixSdk::Protocols::CS
1521
1545
  # # => #<URI::HTTPS https://matrix.org/_matrix/media/r0/download/example.com/media_hash>
1522
1546
  def get_download_url(mxcurl, source: nil, **_params)
1523
1547
  mxcurl = URI.parse(mxcurl.to_s) unless mxcurl.is_a? URI
1524
- raise 'Not a mxc:// URL' unless mxcurl.is_a? URI::MATRIX
1548
+ raise 'Not a mxc:// URL' unless mxcurl.is_a? URI::MXC
1525
1549
 
1526
1550
  if source
1527
1551
  source = "https://#{source}" unless source.include? '://'
@@ -1712,7 +1736,7 @@ module MatrixSdk::Protocols::CS
1712
1736
  # # => { :device_keys => { :'@alice:example.com' => { :ABCDEFGHIJ => { ...
1713
1737
  # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-keys-query
1714
1738
  # The Matrix Spec, for more information about the parameters and data
1715
- def keys_query(timeout: nil, device_keys:, token: nil, **params)
1739
+ def keys_query(device_keys:, timeout: nil, token: nil, **params)
1716
1740
  body = {
1717
1741
  timeout: (timeout || 10) * 1000,
1718
1742
  device_keys: device_keys
@@ -1834,7 +1858,7 @@ module MatrixSdk::Protocols::CS
1834
1858
  # @return [Response] A response hash containing the full data of the requested push rule
1835
1859
  # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules-scope-kind-ruleid
1836
1860
  # The Matrix Spec, for more information about the parameters and data
1837
- def get_pushrule(scope: 'global', kind:, id:)
1861
+ def get_pushrule(kind:, id:, scope: 'global')
1838
1862
  scope = ERB::Util.url_encode scope.to_s
1839
1863
  kind = ERB::Util.url_encode kind.to_s
1840
1864
  id = ERB::Util.url_encode id.to_s
@@ -1850,7 +1874,7 @@ module MatrixSdk::Protocols::CS
1850
1874
  # @return [Response] A response hash containing an :enabled key for if the rule is enabled or not
1851
1875
  # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules-scope-kind-ruleid-enabled
1852
1876
  # The Matrix Spec, for more information about the parameters and data
1853
- def get_pushrule_enabled(scope: 'global', kind:, id:)
1877
+ def get_pushrule_enabled(kind:, id:, scope: 'global')
1854
1878
  scope = ERB::Util.url_encode scope.to_s
1855
1879
  kind = ERB::Util.url_encode kind.to_s
1856
1880
  id = ERB::Util.url_encode id.to_s
@@ -1867,7 +1891,7 @@ module MatrixSdk::Protocols::CS
1867
1891
  # @return [Response] An empty response hash if the push rule was enabled/disabled successfully
1868
1892
  # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-pushrules-scope-kind-ruleid-enabled
1869
1893
  # The Matrix Spec, for more information about the parameters and data
1870
- def set_pushrule_enabled(enabled, scope: 'global', kind:, id:)
1894
+ def set_pushrule_enabled(enabled, kind:, id:, scope: 'global')
1871
1895
  scope = ERB::Util.url_encode scope.to_s
1872
1896
  kind = ERB::Util.url_encode kind.to_s
1873
1897
  id = ERB::Util.url_encode id.to_s
@@ -1887,7 +1911,7 @@ module MatrixSdk::Protocols::CS
1887
1911
  # @return [Response] A response hash containing an :enabled key for if the rule is enabled or not
1888
1912
  # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules-scope-kind-ruleid-actions
1889
1913
  # The Matrix Spec, for more information about the parameters and data
1890
- def get_pushrule_actions(scope: 'global', kind:, id:)
1914
+ def get_pushrule_actions(kind:, id:, scope: 'global')
1891
1915
  scope = ERB::Util.url_encode scope.to_s
1892
1916
  kind = ERB::Util.url_encode kind.to_s
1893
1917
  id = ERB::Util.url_encode id.to_s
@@ -1904,7 +1928,7 @@ module MatrixSdk::Protocols::CS
1904
1928
  # @return [Response] An empty response hash if the push rule actions were modified successfully
1905
1929
  # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-pushrules-scope-kind-ruleid-actions
1906
1930
  # The Matrix Spec, for more information about the parameters and data
1907
- def set_pushrule_actions(actions, scope: 'global', kind:, id:)
1931
+ def set_pushrule_actions(actions, kind:, id:, scope: 'global')
1908
1932
  scope = ERB::Util.url_encode scope.to_s
1909
1933
  kind = ERB::Util.url_encode kind.to_s
1910
1934
  id = ERB::Util.url_encode id.to_s