diff --git a/CHANGELOG.md b/CHANGELOG.md index 6649a065..70822654 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log + +## [v4.55.0](https://github.com/plivo/plivo-node/tree/v4.55.0) (2023-08-10) +**Verify Service API's** +- Create Session API - To initiate a session +- Get Session API - Get session detail +- List Session API - List Session details +- Validate Session API + ## [v4.54.0](https://github.com/plivo/plivo-node/tree/v4.54.0) (2023-08-07) **Feature - WhatsApp message support** - Added new param `template` and new message_type `whatsapp` to [send message API](https://www.plivo.com/docs/sms/api/message#send-a-message) - Added new `message_states` (`read`) `message_type`(`whatsapp`),`conversation_id`, `conversation_origin`, `conversation_expiry_timestamp` in [list all messages API](https://www.plivo.com/docs/sms/api/message#list-all-messages) and [get message details API](https://www.plivo.com/docs/sms/api/message#retrieve-a-message) response + ## [4.53.0](https://github.com/plivo/plivo-node/tree/v4.53.0) (2023-08-03) **Feature - DLT parameters** - Added new params `DLTEntityID`, `DLTTemplateID`, `DLTTemplateCategory` to the [send message API](https://www.plivo.com/docs/sms/api/message/send-a-message/) diff --git a/examples/verify.js b/examples/verify.js new file mode 100644 index 00000000..ec0719ce --- /dev/null +++ b/examples/verify.js @@ -0,0 +1,23 @@ +let plivo = require('plivo') + +let client = new plivo.Client(process.env.PLIVO_AUTH_ID, process.env.PLIVO_AUTH_TOKEN); + +client.verify_session.create({ + recipient: '+14156667778', +}).then(function(response) { + console.log(response) +}); + +client.verify_session.get('5c533d15-1975-4f20-80be-40174142ea37').then(function(response) { + console.log(response) +}); + +client.verify_session.list().then(function(response) { + console.log(response) +}); + +client.verify_session.validate({id:'c549be00-0e74-4ccb-ac04-8a778312b861',otp:'123456'}).then(function(response) { + console.log(response) +}).catch(function (error) { + console.log(error) +}); diff --git a/lib/resources/verify.js b/lib/resources/verify.js new file mode 100644 index 00000000..de04d586 --- /dev/null +++ b/lib/resources/verify.js @@ -0,0 +1,313 @@ +import * as _ from "lodash"; + +import { + PlivoResource, + PlivoResourceInterface +} from '../base'; +import { + extend, + validate +} from '../utils/common.js'; + +const action = 'Verify/Session/'; +const idField = 'session_uuid'; +let actionKey = Symbol('api action'); +let klassKey = Symbol('constructor'); +let idKey = Symbol('id filed'); +let clientKey = Symbol('make api call'); + + +export class SessionResponse { + constructor(params) { + params = params || {}; + this.apiId = params.apiId; + this.message = params.message; + this.sessionUuid = params.sessionUuid; + if (params.invalidNumber != undefined ){ + this.invalid_number = params.invalidNumber; + } + } +} + +export class ValidateSessionResponse { + constructor(params) { + params = params || {}; + this.apiId = params.apiId; + this.message = params.message; + if (params.invalidNumber != undefined ){ + this.invalid_number = params.invalidNumber; + } + } +} + +export class SessionGetResponse { + constructor(params) { + params = params || {}; + this.apiId = params.apiId; + this.sessionUuid = params.sessionUuid; + this.appUuid = params.appUuid; + this.alias = params.alias; + this.recipient = params.recipient; + this.channel = params.channel; + this.status = params.status; + this.count = params.count; + this.requestor_ip = params.requestorIp; + this.destination_country_iso2 = params.destinationCountryIso2; + this.destination_network = params.destinationNetwork; + this.attemptDetails = params.attemptDetails; + this.createdAt = params.createdAt; + this.updatedAt = params.updatedAt; + + this.charges = Object.assign({}, params.charges); + + this.charges.totalCharge = params.charges.totalCharge; + this.charges.validationCharge = params.charges.validationCharge; + this.charges.attemptCharges = params.charges.attemptCharges + } +} + +export class SessionListResponse { + constructor(params) { + params = params || {}; + this.sessionUuid = params.sessionUuid; + this.appUuid = params.appUuid; + this.recipient = params.recipient; + this.alias = params.alias; + this.channel = params.channel; + this.status = params.status; + this.count = params.count; + this.requestor_ip = params.requestorIp; + this.destination_country_iso2 = params.destinationCountryIso2; + this.destination_network = params.destinationNetwork; + this.attemptDetails = params.attemptDetails; + this.createdAt = params.createdAt; + this.updatedAt = params.updatedAt; + + this.charges = Object.assign({}, params.charges); + + this.charges.totalCharge = params.charges.totalCharge; + this.charges.validationCharge = params.charges.validationCharge; + this.charges.attemptCharges = params.charges.attemptCharges + } +} + +/** + * Represents a Session + * @constructor + * @param {function} client - make api call + * @param {object} [data] - data of call + */ +export class Session extends PlivoResource { + constructor(client, data = {}) { + super(action, Session, idField, client); + this[actionKey] = action; + this[clientKey] = client; + if (idField in data) { + this.id = data[idField]; + }; + + extend(this, data); + } + +} + + +/** + * Represents a Session Interface + * @constructor + * @param {function} client - make api call + * @param {object} [data] - data of call + */ +export class SessionInterface extends PlivoResourceInterface { + constructor(client, data = {}) { + super(action, Session, idField, client); + extend(this, data); + this[clientKey] = client; + this[actionKey] = action; + this[klassKey] = Session; + this[idKey] = idField; + } + + /** + * Send Session + * @method + * @param {Object} sessionReq- request body fields + * @promise {object} return {@link PlivoGenericMessage} object if success + * @fail {Error} return Error + */ + create(sessionReq){ + + var isObject = arguments.length; + var app_uuid, recipient, url, method, channel + + if (isObject === 1) { + app_uuid = sessionReq.app_uuid + recipient = sessionReq.recipient + url = sessionReq.url + method = sessionReq.method + channel = sessionReq.channel + } + + let errors = validate([{ + field: 'recipient', + value: recipient, + validators: ['isRequired'] + }, + ]); + + if (errors) { + return errors + } + + let params = {} + if (isObject === 1) { + if(app_uuid) { + params.app_uuid = app_uuid + } + if(recipient) { + params.recipient = recipient + } + if(channel) { + params.channel = channel + } + if(url) { + params.url = url + } + if(method) { + params.method = method + } + } + + let client = this[clientKey]; + let idField = this[idKey]; + let action = this[actionKey] + (this.id ? this.id + '/' : ''); + + return new Promise((resolve, reject) => { + client('POST', action, params) + .then(response => { + resolve(new SessionResponse(response.body, idField)); + }) + .catch(error => { + reject(error); + }); + }) + + } + + + /** + * Get Session by given id + * @method + * @param {string} id - id of session + * @promise {object} return {@link Session} object if success + * @fail {Error} return Error + */ + get(id) { + let errors = validate([{ + field: 'id', + value: id, + validators: ['isRequired'] + }]); + + if (errors) { + return errors; + } + + let client = this[clientKey]; + let action = this[actionKey]; + + return new Promise((resolve, reject) => { + if (action !== '' && !id) { + reject(new Error(this[idKey] + ' must be set')); + } + client('GET', action + (id ? id + '/' : '')) + .then(response => { + resolve(new SessionGetResponse(response.body, client)); + }) + .catch(error => { + reject(error); + }); + }); + } + + list(params) { + let client = this[clientKey]; + let action = this[actionKey]; + return new Promise((resolve, reject) => { + client('GET', action, params) + .then(response => { + let sessions = { + api_id: response.body.apiId, + meta: response.body.meta + } + let objects = []; + Object.defineProperty(objects, 'meta', { + value: response.body.meta, + enumerable: true + }); + Object.defineProperty(objects, 'apiId', { + value: response.body.apiId, + enumerable: true + }) + if (response.body.sessions !== null) { + response.body.sessions.forEach(item => { + objects.push(new SessionListResponse(item, client)); + }); + sessions.sessions = objects + } else { + sessions.sessions = null + } + resolve(sessions); + }) + .catch(error => { + reject(error); + }); + }); + } + + validate(req) { + var id, otp + var isObject = arguments.length; + if (isObject === 1) { + id = req.id + otp = req.otp + } + let errors = validate([{ + field: 'id', + value: id, + validators: ['isRequired'] + }]); + + if (errors) { + return errors; + } + + errors = validate([{ + field: 'otp', + value: otp, + validators: ['isRequired'] + }]); + + if (errors) { + return errors; + } + + let params = {} + params.otp = otp + + let client = this[clientKey]; + let idField = this[idKey]; + let action = this[actionKey]; + + return new Promise((resolve, reject) => { + client('POST', action + (id ? id + '/' : ''), params) + .then(response => { + resolve(new ValidateSessionResponse(response.body, idField)); + }) + .catch(error => { + reject(error); + }); + }) + + } +} diff --git a/lib/rest/client-test.js b/lib/rest/client-test.js index 2ddc6e32..64f83b22 100644 --- a/lib/rest/client-test.js +++ b/lib/rest/client-test.js @@ -69,6 +69,7 @@ import { ComplianceRequirementInterface } from "../resources/complianceRequireme import { ComplianceApplicationInterface } from "../resources/complianceApplications"; import { LOAInterface } from "../resources/loa"; import { HostedMessagingNumberInterface } from "../resources/hostedMessagingNumber"; +import {SessionInterface} from "../resources/verify"; import { MaskingSessionInterface } from '../resources/maskingSession.js'; export class Client { @@ -124,6 +125,7 @@ export class Client { this.multiPartyCalls = new MultiPartyCallInterface(client); this.loa = new LOAInterface(client); this.hostedMessagingNumber = new HostedMessagingNumberInterface(client); + this.verify_session = new SessionInterface(client); this.maskingSession = new MaskingSessionInterface(client); } } diff --git a/lib/rest/client.js b/lib/rest/client.js index 5a99038a..c1bce649 100644 --- a/lib/rest/client.js +++ b/lib/rest/client.js @@ -32,6 +32,7 @@ import { ComplianceApplicationInterface } from "../resources/complianceApplicati import { MultiPartyCallInterface } from "../resources/multiPartyCall"; import { LOAInterface } from "../resources/loa"; import { HostedMessagingNumberInterface } from "../resources/hostedMessagingNumber"; +import { SessionInterface } from "../resources/verify"; import { MaskingSessionInterface } from "../resources/maskingSession.js"; @@ -112,6 +113,7 @@ export class Client { this.multiPartyCalls = new MultiPartyCallInterface(client); this.loa = new LOAInterface(client); this.hostedMessagingNumber = new HostedMessagingNumberInterface(client); + this.verify_session = new SessionInterface(client); this.maskingSession = new MaskingSessionInterface(client) } diff --git a/lib/rest/request-test.js b/lib/rest/request-test.js index e904ee47..cf20f6b4 100644 --- a/lib/rest/request-test.js +++ b/lib/rest/request-test.js @@ -342,7 +342,7 @@ export function Request(config) { } } }); - } + } else if (method === 'GET' && action === 'Masking/Session/') { resolve({ response: {}, @@ -1920,7 +1920,7 @@ export function Request(config) { total_amount: '0.00000', total_rate: '0.00350', units: 1, - requester_ip: "192.168.1.1", + requester_ip: "192.168.1.1", is_domestic: false } }); @@ -2163,7 +2163,7 @@ export function Request(config) { total_amount: '0.00000', total_rate: '0.00350', units: 1, - requester_ip: '192.168.1.2', + requester_ip: '192.168.1.2', is_domestic: false, dlt_entity_id: "9876", dlt_template_id: "5432", @@ -2199,7 +2199,7 @@ export function Request(config) { total_amount: '0.00000', total_rate: '0.00350', units: 1, - requester_ip: "192.168.1.1", + requester_ip: "192.168.1.1", is_domestic: false, dlt_entity_id: "2233", dlt_template_id: "4455", @@ -2222,7 +2222,7 @@ export function Request(config) { total_amount: '0.00000', total_rate: '0.00350', units: 1, - requester_ip: "192.168.1.2", + requester_ip: "192.168.1.2", is_domestic: false, dlt_entity_id: null, dlt_template_id: null, @@ -2506,6 +2506,114 @@ export function Request(config) { }); } + else if (method == 'POST' && action == 'Verify/Session/') { + resolve({ + response: {}, + body: { + message: 'Session initiated', + session_uuid: 'db3ce55a-7f1d-11e1-8ea7-1231380bc196', + api_id: 'db342550-7f1d-11e1-8ea7-1231380bc196' + } + }); + } + + else if (method == 'GET' && action == 'Verify/Session/1/') { + resolve({ + response: {}, + body: { + api_id: 'c3f2f101-ff46-44dd-808a-00408deba5d1', + session_uuid: 'd8f1b187-ddcb-438a-a298-eb17fb2b31f5', + app_uuid: '3cdec449-a367-435e-b4f9-40d777a7cfcc', + alias: 'new_voice45', + recipient: '918707046406', + channel: 'sms', + status: 'verified', + count: 1, + requestor_ip: '', + destination_country_iso2: 'IN', + destination_network: 'Jio', + attempt_details: [ + { + channel: 'sms', + attempt_uuid: 'e2f66aeb-6b98-42a9-ba81-0aba74a7eb7c', + status: 'delivered', + time: '2023-07-24T22:47:21.279363+05:30' + } + ], + charges: { + total_charge: '0.07100', + validation_charge: '0.05', + attempt_charges: [ + { + attempt_uuid: 'e2f66aeb-6b98-42a9-ba81-0aba74a7eb7c', + channel: 'sms', + charge: '0.02100' + } + ] + }, + created_at: '2023-07-24T22:47:19.243437+05:30', + updated_at: '2023-07-24T22:47:21.279363+05:30' + } + }) + } + + else if (method == 'GET' && action == 'Verify/Session/') { + resolve({ + response: {}, + body: { + api_id: 'c3f2f101-ff46-44dd-808a-00408deba5d1', + meta: { + limit: 20, + offset: 0, + next: null, + previous: null + }, + sessions:[{session_uuid: 'd8f1b187-ddcb-438a-a298-eb17fb2b31f5', + app_uuid: '3cdec449-a367-435e-b4f9-40d777a7cfcc', + alias: 'new_voice45', + recipient: '918707046406', + channel: 'sms', + status: 'verified', + count: 1, + requestor_ip: '', + destination_country_iso2: 'IN', + destination_network: 'Jio', + attempt_details: [ + { + channel: 'sms', + attempt_uuid: 'e2f66aeb-6b98-42a9-ba81-0aba74a7eb7c', + status: 'delivered', + time: '2023-07-24T22:47:21.279363+05:30' + } + ], + charges: { + total_charge: '0.07100', + validation_charge: '0.05', + attempt_charges: [ + { + attempt_uuid: 'e2f66aeb-6b98-42a9-ba81-0aba74a7eb7c', + channel: 'sms', + charge: '0.02100' + } + ] + }, + created_at: '2023-07-24T22:47:19.243437+05:30', + updated_at: '2023-07-24T22:47:21.279363+05:30'}] + } + }) + } + + else if (method == 'POST' && action == 'Verify/Session/1/') { + resolve({ + response: {}, + body: { + message: 'session validated successfully.', + session_uuid: 'db3ce55a-7f1d-11e1-8ea7-1231380bc196', + api_id: 'db342550-7f1d-11e1-8ea7-1231380bc196' + } + }); + } + // =========== If no combination found, raise issue ============================ else { console.log('===>--->', method, action, '=>', params); diff --git a/package.json b/package.json index ca3ed89c..9e4a1008 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plivo", - "version": "4.54.0", + "version": "4.55.0", "description": "A Node.js SDK to make voice calls and send SMS using Plivo and to generate Plivo XML", "homepage": "https://github.com/plivo/plivo-node", "files": [ diff --git a/test/verify.js b/test/verify.js new file mode 100644 index 00000000..2055451f --- /dev/null +++ b/test/verify.js @@ -0,0 +1,47 @@ +import { + Client +} from '../lib/rest/client-test'; +import { + PlivoGenericResponse +} from '../lib/base.js'; +import assert from 'assert'; +import sinon from 'sinon'; + +let client = new Client('sampleid', 'sammpletoken', 'sampleproxy'); + +describe('session', function () { + + it('should create session via interface', function () { + return client.verify_session.create({ + recipient: '+14156667778', + }) + .then(function (session) { + assert.equal(session.message, 'Session initiated') + }) + }); + + it('should get session', function () { + return client.verify_session.get(1) + .then(function (session) { + assert.equal(session.alias, 'new_voice45') + }) + }); + + it('list sessions', function () { + return client.verify_session.list() + .then(function (session) { + assert.equal(session.sessions[0].count, 1) + }) + }); + + it('should validate session via interface', function () { + return client.verify_session.validate({ + id: 1, + otp: 123456 + }) + .then(function (session) { + assert.equal(session.message, 'session validated successfully.') + }) + }); + +});