@@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313See the License for the specific language governing permissions and
1414limitations under the License.
1515*/
16- import type { IMentions } from "../matrix.ts" ;
16+ import type { IContent , IMentions } from "../matrix.ts" ;
1717import type { RelationEvent } from "../types.ts" ;
1818import type { CallMembership } from "./CallMembership.ts" ;
1919
@@ -102,6 +102,46 @@ export type RTCNotificationType = "ring" | "notification";
102102 * May be any string, although `"audio"` and `"video"` are commonly accepted values.
103103 */
104104export type RTCCallIntent = "audio" | "video" | string ;
105+
106+ /**
107+ * This will check if the content has all the expected fields to be a valid IRTCNotificationContent.
108+ * It will also cap the lifetime to 120000ms if a higher value is provided.
109+ * @param content
110+ * @throws if the content is invalid
111+ * @returns a parsed IRTCNotificationContent
112+ */
113+ export function parseCallNotificationContent ( content : IContent ) : IRTCNotificationContent {
114+ if ( typeof content [ "m.mentions" ] !== "object" ) {
115+ throw new Error ( "Missing m.mentions" ) ;
116+ }
117+ if ( typeof content [ "notification_type" ] !== "string" ) {
118+ throw new Error ( "Missing or invalid notification_type" ) ;
119+ }
120+ if ( typeof content [ "sender_ts" ] !== "number" ) {
121+ throw new Error ( "Missing or invalid sender_ts" ) ;
122+ }
123+ if ( typeof content [ "lifetime" ] !== "number" ) {
124+ throw new Error ( "Missing or invalid lifetime" ) ;
125+ }
126+
127+ if ( content [ "decline_reason" ] && typeof content [ "decline_reason" ] !== "string" ) {
128+ throw new Error ( "Invalid decline_reason" ) ;
129+ }
130+ if ( content [ "relation" ] && content [ "relation" ] [ "rel_type" ] !== "m.reference" ) {
131+ throw new Error ( "Invalid relation" ) ;
132+ }
133+ if ( content [ "m.call.intent" ] && typeof content [ "m.call.intent" ] !== "string" ) {
134+ throw new Error ( "Invalid m.call.intent" ) ;
135+ }
136+
137+ const cappedLifetime = content [ "lifetime" ] >= 120000 ? 120000 : content [ "lifetime" ] ;
138+ return { lifetime : cappedLifetime , ...content } as IRTCNotificationContent ;
139+ }
140+
141+ /**
142+ * Interface for `org.matrix.msc4075.rtc.notification` events.
143+ * Don't cast event content to this directly. Use `parseCallNotificationContent` instead to validate the content first.
144+ */
105145export interface IRTCNotificationContent extends RelationEvent {
106146 "m.mentions" : IMentions ;
107147 "decline_reason" ?: string ;
0 commit comments