Skip to content

Commit

Permalink
Add custom notification handling for MSC3401 call events (#2720)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonBrandner authored Oct 6, 2022
1 parent a1b046b commit 6e5326f
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 4 deletions.
2 changes: 2 additions & 0 deletions spec/test-utils/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ interface IEventOpts {
sender?: string;
skey?: string;
content: IContent;
prev_content?: IContent;
user?: string;
unsigned?: IUnsigned;
redacts?: string;
Expand Down Expand Up @@ -103,6 +104,7 @@ export function mkEvent(opts: IEventOpts & { event?: boolean }, client?: MatrixC
room_id: opts.room,
sender: opts.sender || opts.user, // opts.user for backwards-compat
content: opts.content,
prev_content: opts.prev_content,
unsigned: opts.unsigned || {},
event_id: "$" + testEventIndex++ + "-" + Math.random() + "-" + Math.random(),
txn_id: "~" + Math.random(),
Expand Down
102 changes: 100 additions & 2 deletions spec/unit/pushprocessor.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as utils from "../test-utils/test-utils";
import { PushProcessor } from "../../src/pushprocessor";
import { EventType, MatrixClient, MatrixEvent } from "../../src";
import { IActionsObject, PushProcessor } from "../../src/pushprocessor";
import { EventType, IContent, MatrixClient, MatrixEvent } from "../../src";

describe('NotificationService', function() {
const testUserId = "@ali:matrix.org";
Expand Down Expand Up @@ -336,4 +336,102 @@ describe('NotificationService', function() {
enabled: true,
}, testEvent)).toBe(true);
});

describe("performCustomEventHandling()", () => {
const getActionsForEvent = (prevContent: IContent, content: IContent): IActionsObject => {
testEvent = utils.mkEvent({
type: "org.matrix.msc3401.call",
room: testRoomId,
user: "@alice:foo",
skey: "state_key",
event: true,
content: content,
prev_content: prevContent,
});

return pushProcessor.actionsForEvent(testEvent);
};

const assertDoesNotify = (actions: IActionsObject): void => {
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();
};

it.each(
["m.ring", "m.prompt"],
)("should notify when new group call event appears with %s intent", (intent: string) => {
assertDoesNotify(getActionsForEvent({}, {
"m.intent": intent,
"m.type": "m.voice",
"m.name": "Call",
}));
});

it("should notify when a call is un-terminated", () => {
assertDoesNotify(getActionsForEvent({
"m.intent": "m.ring",
"m.type": "m.voice",
"m.name": "Call",
"m.terminated": "All users left",
}, {
"m.intent": "m.ring",
"m.type": "m.voice",
"m.name": "Call",
}));
});

it("should not notify when call is terminated", () => {
assertDoesNotNotify(getActionsForEvent({
"m.intent": "m.ring",
"m.type": "m.voice",
"m.name": "Call",
}, {
"m.intent": "m.ring",
"m.type": "m.voice",
"m.name": "Call",
"m.terminated": "All users left",
}));
});

it("should ignore with m.room intent", () => {
assertDoesNotNotify(getActionsForEvent({}, {
"m.intent": "m.room",
"m.type": "m.voice",
"m.name": "Call",
}));
});

describe("ignoring non-relevant state changes", () => {
it("should ignore intent changes", () => {
assertDoesNotNotify(getActionsForEvent({
"m.intent": "m.ring",
"m.type": "m.voice",
"m.name": "Call",
}, {
"m.intent": "m.ring",
"m.type": "m.video",
"m.name": "Call",
}));
});

it("should ignore name changes", () => {
assertDoesNotNotify(getActionsForEvent({
"m.intent": "m.ring",
"m.type": "m.voice",
"m.name": "Call",
}, {
"m.intent": "m.ring",
"m.type": "m.voice",
"m.name": "New call",
}));
});
});
});
});
42 changes: 40 additions & 2 deletions src/pushprocessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { escapeRegExp, globToRegexp, isNullOrUndefined } from "./utils";
import { deepCompare, escapeRegExp, globToRegexp, isNullOrUndefined } from "./utils";
import { logger } from './logger';
import { MatrixClient } from "./client";
import { MatrixEvent } from "./models/event";
Expand Down Expand Up @@ -91,6 +91,20 @@ const DEFAULT_OVERRIDE_RULES: IPushRule[] = [
],
actions: [],
},
{
// For homeservers which don't support MSC3401 yet
rule_id: ".org.matrix.msc3401.rule.room.call",
default: true,
enabled: true,
conditions: [
{
kind: ConditionKind.EventMatch,
key: "type",
pattern: "org.matrix.msc3401.call",
},
],
actions: [PushRuleActionName.Notify, { set_tweak: TweakName.Sound, value: "default" }],
},
];

export interface IActionsObject {
Expand Down Expand Up @@ -424,7 +438,7 @@ export class PushProcessor {
return {} as IActionsObject;
}

const actionObj = PushProcessor.actionListToActionsObject(rule.actions);
let actionObj = PushProcessor.actionListToActionsObject(rule.actions);

// Some actions are implicit in some situations: we add those here
if (actionObj.tweaks.highlight === undefined) {
Expand All @@ -433,6 +447,30 @@ 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 6e5326f

Please sign in to comment.