Skip to content

Commit 7c0a8d0

Browse files
committed
- added Contacts class
- added Redis support - added in .env: CONTACTS_LOOKUP_ENDPOINT, REDIS_HOST, REDIS_PASSWORD, REDIS_PORT, CACHE_ENABLED - test, added embedded CONTACTS_LOOKUP_ENDPOINT - test, fixed await tdcache
1 parent 0a9449c commit 7c0a8d0

File tree

11 files changed

+1141
-540
lines changed

11 files changed

+1141
-540
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11

2+
**npm @chat21/chat21-http-server@0.2.11**
3+
4+
available on:
5+
▶️ https://www.npmjs.com/package/@chat21/chat21-http-server
6+
7+
## v0.2.11
8+
- test, added embedded CONTACTS_LOOKUP_ENDPOINT
9+
- test, fixed await tdcache
10+
11+
## v0.2.10
12+
- added Contacts class
13+
- added Redis support
14+
- added in .env: CONTACTS_LOOKUP_ENDPOINT, REDIS_HOST, REDIS_PASSWORD, REDIS_PORT, CACHE_ENABLED
15+
216
## v0.2.9
317
- added /:appid/:userid/archived_conversations/:conversWith endpoint
18+
- fixed conversationDetail() bug (not discrimitating history/archived conversations)
419

520
## v0.2.8
621
- chat21Api.joinGroupMessages(): forced message.status = 150 in history messages after a join

Contacts.js

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
const axios = require('axios'); // ONLY FOR TEMP PUSH WEBHOOK ENDPOINT
2+
3+
class Contacts {
4+
5+
constructor(config) {
6+
this.CONTACTS_LOOKUP_ENDPOINT = config.CONTACTS_LOOKUP_ENDPOINT;
7+
this.tdcache = config.tdcache;
8+
this.log = config.log;
9+
}
10+
11+
/**
12+
* Returns the contact info
13+
* @param {callback} callback - The callback that handles the response.
14+
* @param {string} contact_id - The contact id.
15+
*/
16+
async getContact(contact_id, callback) {
17+
if (this.log) {
18+
console.log("Getting contacts:", contact_id);
19+
console.log("Getting contacts CONTACTS_LOOKUP_ENDPOINT", this.CONTACTS_LOOKUP_ENDPOINT);
20+
console.log("Getting contacts tdcache", this.tdcache);
21+
}
22+
if (this.tdcache) {
23+
let contact_string = await this.tdcache.get("contacts:" + contact_id);
24+
if (contact_string) {
25+
const contact = JSON.parse(contact_string);
26+
if (contact) {
27+
contact.cached = true;
28+
if (callback) {
29+
callback(contact);
30+
}
31+
return contact;
32+
}
33+
}
34+
}
35+
const URL = `${this.CONTACTS_LOOKUP_ENDPOINT}/${contact_id}`
36+
if (this.log) {
37+
console.log("Contacts URL:", URL)
38+
}
39+
const HTTPREQUEST = {
40+
url: URL,
41+
headers: {
42+
'Content-Type' : 'application/json'
43+
//'Authorization': this.jwt_token
44+
},
45+
method: 'GET'
46+
};
47+
let contact = null;
48+
contact = await this.myrequest(HTTPREQUEST);
49+
if (contact) {
50+
const contact_key = "contacts:" + contact_id;
51+
if (this.log) {
52+
console.log("contact found:", contact);
53+
console.log("contact key:", contact_key);
54+
}
55+
const contact_string = JSON.stringify(contact);
56+
if (this.tdcache) {
57+
if (this.log) {
58+
console.log("Caching contact as string:", contact_string);
59+
}
60+
this.tdcache.set(contact_key, contact_string, { EX: 120 });
61+
}
62+
}
63+
return contact;
64+
// (err, contact) => {
65+
// if (err) {
66+
// if (callback) {
67+
// callback(err);
68+
// }
69+
// }
70+
// else {
71+
// if (contact) {
72+
// console.log("contact found", contact);
73+
// const contact_string = JSON.stringify(contact);
74+
// this.tdcache.set("contacts:" + contact_id, contact_string, { EX: 120 });
75+
// }
76+
// if (callback) {
77+
// callback(null, contact);
78+
// }
79+
// return contact;
80+
// }
81+
// });
82+
}
83+
84+
static getFullnameOf(contact) {
85+
if (contact && contact.fullname) {
86+
return contact.fullname.trim();
87+
}
88+
else if (contact && contact.firstname && contact.lastname) {
89+
return (contact.firstname.trim() + " " + contact.lastname.trim()).trim();
90+
}
91+
else if (contact.firstname) {
92+
return contact.firstname.trim();
93+
}
94+
else if (contact.lastname) {
95+
return contact.lastname.trim();
96+
}
97+
return "";
98+
}
99+
// ************************************************
100+
// ****************** HTTP REQUEST ****************
101+
// ************************************************
102+
103+
async myrequest(options, callback) {
104+
return new Promise( (resolve, reject) => {
105+
if (this.log) {
106+
console.log("API URL:", options.url);
107+
console.log("** Options:", options);
108+
}
109+
axios(
110+
{
111+
url: options.url,
112+
method: options.method,
113+
data: options.json,
114+
params: options.params,
115+
headers: options.headers
116+
})
117+
.then( (res) => {
118+
if (this.log) {
119+
console.log("Response for url:", options.url);
120+
console.log("Response headers:\n", res.headers);
121+
}
122+
if (res && res.status == 200 && res.data) {
123+
if (callback) {
124+
callback(null, res.data);
125+
}
126+
resolve(res.data);
127+
}
128+
else {
129+
if (callback) {
130+
const error = { message: "Response status error" };
131+
callback(error, null);
132+
}
133+
reject(error);
134+
}
135+
})
136+
.catch( (error) => {
137+
console.error("An error occurred:", error);
138+
if (callback) {
139+
callback(error, null);
140+
}
141+
reject(error);
142+
});
143+
})
144+
}
145+
146+
}
147+
148+
module.exports = { Contacts };

