How to choose different Lambda function while Start Streaming to Amazon Elasticsearch Service - amazon-web-services

Following this Streaming CloudWatch Logs Data to Amazon Elasticsearch Service, it's working fine to stream cloud watch log to ELK having one log group and one Lambda function.
But now I want to change target lambda function for my other logs group, but I am not able to do that as there is no option in AWS console.
Any Help will be appreciated.
Thanks

I was streaming to ELK using the AWS console option which is Start Streaming to Amazon Elasticsearch Service, But I failed to change or choose different lambda function as there is only lambda function can be selected for any log group using this option.
So, I create new lambda function and set stream target to AWS lambda function,
Here is the code that all you need, Node version for lambda function is 4.* as it was some issue with the new version but the pulse point is it does not require any extra NPM packages.
// v1.1.2
var https = require('https');
var zlib = require('zlib');
var crypto = require('crypto');
var endpoint = 'search-my-test.us-west-2.es.amazonaws.com';
exports.handler = function(input, context) {
// decode input from base64
var zippedInput = new Buffer(input.awslogs.data, 'base64');
// decompress the input
zlib.gunzip(zippedInput, function(error, buffer) {
if (error) { context.fail(error); return; }
// parse the input from JSON
var awslogsData = JSON.parse(buffer.toString('utf8'));
// transform the input to Elasticsearch documents
var elasticsearchBulkData = transform(awslogsData);
// skip control messages
if (!elasticsearchBulkData) {
console.log('Received a control message');
context.succeed('Control message handled successfully');
return;
}
// post documents to the Amazon Elasticsearch Service
post(elasticsearchBulkData, function(error, success, statusCode, failedItems) {
console.log('Response: ' + JSON.stringify({
"statusCode": statusCode
}));
if (error) {
console.log('Error: ' + JSON.stringify(error, null, 2));
if (failedItems && failedItems.length > 0) {
console.log("Failed Items: " +
JSON.stringify(failedItems, null, 2));
}
context.fail(JSON.stringify(error));
} else {
console.log('Success: ' + JSON.stringify(success));
context.succeed('Success');
}
});
});
};
function transform(payload) {
if (payload.messageType === 'CONTROL_MESSAGE') {
return null;
}
var bulkRequestBody = '';
payload.logEvents.forEach(function(logEvent) {
var timestamp = new Date(1 * logEvent.timestamp);
// index name format: cwl-YYYY.MM.DD
var indexName = [
'prod-background-wo-' + timestamp.getUTCFullYear(), // year
('0' + (timestamp.getUTCMonth() + 1)).slice(-2), // month
('0' + timestamp.getUTCDate()).slice(-2) // day
].join('.');
var source = buildSource(logEvent.message, logEvent.extractedFields);
source['response_time'] = source["end"] - source["start"];
source['#id'] = logEvent.id;
source['#timestamp'] = new Date(1 * logEvent.timestamp).toISOString();
source['#message'] = logEvent.message;
source['#owner'] = payload.owner;
source['#log_group'] = payload.logGroup;
source['#log_stream'] = payload.logStream;
var action = { "index": {} };
action.index._index = indexName;
action.index._type = payload.logGroup;
action.index._id = logEvent.id;
bulkRequestBody += [
JSON.stringify(action),
JSON.stringify(source),
].join('\n') + '\n';
});
return bulkRequestBody;
}
function buildSource(message, extractedFields) {
if (extractedFields) {
var source = {};
for (var key in extractedFields) {
if (extractedFields.hasOwnProperty(key) && extractedFields[key]) {
var value = extractedFields[key];
if (isNumeric(value)) {
source[key] = 1 * value;
continue;
}
jsonSubString = extractJson(value);
if (jsonSubString !== null) {
source['$' + key] = JSON.parse(jsonSubString);
}
source[key] = value;
}
}
return source;
}
jsonSubString = extractJson(message);
if (jsonSubString !== null) {
return JSON.parse(jsonSubString);
}
return {};
}
function extractJson(message) {
var jsonStart = message.indexOf('{');
if (jsonStart < 0) return null;
var jsonSubString = message.substring(jsonStart);
return isValidJson(jsonSubString) ? jsonSubString : null;
}
function isValidJson(message) {
try {
JSON.parse(message);
} catch (e) { return false; }
return true;
}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function post(body, callback) {
var requestParams = buildRequest(endpoint, body);
var request = https.request(requestParams, function(response) {
var responseBody = '';
response.on('data', function(chunk) {
responseBody += chunk;
});
response.on('end', function() {
var info = JSON.parse(responseBody);
var failedItems;
var success;
if (response.statusCode >= 200 && response.statusCode < 299) {
failedItems = info.items.filter(function(x) {
return x.index.status >= 300;
});
success = {
"attemptedItems": info.items.length,
"successfulItems": info.items.length - failedItems.length,
"failedItems": failedItems.length
};
}
var error = response.statusCode !== 200 || info.errors === true ? {
"statusCode": response.statusCode,
"responseBody": responseBody
} : null;
callback(error, success, response.statusCode, failedItems);
});
}).on('error', function(e) {
callback(e);
});
request.end(requestParams.body);
}
function buildRequest(endpoint, body) {
var endpointParts = endpoint.match(/^([^\.]+)\.?([^\.]*)\.?([^\.]*)\.amazonaws\.com$/);
var region = endpointParts[2];
var service = endpointParts[3];
var datetime = (new Date()).toISOString().replace(/[:\-]|\.\d{3}/g, '');
var date = datetime.substr(0, 8);
var kDate = hmac('AWS4' + process.env.AWS_SECRET_ACCESS_KEY, date);
var kRegion = hmac(kDate, region);
var kService = hmac(kRegion, service);
var kSigning = hmac(kService, 'aws4_request');
var request = {
host: endpoint,
method: 'POST',
path: '/_bulk',
body: body,
headers: {
'Content-Type': 'application/json',
'Host': endpoint,
'Content-Length': Buffer.byteLength(body),
'X-Amz-Security-Token': process.env.AWS_SESSION_TOKEN,
'X-Amz-Date': datetime
}
};
var canonicalHeaders = Object.keys(request.headers)
.sort(function(a, b) { return a.toLowerCase() < b.toLowerCase() ? -1 : 1; })
.map(function(k) { return k.toLowerCase() + ':' + request.headers[k]; })
.join('\n');
var signedHeaders = Object.keys(request.headers)
.map(function(k) { return k.toLowerCase(); })
.sort()
.join(';');
var canonicalString = [
request.method,
request.path, '',
canonicalHeaders, '',
signedHeaders,
hash(request.body, 'hex'),
].join('\n');
var credentialString = [ date, region, service, 'aws4_request' ].join('/');
var stringToSign = [
'AWS4-HMAC-SHA256',
datetime,
credentialString,
hash(canonicalString, 'hex')
] .join('\n');
request.headers.Authorization = [
'AWS4-HMAC-SHA256 Credential=' + process.env.AWS_ACCESS_KEY_ID + '/' + credentialString,
'SignedHeaders=' + signedHeaders,
'Signature=' + hmac(kSigning, stringToSign, 'hex')
].join(', ');
return request;
}
function hmac(key, str, encoding) {
return crypto.createHmac('sha256', key).update(str, 'utf8').digest(encoding);
}
function hash(str, encoding) {
return crypto.createHash('sha256').update(str, 'utf8').digest(encoding);
}

