Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(video): add rules module to sendNotification() method & push video #881

Merged
merged 6 commits into from
Dec 18, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix(sendnotification): remove rules object for non-chat notifications
madhur-push committed Nov 29, 2023
commit 478b53988120c1992e7e9f460fb76683fd5fd785
14 changes: 10 additions & 4 deletions packages/examples/sdk-backend-node/chat/chat.lowlevel.ts
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ import { config } from '../config';
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
import { createWalletClient, http } from 'viem';
import { sepolia } from 'viem/chains';
import { VIDEO_NOTIFICATION_ACCESS_TYPE } from '@pushprotocol/restapi/src/lib/payloads/constants';

// CONFIGS
const { env, showAPIResponse } = config;
@@ -632,12 +633,17 @@ async function PushAPI_chat_video_call_notification(
encryptedPGPPrivateKey: user.encryptedPrivateKey,
signer: signer,
});
// get PGP KEy

const apiResponse = await PushAPI.payloads.sendNotification({
senderType: 1,
signer: signer,
signer,
pgpPrivateKey: pgpDecrpyptedPvtKey,
chatId: chatId,
rules:{
access:{
type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT,
data: chatId
}
},
type: 3, // target
identityType: 2, // direct payload
notification: {
@@ -651,7 +657,7 @@ async function PushAPI_chat_video_call_notification(
img: '',
additionalMeta: {
type: '1+1',
data: 'Random DATA',
data: "DATA REQUIRED FOR VIDEO CALL",
domain: 'push.org',
},
},
32 changes: 26 additions & 6 deletions packages/examples/sdk-frontend/pages/video.tsx
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import styled from 'styled-components';
import { usePushSocket } from '../hooks/usePushSocket';
import { useEffect, useRef, useState } from 'react';
import VideoPlayer from '../components/VideoPlayer';
import { ADDITIONAL_META_TYPE } from '@pushprotocol/restapi/src/lib/payloads/constants';
import { ADDITIONAL_META_TYPE, VIDEO_NOTIFICATION_ACCESS_TYPE } from '@pushprotocol/restapi/src/lib/payloads/constants';

interface VideoCallMetaDataType {
recipientAddress: string;
@@ -20,7 +20,7 @@ interface VideoCallMetaDataType {
}

// env which will be used for the video call
const env = ENV.STAGING;
const env = ENV.DEV;

const Home: NextPage = () => {
const { address, isConnected } = useAccount();
@@ -110,7 +110,12 @@ const Home: NextPage = () => {
signalData: data.meta.initiator.signal,
senderAddress: data.local.address,
recipientAddress: data.incoming[0].address,
chatId: data.meta.chatId,
rules: {
access: {
type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT,
data: data.meta.chatId
}
}
});
};

@@ -165,7 +170,12 @@ const Home: NextPage = () => {
await videoObjectRef.current?.request({
senderAddress: data.local.address,
recipientAddress: data.incoming[0].address,
chatId: data.meta.chatId,
rules: {
access: {
type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT,
data: data.meta.chatId
}
}
});
}
})();
@@ -218,7 +228,12 @@ const Home: NextPage = () => {
videoObjectRef.current?.request({
senderAddress: data.local.address,
recipientAddress: data.incoming[0].address,
chatId: data.meta.chatId,
rules: {
access: {
type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT,
data: data.meta.chatId
}
},
retry: true,
});
} else if (
@@ -229,7 +244,12 @@ const Home: NextPage = () => {
signalData: videoCallMetaData.signalingData,
senderAddress: data.local.address,
recipientAddress: data.incoming[0].address,
chatId: data.meta.chatId,
rules: {
access: {
type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT,
data: data.meta.chatId
}
},
retry: true,
});
}
24 changes: 16 additions & 8 deletions packages/restapi/src/lib/payloads/sendNotifications.ts
Original file line number Diff line number Diff line change
@@ -209,7 +209,7 @@ export async function sendNotification(options: ISendNotificationInputOptions) {

const apiPayload = {
verificationProof,
identity, // `2+${payloadJSON}`
identity,
sender:
senderType === 1 && !isValidCAIP10NFTAddress(_channelAddress)
? `${channelCAIPDetails?.blockchain}:${channelCAIPDetails?.address}`
@@ -222,13 +222,21 @@ export async function sendNotification(options: ISendNotificationInputOptions) {
recipients: recipients || '',
channel: _channelAddress,
}),
rules: rules ?? {
// for backwards compatibilty with 'chatId' param
access: {
data: chatId,
type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT,
},
},
/*
- If 'rules' is not provided, check if 'chatId' is available.
- If 'chatId' is available, create a new 'rules' object for backwards compatibility.
- If neither 'rules' nor 'chatId' is available, do not include 'rules' in the payload.
*/
...(rules || chatId
? {
rules: rules ?? {
access: {
data: chatId,
type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT,
},
},
}
: {}),
};

