Skip to content

Commit

Permalink
Update call notification push rule to match MSC3914 (#2781)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonBrandner authored Oct 21, 2022
1 parent d9eac57 commit a12e618
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 35 deletions.
34 changes: 27 additions & 7 deletions spec/unit/pushprocessor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,22 @@ describe('NotificationService', function() {
"enabled": true,
"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": [],
"sender": [],
Expand Down Expand Up @@ -337,7 +353,11 @@ describe('NotificationService', function() {
}, 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 => {
testEvent = utils.mkEvent({
type: "org.matrix.msc3401.call",
Expand All @@ -353,15 +373,15 @@ describe('NotificationService', function() {
};

const assertDoesNotify = (actions: IActionsObject): void => {
expect(actions.notify).toBeTruthy();
expect(actions.tweaks.sound).toBeTruthy();
expect(actions.tweaks.highlight).toBeFalsy();
expect(actions?.notify).toBeTruthy();
expect(actions?.tweaks?.sound).toBeTruthy();
expect(actions?.tweaks?.highlight).toBeFalsy();
};

const assertDoesNotNotify = (actions: IActionsObject): void => {
expect(actions.notify).toBeFalsy();
expect(actions.tweaks.sound).toBeFalsy();
expect(actions.tweaks.highlight).toBeFalsy();
expect(actions?.notify).toBeFalsy();
expect(actions?.tweaks?.sound).toBeFalsy();
expect(actions?.tweaks?.highlight).toBeFalsy();
};

it.each(
Expand Down
14 changes: 13 additions & 1 deletion src/@types/PushRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ export enum ConditionKind {
ContainsDisplayName = "contains_display_name",
RoomMemberCount = "room_member_count",
SenderNotificationPermission = "sender_notification_permission",
CallStarted = "call_started",
CallStartedPrefix = "org.matrix.msc3914.call_started",
}

export interface IPushRuleCondition<N extends ConditionKind | string> {
Expand All @@ -90,12 +92,22 @@ export interface ISenderNotificationPermissionCondition
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
// IPushRuleCondition<Exclude<string, ConditionKind>> unfortunately does not resolve this at the time of writing.
export type PushRuleCondition = IEventMatchCondition
| IContainsDisplayNameCondition
| IRoomMemberCountCondition
| ISenderNotificationPermissionCondition;
| ISenderNotificationPermissionCondition
| ICallStartedCondition
| ICallStartedPrefixCondition;

export enum PushRuleKind {
Override = "override",
Expand Down
54 changes: 27 additions & 27 deletions src/pushprocessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { MatrixEvent } from "./models/event";
import {
ConditionKind,
IAnnotatedPushRule,
ICallStartedCondition,
ICallStartedPrefixCondition,
IContainsDisplayNameCondition,
IEventMatchCondition,
IPushRule,
Expand Down Expand Up @@ -92,8 +94,8 @@ const DEFAULT_OVERRIDE_RULES: IPushRule[] = [
actions: [],
},
{
// For homeservers which don't support MSC3401 yet
rule_id: ".org.matrix.msc3401.rule.room.call",
// For homeservers which don't support MSC3914 yet
rule_id: ".org.matrix.msc3914.rule.room.call",
default: true,
enabled: true,
conditions: [
Expand All @@ -102,6 +104,9 @@ const DEFAULT_OVERRIDE_RULES: IPushRule[] = [
key: "type",
pattern: "org.matrix.msc3401.call",
},
{
kind: ConditionKind.CallStarted,
},
],
actions: [PushRuleActionName.Notify, { set_tweak: TweakName.Sound, value: "default" }],
},
Expand Down Expand Up @@ -269,6 +274,9 @@ export class PushProcessor {
return this.eventFulfillsRoomMemberCountCondition(cond, ev);
case ConditionKind.SenderNotificationPermission:
return this.eventFulfillsSenderNotifPermCondition(cond, ev);
case ConditionKind.CallStarted:
case ConditionKind.CallStartedPrefix:
return this.eventFulfillsCallStartedCondition(cond, ev);
}

// unknown conditions: we previously matched all unknown conditions,
Expand Down Expand Up @@ -383,6 +391,22 @@ export class PushProcessor {
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 {
if (PushProcessor.cachedGlobToRegex[glob]) {
return PushProcessor.cachedGlobToRegex[glob];
Expand Down Expand Up @@ -438,7 +462,7 @@ export class PushProcessor {
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
if (actionObj.tweaks.highlight === undefined) {
Expand All @@ -447,30 +471,6 @@ export class PushProcessor {
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;
}

Expand Down

0 comments on commit a12e618

Please sign in to comment.