Related

How to move array of images from cloudinary to s3 bucket

I want to do two things in my code
I want to move the array of images from cloudinary to s3 bucket
Replace the url with the s3 bucket url
I was able to replace the url but I am not able to move those images from cloudinary to s3
Here is that API
const userSchemaPortfolio = async (req, res) => {
let userPortfolio = (await userSchema.find({}, { portfolio: 1 })).forEach(async
function (docs) {
let updatedPortfolio = []
if (docs.portfolio.length > 0) {
// console.log(docs.portfolio.length, typeof (docs.portfolio), Object.keys(docs.portfolio).length, docs._id)
for (i = 0; i < docs.portfolio.length; i++) {
if (docs.portfolio != "") {
// console.log(docs)
let endPoint = new Date().getTime() + '_' + docs.portfolio[i].toString().split('/').pop();
// console.log(endPoint, docs.portfolio[i])
let imageURL = docs.portfolio[i]
// console.log(imageURL)
let resImg = await fetch(imageURL);
console.log(resImg.url)
let blob = await resImg.buffer()
// console.log(blob)
var uploadedImage = s3.upload({
Bucket: process.env.AWS_BUCKET,
Key: endPoint,
Body: blob,
}).promise()
// console.log(uploadedImage)
var portfolio = "https://**************.amazonaws.com/" + endPoint;
// console.log("....>>>>>",portfolio)
updatedPortfolio.push(portfolio);
// console.log(updatedPortfolio)
// return;
}
}
// console.log(updatedPortfolio)
return;
let updateData = { portfolio: updatedPortfolio }
await userSchema.updateOne({ _id: docs._id }, { $set: updateData });
// console.log(updatedPortfolio, docs._id, docs.portfolio)
}
});
let user = await userSchema.find({}, { portfolio: 1 })
// console.log(chat)
res.send(user)
}