const requestURL = `${API_BASE_URL}/v1/payloads/`;
Original file line number Diff line number Diff line change
@@ -24,7 +24,6 @@ interface CallDetailsType {
export interface VideoDataType {
/** @deprecated - Use `rules` object instead */
chatId?: string;
channelAddress?: string;
recipientAddress: string;
senderAddress: string;
signalData?: any;
184 changes: 184 additions & 0 deletions packages/restapi/tests/lib/video/sendVideoNotification.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import * as path from 'path';
import * as dotenv from 'dotenv';
dotenv.config({ path: path.resolve(__dirname, '../../.env') });
import { expect } from 'chai';
import { ethers } from 'ethers';

import { create } from '../../../src/lib/user';
import { sendNotification } from '../../../src/lib/payloads';
import { approve, send } from '../../../src/lib/chat';
import { MessageType } from '../../../src/lib/constants';

import {
VIDEO_CALL_TYPE,
VIDEO_NOTIFICATION_ACCESS_TYPE,
} from '../../../src/lib/payloads/constants';
import { VideoCallStatus } from '../../../src';

enum IDENTITY_TYPE {
MINIMAL = 0,
IPFS = 1,
DIRECT_PAYLOAD = 2,
SUBGRAPH = 3,
}

enum NOTIFICATION_TYPE {
BROADCAST = 1,
TARGETTED = 3,
SUBSET = 4,
}

enum ENV {
PROD = 'prod',
STAGING = 'staging',
DEV = 'dev',
LOCAL = 'local',
}

const env = ENV.LOCAL;

// Test suite for sendNotification functionality for video calls
describe('sendNotification functionality for video calls', () => {
// Define variables for two signers and their accounts
let signer1: any;
let decryptedPrivateKey1: string;
let account1: string;
let signer2: any;
let decryptedPrivateKey2: string;
let account2: string;

let chatId: string;

// Before running the tests, set up the signers and accounts
before(async () => {
// Create the first signer
const WALLET1 = ethers.Wallet.createRandom();
signer1 = new ethers.Wallet(WALLET1.privateKey);
// Get the address of the first account
account1 = signer1.address;

// Create the second signer
const WALLET2 = ethers.Wallet.createRandom();
signer2 = new ethers.Wallet(WALLET2.privateKey);
// Get the address of the second account
account2 = WALLET2.address;

// Create the first user using the first signer
const user1 = await create({
signer: signer1,
env,
});
decryptedPrivateKey1 = user1.decryptedPrivateKey!;

// Create the second user using the second signer
const user2 = await create({
signer: signer2,
env,
});
decryptedPrivateKey2 = user2.decryptedPrivateKey!;

// Send a message from the first user to the second user
const sendApiResponse = await send({
message: {
content: 'Hey I want to video call.',
type: MessageType.TEXT,
},
receiverAddress: account2,
signer: signer1,
pgpPrivateKey: decryptedPrivateKey1,
env,
});

chatId = sendApiResponse.chatId;

// Approve the message from the first user
await approve({
status: 'Approved',
senderAddress: account1,
signer: signer2,
pgpPrivateKey: decryptedPrivateKey2,
env,
});
});

it('Should send INITIALIZED video call notification with rules object', async () => {
// Send a notification and store the response
const res = await sendNotification({
senderType: 1,
pgpPrivateKey: decryptedPrivateKey1,
env,
signer: signer1,
type: NOTIFICATION_TYPE.TARGETTED,
identityType: IDENTITY_TYPE.DIRECT_PAYLOAD,
rules: {
access: {
type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT,
data: chatId,
},
},
notification: {
title: 'VIDEO CALL',
body: 'VIDEO CALL',
},
payload: {
title: 'VIDEO CALL',
body: 'VIDEO CALL',
cta: '',
img: '',
additionalMeta: {
type: `${VIDEO_CALL_TYPE.PUSH_VIDEO}+1`,
data: JSON.stringify({
senderAddress: account1,
recipientAddress: account2,
chatId,
signalData: null,
status: VideoCallStatus.INITIALIZED,
}),
},
},
channel: `eip155:11155111:${account1}`,
recipients: `eip155:11155111:${account2}`,
});

// Check that the response status is 204
expect(res.status).to.be.equal(204);
});

it('Should send INITIALIZED video call notification with chatId for backwards compatibility', async () => {
// Send a notification and store the response
const res = await sendNotification({
env,
senderType: 1,
pgpPrivateKey: decryptedPrivateKey1,
signer: signer1,
type: NOTIFICATION_TYPE.TARGETTED,
identityType: IDENTITY_TYPE.DIRECT_PAYLOAD,
chatId,
notification: {
title: 'VIDEO CALL',
body: 'VIDEO CALL',
},
payload: {
title: 'VIDEO CALL',
body: 'VIDEO CALL',
cta: '',
img: '',
additionalMeta: {
type: `${VIDEO_CALL_TYPE.PUSH_VIDEO}+1`,
data: JSON.stringify({
senderAddress: account1,
recipientAddress: account2,
chatId,
signalData: null,
status: VideoCallStatus.INITIALIZED,
}),
},
},
channel: `eip155:11155111:${account1}`,
recipients: `eip155:11155111:${account2}`,
});

// Check that the response status is 204
expect(res.status).to.be.equal(204);
});
});