TdCache.js

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
const redis = require('redis');
2+
3+
class TdCache {
4+
5+
constructor(config) {
6+
this.redis_host = config.host;
7+
this.redis_port = config.port;
8+
this.redis_password = config.password;
9+
this.client = null;
10+
}
11+
12+
async connect(callback) {
13+
// client = redis.createClient();
14+
return new Promise( async (resolve, reject) => {
15+
this.client = redis.createClient(
16+
{
17+
host: this.redis_host,
18+
port: this.redis_port,
19+
password: this.redis_password
20+
});
21+
this.client.on('error', err => {
22+
console.error('Redis connection error', err);
23+
reject(err);
24+
if (callback) {
25+
callback(err);
26+
}
27+
});
28+
// this.client.on('connect', function() {
29+
// console.log('Redis Connected!');
30+
// });
31+
this.client.on('ready',function() {
32+
resolve();
33+
if (callback) {
34+
callback();
35+
}
36+
});
37+
});
38+
}
39+
40+
async set(key, value, options) {
41+
return new Promise( async (resolve, reject) => {
42+
if (options && options.EX) {
43+
try {
44+
await this.client.set(
45+
key,
46+
value,
47+
'EX', options.EX);
48+
}
49+
catch(error) {
50+
reject(error)
51+
}
52+
}
53+
else {
54+
try {
55+
//console.log("setting here...key", key, value)
56+
await this.client.set(
57+
key,
58+
value);
59+
}
60+
catch(error) {
61+
console.error("Error", error);
62+
reject(error)
63+
}
64+
}
65+
if (options && options.callback) {
66+
options.callback();
67+
}
68+
//console.log("resolving...", key);
69+
return resolve();
70+
});
71+
}
72+
73+
async hset(dict_key, key, value, options) {
74+
//console.log("hsetting dict_key key value", dict_key, key, value)
75+
return new Promise( async (resolve, reject) => {
76+
if (options && options.EX) {
77+
//console.log("expires:", options.EX)
78+
try {
79+
await this.client.hset(
80+
dict_key,
81+
key,
82+
value,
83+
'EX', options.EX);
84+
}
85+
catch(error) {
86+
reject(error)
87+
}
88+
}
89+
else {
90+
try {
91+
//console.log("setting here...key", key, value)
92+
await this.client.hset(
93+
dict_key,
94+
key,
95+
value);
96+
}
97+
catch(error) {
98+
console.error("Error", error);
99+
reject(error)
100+
}
101+
}
102+
if (options && options.callback) {
103+
options.callback();
104+
}
105+
return resolve();
106+
});
107+
}
108+
109+
async setJSON(key, value, options) {
110+
const _string = JSON.stringify(value);
111+
return await this.set(key, _string, options);
112+
}
113+
114+
async get(key, callback) {
115+
//console.log("getting key", key)
116+
return new Promise( async (resolve, reject) => {
117+
this.client.get(key, (err, value) => {
118+
if (err) {
119+
reject(err);
120+
}
121+
else {
122+
if (callback) {
123+
callback(value);
124+
}
125+
return resolve(value);
126+
}
127+
});
128+
});
129+
}
130+
131+
async hgetall(dict_key, callback) {
132+
//console.log("hgetting dics", dict_key);
133+
return new Promise( async (resolve, reject) => {
134+
this.client.hgetall(dict_key, (err, value) => {
135+
if (err) {
136+
reject(err);
137+
if (callback) {
138+
callback(err, null);
139+
}
140+
}
141+
else {
142+
if (callback) {
143+
callback(null, value);
144+
}
145+
resolve(value);
146+
}
147+
});
148+
});
149+
}
150+
151+
async getJSON(key, callback) {
152+
const value = await this.get(key);
153+
return JSON.parse(value);
154+
}
155+
156+
async del(key, callback) {
157+
return new Promise( async (resolve, reject) => {
158+
await this.client.del(key);
159+
if (callback) {
160+
callback();
161+
}
162+
return resolve();
163+
})
164+
}
165+
}
166+
167+
module.exports = { TdCache };