How to point AWS-SDK DynamoDB to a serverless DynamoDB local

I am trying to write a script that will loop thru an array of items for a DynamoDB table and run a batch write command. My functionality is good, but I am having trouble with DynamoDB. Would be great if I could point my AWS.DynamoDB.DocumentClient() to my localhost running DynamoDB. Any tips?
Would also consider a way to just run the commands via the aws cli but I am not sure how to do that. I am running Node.js so it maybe possible?
Here is my code:
var AWS = require('aws-sdk');
AWS.config.update({ region: 'eu-central-1' });
var DynamoDB = new AWS.DynamoDB.DocumentClient()
DynamoDB.endpoint = 'http://localhost:8000';
const allItems = require('./resource.json');
const tableName = 'some-table-name';
console.log({ tableName, allItems });
var batches = [];
var currentBatch = [];
var count = 0;
for (let i = 0; i < allItems.length; i++) {
//push item to the current batch
count++;
currentBatch.push(allItems[i]);
if (count % 25 === 0) {
batches.push(currentBatch);
currentBatch = [];
}
}
//if there are still items left in the curr batch, add to the collection of batches
if (currentBatch.length > 0 && currentBatch.length !== 25) {
batches.push(currentBatch);
}
var completedRequests = 0;
var errors = false;
//request handler for DynamoDB
function requestHandler(err, data) {
console.log('In the request handler...');
return function (err, data) {
completedRequests++;
errors = errors ? true : err;
//log error
if (errors) {
console.error(JSON.stringify(err, null, 2));
console.error('Request caused a DB error.');
console.error('ERROR: ' + err);
console.error(JSON.stringify(err, null, 2));
} else {
var res = {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true,
},
body: JSON.stringify(data),
isBase64Encoded: false,
};
console.log(`Success: returned ${data}`);
return res;
}
if (completedRequests == batches.length) {
return errors;
}
};
}
//Make request
var params;
for (let j = 0; j < batches.length; j++) {
//items go in params.RequestedItems.id array
//format for the items is {PutRequest : {Item: ITEM_OBJECT}}
params = '{"RequestItems": {"' + tableName + '": []}}';
params = JSON.parse(params);
params.RequestItems[tableName] = batches[j];
console.log('before db.batchWriteItem: ', params);
//send to db
DynamoDB.batchWrite(params, requestHandler(params));
}
I figured it out and will leave this here for anyone that may need it.
var { DynamoDB } = require('aws-sdk');
var db = new DynamoDB.DocumentClient({
region: 'localhost',
endpoint: 'http://localhost:8000',
});

Load testing an API which uses oauth token for authorization using loadimpact k6

