You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
Add custom notification handling for MSC3401 call events (#2720)
This commit is contained in:
@ -74,6 +74,7 @@ interface IEventOpts {
|
|||||||
sender?: string;
|
sender?: string;
|
||||||
skey?: string;
|
skey?: string;
|
||||||
content: IContent;
|
content: IContent;
|
||||||
|
prev_content?: IContent;
|
||||||
user?: string;
|
user?: string;
|
||||||
unsigned?: IUnsigned;
|
unsigned?: IUnsigned;
|
||||||
redacts?: string;
|
redacts?: string;
|
||||||
@ -103,6 +104,7 @@ export function mkEvent(opts: IEventOpts & { event?: boolean }, client?: MatrixC
|
|||||||
room_id: opts.room,
|
room_id: opts.room,
|
||||||
sender: opts.sender || opts.user, // opts.user for backwards-compat
|
sender: opts.sender || opts.user, // opts.user for backwards-compat
|
||||||
content: opts.content,
|
content: opts.content,
|
||||||
|
prev_content: opts.prev_content,
|
||||||
unsigned: opts.unsigned || {},
|
unsigned: opts.unsigned || {},
|
||||||
event_id: "$" + testEventIndex++ + "-" + Math.random() + "-" + Math.random(),
|
event_id: "$" + testEventIndex++ + "-" + Math.random() + "-" + Math.random(),
|
||||||
txn_id: "~" + Math.random(),
|
txn_id: "~" + Math.random(),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as utils from "../test-utils/test-utils";
|
import * as utils from "../test-utils/test-utils";
|
||||||
import { PushProcessor } from "../../src/pushprocessor";
|
import { IActionsObject, PushProcessor } from "../../src/pushprocessor";
|
||||||
import { EventType, MatrixClient, MatrixEvent } from "../../src";
|
import { EventType, IContent, MatrixClient, MatrixEvent } from "../../src";
|
||||||
|
|
||||||
describe('NotificationService', function() {
|
describe('NotificationService', function() {
|
||||||
const testUserId = "@ali:matrix.org";
|
const testUserId = "@ali:matrix.org";
|
||||||
@ -336,4 +336,102 @@ describe('NotificationService', function() {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
}, testEvent)).toBe(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",
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { escapeRegExp, globToRegexp, isNullOrUndefined } from "./utils";
|
import { deepCompare, escapeRegExp, globToRegexp, isNullOrUndefined } from "./utils";
|
||||||
import { logger } from './logger';
|
import { logger } from './logger';
|
||||||
import { MatrixClient } from "./client";
|
import { MatrixClient } from "./client";
|
||||||
import { MatrixEvent } from "./models/event";
|
import { MatrixEvent } from "./models/event";
|
||||||
@ -91,6 +91,20 @@ const DEFAULT_OVERRIDE_RULES: IPushRule[] = [
|
|||||||
],
|
],
|
||||||
actions: [],
|
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 {
|
export interface IActionsObject {
|
||||||
@ -424,7 +438,7 @@ export class PushProcessor {
|
|||||||
return {} as IActionsObject;
|
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
|
// Some actions are implicit in some situations: we add those here
|
||||||
if (actionObj.tweaks.highlight === undefined) {
|
if (actionObj.tweaks.highlight === undefined) {
|
||||||
@ -433,6 +447,30 @@ 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