bin/www.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,15 @@ async function start() {
2323
console.log('HTTPS server started.')
2424
console.log('Starting AMQP publisher...');
2525
//chat21HttpServer.startAMQP();
26-
chat21HttpServer.startAMQP({rabbitmq_uri: process.env.RABBITMQ_URI});
26+
chat21HttpServer.startAMQP(
27+
{
28+
rabbitmq_uri: process.env.RABBITMQ_URI,
29+
REDIS_HOST: process.env.REDIS_HOST,
30+
REDIS_PORT: process.env.REDIS_PORT,
31+
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
32+
CACHE_ENABLED: process.env.CACHE_ENABLED
33+
}
34+
);
2735
});
2836
}
2937
else {
@@ -32,7 +40,15 @@ async function start() {
3240
console.log('HTTP server started.')
3341
console.log('Starting AMQP publisher...');
3442
//chat21HttpServer.startAMQP();
35-
chat21HttpServer.startAMQP({rabbitmq_uri: process.env.RABBITMQ_URI});
43+
chat21HttpServer.startAMQP(
44+
{
45+
rabbitmq_uri: process.env.RABBITMQ_URI,
46+
REDIS_HOST: process.env.REDIS_HOST,
47+
REDIS_PORT: process.env.REDIS_PORT,
48+
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
49+
CACHE_ENABLED: process.env.CACHE_ENABLED
50+
}
51+
);
3652
});
3753
}
3854

0 commit comments

Comments
 (0)