I'm trying to load test an API (GET method) using loadimpact k6 which requires oauth token for authorization to get the successful response. I already have a postman collection file which does this by running pre-request script. The pre-request script will request token from the authorization server and then populates the token in the environment variable. I used the "Postman to LoadImpact converter" to generate the k6 script but it isn't doing any help. The script fails to get the access token.
The generated script from the converter is given below:
// Auto-generated by the Load Impact converter
import "./libs/shim/core.js";
export let options = { maxRedirects: 4 };
const Request = Symbol.for("request");
postman[Symbol.for("initial")]({
options,
collection: {
currentAccessToken: "",
"Client-Id": "",
"Client-Secret": "",
"Token-Scope": "",
"Grant-Type": "client_credentials",
"Access-Token-URL": "",
accessTokenExpiry: ""
}
});
export default function() {
postman[Request]({
name: "Collection Mock",
id: "",
method: "GET",
address:
"",
headers: {
Authorization: "Bearer {{currentAccessToken}}"
},
pre() {
const echoPostRequest = {
url: pm.environment.get("Access-Token-URL"),
method: "POST",
header: "Content-Type:x-www-form-urlencoded",
body: {
mode: "urlencoded",
urlencoded: [
{ key: "client_id", value: pm.environment.get("Client-Id") },
{
key: "client_secret",
value: pm.environment.get("Client-Secret")
},
{ key: "grant_type", value: pm.environment.get("Grant-Type") },
{ key: "scope", value: pm.environment.get("Token-Scope") }
]
}
};
var getToken = true;
if (
!pm.environment.get("accessTokenExpiry") ||
!pm.environment.get("currentAccessToken")
) {
console.log("Token or expiry date are missing");
} else if (
pm.environment.get("accessTokenExpiry") <= new Date().getTime()
) {
console.log("Token is expired");
} else {
getToken = false;
console.log("Token and expiry date are all good");
}
if (getToken === true) {
pm.sendRequest(echoPostRequest, function(err, res) {
console.log(err ? err : res.json());
if (err === null) {
console.log("Saving the token and expiry date");
var responseJson = res.json();
pm.environment.set("currentAccessToken", responseJson.access_token);
var expiryDate = new Date();
expiryDate.setSeconds(
expiryDate.getSeconds() + responseJson.expires_in
);
pm.environment.set("accessTokenExpiry", expiryDate.getTime());
}
});
}
}
});
}
The issue is with pm.sendRequest which is not supported by the converter and I'm not sure what the alternative is. So, I'm looking for ways to dynamically request access token from the authorization server and use that token to make a request to the API for load testing in k6 script.
As you have seen sendRequest is not supported ...
This is primarily because of the fact pm.sendRequest is asynchronous but k6 at this point doesn't have a event loop so ... no asynchronous http calls :( (except with http.batch but ... not
I find it unlikely that you want this to be asynchronous or ... well you can't do it with k6 at this point either way ... you can just rewrite it to use k6's http.post
As far as I can see this should look like
pre() {
var getToken = true;
if (
!pm.environment.get("accessTokenExpiry") ||
!pm.environment.get("currentAccessToken")
) {
console.log("Token or expiry date are missing");
} else if (
pm.environment.get("accessTokenExpiry") <= new Date().getTime()
) {
console.log("Token is expired");
} else {
getToken = false;
console.log("Token and expiry date are all good");
}
if (getToken === true) {
let res = http.post(pm.environment.get("Access-Token-URL"), {
"client_id": pm.environment.get("Client-Id") ,
"client_secret": pm.environment.get("Client-Secret"),
"grant_type": pm.environment.get("Grant-Type"),
"scope": pm.environment.get("Token-Scope")
});
console.log(err ? err : res.json());
if (err === null) {
console.log("Saving the token and expiry date");
var responseJson = res.json();
pm.environment.set("currentAccessToken", responseJson.access_token);
var expiryDate = new Date();
expiryDate.setSeconds(
expiryDate.getSeconds() + responseJson.expires_in
);
pm.environment.set("accessTokenExpiry", expiryDate.getTime());
}
}
Disclaimer: I have never used postman and the code above was written/copy-pasted by hand and not tested :)
I ended up using below code snippet to make a successful call for my purpose:
// Auto-generated by the Load Impact converter
import "./libs/shim/core.js";
import http from "k6/http";
import { check, sleep } from "k6";
export let options = {
max_vus: 10,
vus: 10,
stages: [
{ duration: "1m", target: 10 }
]
}
const Request = Symbol.for("request");
pm.environment.set("currentAccessToken", "");
pm.environment.set("accessTokenExpiry", "");
pm.environment.set("clientId", "");
pm.environment.set("clientSecret", "");
pm.environment.set("tokenScope", "");
pm.environment.set("grantType", "");
pm.environment.set("accesstokenUrl", "");
pm.environment.set("apiUrl", "");
pm.environment.set("subscriptionKeys", "");
export default function() {
var getToken = true;
if (!pm.environment.get("accessTokenExpiry") || !pm.environment.get("currentAccessToken")) {
//console.log("Token or expiry date are missing");
} else if (pm.environment.get("accessTokenExpiry") <= new Date().getTime()) {
//console.log("Token is expired");
} else {
getToken = false;
//console.log("Token and expiry date are all good");
}
if (getToken === true) {
//get the access token first
let res = http.post(pm.environment.get("accesstokenUrl"), {
"client_id": pm.environment.get("clientId"),
"client_secret": pm.environment.get("clientSecret"),
"grant_type": pm.environment.get("grantType"),
"scope": pm.environment.get("tokenScope")
});
var checkRes = check(res, {
"Token Request status is 200": (r) => r.status === 200,
});
if (checkRes) {
var responseJson = res.json();
pm.environment.set("currentAccessToken", responseJson.access_token);
var expiryDate = new Date();
expiryDate.setSeconds(
expiryDate.getSeconds() + responseJson.expires_in
);
pm.environment.set("accessTokenExpiry", expiryDate.getTime());
}
sleep(1);
//make the api request using the access token and subscription keys (if required)
let apiRes = http.get(pm.environment.get("apiUrl"),
{
headers: { "Authorization": "Bearer " + pm.environment.get("currentAccessToken"),
"Subscription-Key" : pm.environment.get("subscriptionKeys")
}
});
check(apiRes, {
"API Request status is 200": (res) => res.status === 200
});
sleep(3);
}
}

