You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-09 10:22:46 +03:00
Update call notification push rule to match MSC3914 (#2781)
This commit is contained in:
@@ -163,6 +163,22 @@ describe('NotificationService', function() {
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"rule_id": ".m.rule.room_one_to_one",
|
"rule_id": ".m.rule.room_one_to_one",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
rule_id: ".org.matrix.msc3914.rule.room.call",
|
||||||
|
default: true,
|
||||||
|
enabled: true,
|
||||||
|
conditions: [
|
||||||
|
{
|
||||||
|
kind: "event_match",
|
||||||
|
key: "type",
|
||||||
|
pattern: "org.matrix.msc3401.call",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "call_started",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: ["notify", { set_tweak: "sound", value: "default" }],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
"room": [],
|
"room": [],
|
||||||
"sender": [],
|
"sender": [],
|
||||||
@@ -337,7 +353,11 @@ describe('NotificationService', function() {
|
|||||||
}, testEvent)).toBe(true);
|
}, testEvent)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("performCustomEventHandling()", () => {
|
describe("group call started push rule", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
matrixClient.pushRules!.global!.underride!.find(r => r.rule_id === ".m.rule.fallback")!.enabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
const getActionsForEvent = (prevContent: IContent, content: IContent): IActionsObject => {
|
const getActionsForEvent = (prevContent: IContent, content: IContent): IActionsObject => {
|
||||||
testEvent = utils.mkEvent({
|
testEvent = utils.mkEvent({
|
||||||
type: "org.matrix.msc3401.call",
|
type: "org.matrix.msc3401.call",
|
||||||
@@ -353,15 +373,15 @@ describe('NotificationService', function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const assertDoesNotify = (actions: IActionsObject): void => {
|
const assertDoesNotify = (actions: IActionsObject): void => {
|
||||||
expect(actions.notify).toBeTruthy();
|
expect(actions?.notify).toBeTruthy();
|
||||||
expect(actions.tweaks.sound).toBeTruthy();
|
expect(actions?.tweaks?.sound).toBeTruthy();
|
||||||
expect(actions.tweaks.highlight).toBeFalsy();
|
expect(actions?.tweaks?.highlight).toBeFalsy();
|
||||||
};
|
};
|
||||||
|
|
||||||
const assertDoesNotNotify = (actions: IActionsObject): void => {
|
const assertDoesNotNotify = (actions: IActionsObject): void => {
|
||||||
expect(actions.notify).toBeFalsy();
|
expect(actions?.notify).toBeFalsy();
|
||||||
expect(actions.tweaks.sound).toBeFalsy();
|
expect(actions?.tweaks?.sound).toBeFalsy();
|
||||||
expect(actions.tweaks.highlight).toBeFalsy();
|
expect(actions?.tweaks?.highlight).toBeFalsy();
|
||||||
};
|
};
|
||||||
|
|
||||||
it.each(
|
it.each(
|
||||||
|
@@ -65,6 +65,8 @@ export enum ConditionKind {
|
|||||||
ContainsDisplayName = "contains_display_name",
|
ContainsDisplayName = "contains_display_name",
|
||||||
RoomMemberCount = "room_member_count",
|
RoomMemberCount = "room_member_count",
|
||||||
SenderNotificationPermission = "sender_notification_permission",
|
SenderNotificationPermission = "sender_notification_permission",
|
||||||
|
CallStarted = "call_started",
|
||||||
|
CallStartedPrefix = "org.matrix.msc3914.call_started",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPushRuleCondition<N extends ConditionKind | string> {
|
export interface IPushRuleCondition<N extends ConditionKind | string> {
|
||||||
@@ -90,12 +92,22 @@ export interface ISenderNotificationPermissionCondition
|
|||||||
key: string;
|
key: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ICallStartedCondition extends IPushRuleCondition<ConditionKind.CallStarted> {
|
||||||
|
// no additional fields
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ICallStartedPrefixCondition extends IPushRuleCondition<ConditionKind.CallStartedPrefix> {
|
||||||
|
// no additional fields
|
||||||
|
}
|
||||||
|
|
||||||
// XXX: custom conditions are possible but always fail, and break the typescript discriminated union so ignore them here
|
// XXX: custom conditions are possible but always fail, and break the typescript discriminated union so ignore them here
|
||||||
// IPushRuleCondition<Exclude<string, ConditionKind>> unfortunately does not resolve this at the time of writing.
|
// IPushRuleCondition<Exclude<string, ConditionKind>> unfortunately does not resolve this at the time of writing.
|
||||||
export type PushRuleCondition = IEventMatchCondition
|
export type PushRuleCondition = IEventMatchCondition
|
||||||
| IContainsDisplayNameCondition
|
| IContainsDisplayNameCondition
|
||||||
| IRoomMemberCountCondition
|
| IRoomMemberCountCondition
|
||||||
| ISenderNotificationPermissionCondition;
|
| ISenderNotificationPermissionCondition
|
||||||
|
| ICallStartedCondition
|
||||||
|
| ICallStartedPrefixCondition;
|
||||||
|
|
||||||
export enum PushRuleKind {
|
export enum PushRuleKind {
|
||||||
Override = "override",
|
Override = "override",
|
||||||
|
@@ -21,6 +21,8 @@ import { MatrixEvent } from "./models/event";
|
|||||||
import {
|
import {
|
||||||
ConditionKind,
|
ConditionKind,
|
||||||
IAnnotatedPushRule,
|
IAnnotatedPushRule,
|
||||||
|
ICallStartedCondition,
|
||||||
|
ICallStartedPrefixCondition,
|
||||||
IContainsDisplayNameCondition,
|
IContainsDisplayNameCondition,
|
||||||
IEventMatchCondition,
|
IEventMatchCondition,
|
||||||
IPushRule,
|
IPushRule,
|
||||||
@@ -92,8 +94,8 @@ const DEFAULT_OVERRIDE_RULES: IPushRule[] = [
|
|||||||
actions: [],
|
actions: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// For homeservers which don't support MSC3401 yet
|
// For homeservers which don't support MSC3914 yet
|
||||||
rule_id: ".org.matrix.msc3401.rule.room.call",
|
rule_id: ".org.matrix.msc3914.rule.room.call",
|
||||||
default: true,
|
default: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
conditions: [
|
conditions: [
|
||||||
@@ -102,6 +104,9 @@ const DEFAULT_OVERRIDE_RULES: IPushRule[] = [
|
|||||||
key: "type",
|
key: "type",
|
||||||
pattern: "org.matrix.msc3401.call",
|
pattern: "org.matrix.msc3401.call",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
kind: ConditionKind.CallStarted,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
actions: [PushRuleActionName.Notify, { set_tweak: TweakName.Sound, value: "default" }],
|
actions: [PushRuleActionName.Notify, { set_tweak: TweakName.Sound, value: "default" }],
|
||||||
},
|
},
|
||||||
@@ -269,6 +274,9 @@ export class PushProcessor {
|
|||||||
return this.eventFulfillsRoomMemberCountCondition(cond, ev);
|
return this.eventFulfillsRoomMemberCountCondition(cond, ev);
|
||||||
case ConditionKind.SenderNotificationPermission:
|
case ConditionKind.SenderNotificationPermission:
|
||||||
return this.eventFulfillsSenderNotifPermCondition(cond, ev);
|
return this.eventFulfillsSenderNotifPermCondition(cond, ev);
|
||||||
|
case ConditionKind.CallStarted:
|
||||||
|
case ConditionKind.CallStartedPrefix:
|
||||||
|
return this.eventFulfillsCallStartedCondition(cond, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unknown conditions: we previously matched all unknown conditions,
|
// unknown conditions: we previously matched all unknown conditions,
|
||||||
@@ -383,6 +391,22 @@ export class PushProcessor {
|
|||||||
return !!val.match(regex);
|
return !!val.match(regex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private eventFulfillsCallStartedCondition(
|
||||||
|
_cond: ICallStartedCondition | ICallStartedPrefixCondition,
|
||||||
|
ev: MatrixEvent,
|
||||||
|
): boolean {
|
||||||
|
// Since servers don't support properly sending push notification
|
||||||
|
// about MSC3401 call events, we do the handling ourselves
|
||||||
|
return (
|
||||||
|
["m.ring", "m.prompt"].includes(ev.getContent()["m.intent"])
|
||||||
|
&& !("m.terminated" in ev.getContent())
|
||||||
|
&& (
|
||||||
|
(ev.getPrevContent()["m.terminated"] !== ev.getContent()["m.terminated"])
|
||||||
|
|| deepCompare(ev.getPrevContent(), {})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private createCachedRegex(prefix: string, glob: string, suffix: string): RegExp {
|
private createCachedRegex(prefix: string, glob: string, suffix: string): RegExp {
|
||||||
if (PushProcessor.cachedGlobToRegex[glob]) {
|
if (PushProcessor.cachedGlobToRegex[glob]) {
|
||||||
return PushProcessor.cachedGlobToRegex[glob];
|
return PushProcessor.cachedGlobToRegex[glob];
|
||||||
@@ -438,7 +462,7 @@ export class PushProcessor {
|
|||||||
return {} as IActionsObject;
|
return {} as IActionsObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
let actionObj = PushProcessor.actionListToActionsObject(rule.actions);
|
const actionObj = PushProcessor.actionListToActionsObject(rule.actions);
|
||||||
|
|
||||||
// Some actions are implicit in some situations: we add those here
|
// Some actions are implicit in some situations: we add those here
|
||||||
if (actionObj.tweaks.highlight === undefined) {
|
if (actionObj.tweaks.highlight === undefined) {
|
||||||
@@ -447,30 +471,6 @@ export class PushProcessor {
|
|||||||
actionObj.tweaks.highlight = (rule.kind == PushRuleKind.ContentSpecific);
|
actionObj.tweaks.highlight = (rule.kind == PushRuleKind.ContentSpecific);
|
||||||
}
|
}
|
||||||
|
|
||||||
actionObj = this.performCustomEventHandling(ev, actionObj);
|
|
||||||
|
|
||||||
return actionObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some events require custom event handling e.g. due to missing server support
|
|
||||||
*/
|
|
||||||
private performCustomEventHandling(ev: MatrixEvent, actionObj: IActionsObject): IActionsObject {
|
|
||||||
switch (ev.getType()) {
|
|
||||||
case "m.call":
|
|
||||||
case "org.matrix.msc3401.call":
|
|
||||||
// Since servers don't support properly sending push notification
|
|
||||||
// about MSC3401 call events, we do the handling ourselves
|
|
||||||
if (
|
|
||||||
ev.getContent()["m.intent"] === "m.room"
|
|
||||||
|| ("m.terminated" in ev.getContent())
|
|
||||||
|| !("m.terminated" in ev.getPrevContent()) && !deepCompare(ev.getPrevContent(), {})
|
|
||||||
) {
|
|
||||||
actionObj.notify = false;
|
|
||||||
actionObj.tweaks = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return actionObj;
|
return actionObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user