InvalidRequestException of status code 400 when AWS Lambda Function was invoked

var config = {};
config.IOT_BROKER_ENDPOINT = "abcdefghijk.iot.us-east-1.amazonaws.com".toLowerCase();
config.IOT_BROKER_REGION = "us-east-1";
config.IOT_THING_2 = "Thing1";
var AWS = require('aws-sdk');
AWS.config.region = config.IOT_BROKER_REGION;
AWS.config.update({accessKeyId: 'xxxxxxxxxxxxxxxxxxxx', secretAccessKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'});
var iotdata = new AWS.IotData({endpoint: config.IOT_BROKER_ENDPOINT});
// namespaces
const NAMESPACE_CONTROL = "Alexa.ConnectedHome.Control";
const NAMESPACE_DISCOVERY = "Alexa.ConnectedHome.Discovery";
// discovery
const REQUEST_DISCOVER = "DiscoverAppliancesRequest";
const RESPONSE_DISCOVER = "DiscoverAppliancesResponse";
// control
const REQUEST_TURN_ON = "TurnOnRequest";
const RESPONSE_TURN_ON = "TurnOnConfirmation";
const REQUEST_TURN_OFF = "TurnOffRequest";
const RESPONSE_TURN_OFF = "TurnOffConfirmation";
// errors
const ERROR_UNSUPPORTED_OPERATION = "UnsupportedOperationError";
const ERROR_UNEXPECTED_INFO = "UnexpectedInformationReceivedError";
// entry
exports.handler = function (event, context, callback) {
log("Received Directive", event);
var requestedNamespace = event.header.namespace;
var response = null;
try {
switch (requestedNamespace) {
case NAMESPACE_DISCOVERY:
response = handleDiscovery(event);
break;
case NAMESPACE_CONTROL:
response = handleControl(event);
break;
default:
log("Error", "Unsupported namespace: " + requestedNamespace);
response = handleUnexpectedInfo(requestedNamespace);
break;
}// switch
} catch (error) {
log("Error", error);
}// try-catch
callback(null, response);
}// exports.handler
var handleDiscovery = function (event) {
var header = createHeader(NAMESPACE_DISCOVERY, RESPONSE_DISCOVER);
var payload = {
"discoveredAppliances": [],
};
return createDirective(header, payload);
}// handleDiscovery
var handleControl = function (event) {
var response = null;
var requestedName = event.header.name;
switch (requestedName) {
case REQUEST_TURN_ON :
response = handleControlTurnOn(event);
break;
case REQUEST_TURN_OFF :
response = handleControlTurnOff(event);
break;
default:
log("Error", "Unsupported operation" + requestedName);
response = handleUnsupportedOperation();
break;
}// switch
return response;
}// handleControl
var handleControlTurnOn = function (event) {
var thingPicker = config.IOT_THING_2;
console.log("Turning On the LED now");
console.log("check 1");
var update = {
"desired": {
"led": 1,
},
};
console.log("check 2");
console.log(thingPicker);
iotdata.updateThingShadow({
payload: JSON.stringify(update),
thingName: thingPicker,
}, function (err, data) {
console.log("check 4");
if (err) {
console.log("check 5");
console.log(err);
} else {
console.log("check 6");
console.log(data);
}
});
var header = createHeader(NAMESPACE_CONTROL, RESPONSE_TURN_ON);
var payload = {};
return createDirective(header, payload);
}// handleControlTurnOn
var handleControlTurnOff = function (event) {
var thingPicker = config.IOT_THING_2;
console.log("Turning Off the LED now");
var update = {
"desired": {
"led": 0,
},
};
console.log(thingPicker);
iotdata.updateThingShadow({
payload: JSON.stringify(update),
thingName: thingPicker,
}, function (err, data) {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
var header = createHeader(NAMESPACE_CONTROL, RESPONSE_TURN_OFF);
var payload = {};
return createDirective(header, payload);
}// handleControlTurnOff
var handleUnsupportedOperation = function () {
var header = createHeader(NAMESPACE_CONTROL, ERROR_UNSUPPORTED_OPERATION);
var payload = {};
return createDirective(header, payload);
}// handleUnsupportedOperation
var handleUnexpectedInfo = function (fault) {
var header = createHeader(NAMESPACE_CONTROL, ERROR_UNEXPECTED_INFO);
var payload = {
"faultingParameter": fault,
};
return createDirective(header, payload);
}// handleUnexpectedInfo
// support functions
var createMessageId = function () {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
}// createMessageId
var createHeader = function (namespace, name) {
return {
"messageId": createMessageId(),
"namespace": namespace,
"name": name,
"payloadVersion": "2",
};
}// createHeader
var createDirective = function (header, payload) {
return {
"header": header,
"payload": payload,
};
}// createDirective
var log = function (title, msg) {
console.log('**** ' + title + ': ' + JSON.stringify(msg));
}// log
Piece of code related to AWS Lambda Function which is of smart home API, when it was run against a testing event to turn on light, its giving "InvalidRequestException" of status code :400
the test event that was run against the code was:
{
"header": {
"messageId" : "5d599a53-fe40-405f-b0ab-233611e2dc5c",
"name" : "TurnOnRequest",
"namespace" : "Alexa.ConnectedHome.Control",
"payloadVersion" : "2"
},
"payload" : {
"accessToken" : "acc355t0ken"
}
}
Can any one please help me solve that exception.
Thanks in advance

Duplicate existing contacts alert

In Vtiger 6.5.0 open source, I wants to create a alert function to warn users that the conact's mobile is existing? could you please help me. I'm fresher.
Thanks,
Loi
You can refer the function wich exist in Account module for checking Duplicate Account Name.
Please follow this files you will get an idea.
This is the code flow how its done In Account Module
Registring Pre Save Event
http://code.vtiger.com/vtiger/vtigercrm/blob/master/layouts/vlayout/modules/Accounts/resources/Edit.js#L250
This teh Fucntion to check Duplicate in cache, If not calls the Helper function
http://code.vtiger.com/vtiger/vtigercrm/blob/master/layouts/vlayout/modules/Accounts/resources/Edit.js#L83
This the Helper function which makes the call to server
http://code.vtiger.com/vtiger/vtigercrm/blob/master/resources/helper.js#L166
This is the action function which is responsible for Serving the request which came from Helper Function
http://code.vtiger.com/vtiger/vtigercrm/blob/master/modules/Accounts/actions/CheckDuplicate.php#L30
And this is the function which checks for Duplicate
http://code.vtiger.com/vtiger/vtigercrm/blob/master/modules/Accounts/models/Record.php#L57
Hope this helps.
Hi Victor please follow this steps
modules\Leads\actions\Checkprimaryemail.php
<?php
class Leads_Checkprimaryemail_Action extends Vtiger_BasicAjax_Action {
public function checkPermission(Vtiger_Request $request) {
return;
}
public function process(Vtiger_Request $request) {
global $adb;
$moduleName = $request->get('module');
$recordId = $request->get('recordId');
$primary_email = $request->get('primary_email');
/*Lead Details*/
$lead_query = "select * from vtiger_leaddetails
inner join vtiger_crmentity on vtiger_crmentity.crmid=vtiger_leaddetails.leadid
where vtiger_crmentity.deleted = 0 and vtiger_leaddetails.email='".$primary_email."'";
$lead_result = $adb->query($lead_query);
$lead_email = $adb->query_result($lead_result,0,'email');
$lead_numrows = $adb->num_rows($lead_result);
/*Contact Details*/
$cont_query = "select * from vtiger_contactdetails
inner join vtiger_crmentity on vtiger_crmentity.crmid=vtiger_contactdetails.contactid
where vtiger_crmentity.deleted = 0 and vtiger_contactdetails.email='".$primary_email."'";
$cont_result = $adb->query($cont_query);
$cont_email = $adb->query_result($cont_result,0,'email');
$cont_numrows = $adb->num_rows($cont_result);
if($recordId != '' ){
if($primary_email == $lead_email && $lead_numrows == 1 ){
$emailtrue = 0;
} elseif($primary_email == $cont_email && $cont_numrows >= 1 ) {
$emailtrue = 1;
}
} else {
if(($lead_numrows >=1 || $cont_numrows >=1 ) || ($lead_numrows >=1 && $cont_numrows >= 1) ){
$emailtrue = 1;
} else {
$emailtrue = 0;
}
}
$emailData = array($emailtrue);
$response = new Vtiger_Response();
$response->setResult($emailData);
$response->emit();
}
}
?>
After Create One other file
layouts\vlayout\modules\Leads\resources\Edit.js
Vtiger_Edit_Js("Leads_Edit_Js", {
}, {
changeEvent: function (container) {
jQuery('input[name="email"]').on('focusout', function (e) {
var email = jQuery('input[name="email"]').val();
var recordId = jQuery('input[name="record"]').val();
var email_length = email.length;
if (email != '') {
if (email_length > 100) {
var errorMessage = app.vtranslate('JS_EMAIL_LENGTH_VALIDATION');
params = {
text: errorMessage,
'type': 'error',
};
Vtiger_Helper_Js.showMessage(params);
}
var progressIndicatorElement = jQuery.progressIndicator({
'position': 'html',
'blockInfo': {
'enabled': true
}
});
var postData = {
"module": 'Leads',
"action": "Checkprimaryemail",
"primary_email": email,
"recordId": recordId
}
AppConnector.request(postData).then(
function (data) {
progressIndicatorElement.progressIndicator({'mode': 'hide'});
if (data['result'] == 1) {
jQuery('#emailalready_exists').val(1);
var errorMessage = app.vtranslate('JS_EMAIL_EXIST');
params = {
text: errorMessage,
'type': 'error',
};
Vtiger_Helper_Js.showMessage(params);
} else {
jQuery('#emailalready_exists').val(0);
}
},
function (error, err) {}
);
e.preventDefault();
}
});
},
registerBasicEvents: function (container) {
this._super(container);
this.changeEvent(container);
}
});
To check duplicate records in vTiger follow below steps:
Register checkDuplicate function in registerBasicEvents
1: \layouts\vlayout\modules\Contacts\resources\Edit.js
getmobile : function(container){
return jQuery('input[name="mobile"]',container).val();
},
getRecordId : function(container){
return jQuery('input[name="record"]',container).val();
},
DuplicateCheck : function(form) {
var thisInstance = this;
if(typeof form == 'undefined') {
form = this.getForm();
}
jQuery( "#mobileFieldId" ).change(function() {
var mobile = thisInstance.getmobile(form);
var recordId = thisInstance.getRecordId(form);
var params = {
'module' : "Contacts",
'action' : "CheckDuplicate",
'mobile' : mobile,
'record' : recordId
}
AppConnector.request(params).then(
function(data) {
var response = data['result'];
var result = response['success'];
if(result == true) {
var message_params = {
title : app.vtranslate('JS_MESSAGE'),
text: response['message'],
animation: 'show',
type: 'error'
};
Vtiger_Helper_Js.showPnotify(message_params);
jQuery(".btn-success").attr('disabled',true);
return false;
} else {
jQuery(".btn-success").attr('disabled',false);
}
}
);
});
},
2: Create new file in** \modules\Contacts\actions\CheckDuplicate.php
Follow the same process / code as given in \modules\Accounts\actions\CheckDuplicate.php
3: Add new function checkDuplicate() in \modules\Contacts\models\Record.php
And follow same process as given in \modules\Accounts\models\Record.php having function checkDuplicate()
Note: Don't forget to change the db table name, class name module wise.
Hope this will help you. Thank you.