Telegram bot and CouchDB insert new user to DB - javascript

How Can I insert New Telegram Bot user to CouchDB?
I inserted a Sample Data jack johnsin db and was ok, But I Don't Know How Should I Take Telegram users Username and Put That in Db.
This is My Code:
import 'babel-polyfill';
import './env';
import TelegramBot from 'node-telegram-bot-api';
const bot = new TelegramBot(process.env.BOT_TOKEN, {polling: true});
/////////////////////////////////// Sample Data
var server = require('couch-db')('http://localhost:5984');
var db = server.database('users');
db.destroy(function(err) {
// create a new database
db.create(function(err) {
// insert a document with id 'jack johns'
db.insert({ _id: 'jack johns', name: 'jack' }, function(err, body) {
if (err) {
console.log('insertion failed ', err.message);
return;
}
console.log(body);
// body will like following:
// { ok: true,
// id: 'jack johns',
// rev: '1-610953b93b8bf1bae12427e2de181307' }
});
});
});
//////////////////////////////
bot.onText(/^[\/!#]start$/, msg => {
const opts = {
reply_to_message_id: msg.message_id,
reply_markup: JSON.stringify({
keyboard: [['Store username']],
resize_keyboard:true,
one_time_keyboard: true
})
};
bot.sendMessage(msg.chat.id, 'You Are Exist in DB', opts);
});

Solved By Myselfe,
For User ID You Can Use User_ID: msg.from.id
This is My Code:
bot.onText(/^[\/!#]start$/, msg => {
db.insert({ _id: msg.from.username }, function(err, body) {
if (err) {
console.log('insertion failed ', err.message);
return;
}
console.log(body);
});
const opts = {
reply_to_message_id: msg.message_id,
reply_markup: JSON.stringify({
keyboard: [['Store username']],
resize_keyboard:true,
one_time_keyboard: true
})
};
bot.sendMessage(msg.chat.id, 'You Are Exist in DB', opts);
});

Related

Getting error while reading outlook mails in Node.js

Goal: I am trying to read the mails (outlook) with certain filters like 'from specified user','read','sent' etc. Used a module "IMAP" for parsing. I have to read the mail and download and store attachments from the mail in a certain location (preferably local). But my code is failing to connect to the mail server.
Below is my code which results in 'Auth:timeout error' when I ran.
Please let me know what is wrong with my code. Thanks in advance!
var Imap = require('imap'),
inspect = require('util').inspect;
var fs = require('fs'), fileStream;
var buffer = '';
var myMap;
var imap = new Imap({
user: "put user id here",
password: "put your password here",
host: "outlook.office365.com", //this may differ if you are using some other mail services like yahoo
port: 993,
tls: true,
// connTimeout: 10000, // Default by node-imap
// authTimeout: 5000, // Default by node-imap,
debug: console.log, // Or your custom function with only one incoming argument. Default: null
tlsOptions: true,
mailbox: "INBOX", // mailbox to monitor
searchFilter: ["UNSEEN", "FLAGGED"], // the search filter being used after an IDLE notification has been retrieved
markSeen: true, // all fetched email willbe marked as seen and not fetched next time
fetchUnreadOnStart: true, // use it only if you want to get all unread email on lib start. Default is `false`,
mailParserOptions: { streamAttachments: true }, // options to be passed to mailParser lib.
attachments: true, // download attachments as they are encountered to the project directory
attachmentOptions: { directory: "attachments/" } // specify a download directory for attachments
});
function openInbox(cb) {
imap.openBox('INBOX', false, cb);
}
imap.once('ready', function () {
openInbox(function (err, box) {
if (err) throw err;
imap.search(['UNSEEN', ['SUBJECT', 'Give Subject Here']], function (err, results) {
if (err) throw err;
var f = imap.fetch(results, { bodies: '1', markSeen: true });
f.on('message', function (msg, seqno) {
console.log('Message #%d' + seqno);
console.log('Message type' + msg.text)
var prefix = '(#' + seqno + ') ';
msg.on('body', function (stream, info) {
stream.on('data', function (chunk) {
buffer += chunk.toString('utf8');
console.log("BUFFER" + buffer)
})
stream.once('end', function () {
if (info.which === '1') {
console.log("BUFFER" + buffer)
}
});
console.log(prefix + 'Body');
stream.pipe(fs.createWriteStream('msg-' + seqno + '-body.txt'));
});
msg.once('attributes', function (attrs) {
console.log(prefix + 'Attributes: %s', inspect(attrs, false, 8));
});
msg.once('end', function () {
console.log(prefix + 'Finished');
});
});
f.once('error', function (err) {
console.log('Fetch error: ' + err);
});
f.once('end', function () {
console.log('Done fetching all messages!');
imap.end();
});
});
});
});
imap.once('error', function (err) {
console.log(err);
});
imap.once('end', function () {
console.log('Connection ended');
});
imap.connect();
It's not exactly what you asked for but an alternative implementation that uses ImapFlow module instead of node-imap, and that I just verified to work against Outlook looks like the script below. If you still get timeouts etc. then it is probably a firewall issue.
const { ImapFlow } = require("imapflow");
const fs = require("fs").promises;
const client = new ImapFlow({
host: "outlook.office365.com",
port: 993,
secure: true,
auth: {
user: "example.user#hotmail.com",
pass: "secretpass",
},
logger: false, // set to true if you want to see IMAP transaction logs
});
// can't run await in main scope, have to wrap it to an async function
async function main() {
// establish the connection and log in
await client.connect();
// open INBOX folder
let mailbox = await client.mailboxOpen("INBOX");
// list messages matching provided criteria
for await (let msg of client.fetch(
{
// search query to filter messages
// https://imapflow.com/global.html#SearchObject
seen: false,
subject: "Give Subject Here",
},
{
// attributes to request for
// https://imapflow.com/global.html#FetchQueryObject
uid: true,
flags: true,
internalDate: true,
bodyStructure: true,
// include full message body in the response as well
source: true,
}
)) {
// extract variables
let { seq, uid, flags, bodyStructure, internalDate, source } = msg;
console.log(`#${seq} Attributes:`, { seq, uid, flags, bodyStructure, internalDate });
// store message body as an eml file
await fs.writeFile(`msg-${seq}.eml`, source);
}
// close the connection
await client.logout();
}
main().catch(console.error);

Is there a correct way to handle promisified stream error in Nodejs

I am trying to catch an error in the controller and send status(500) to the front-end to let the user know that there is a streaming error. But for some reason the error is not caught and I am sending status(200) to the user. Let me know if i am doing something wrong.
file - utils.js
import WebSocket from 'ws';
import Twitter from 'twitter-lite';
import ck from 'ckey';
export const stream = (term, clients, twitterStream) => {
try {
const twitter = new Twitter({
// subdomain: 'api', // "api" is the default (change for other subdomains)
// version: '1.1', // version "1.1" is the default (change for other subdomains)
version: '2', // version "1.1" is the default (change for v2)
extension: false, // true is the default (this must be set to false for v2 endpoints)
consumer_key: ck.TWITTER_CONSUMER_KEY,
consumer_secret: ck.TWITTER_CONSUMER_SECRET,
access_token_key: ck.TWITTER_ACCESS_TOKEN_KEY,
access_token_secret: ck.TWITTER_ACCESS_TOKEN_SECRET,
});
let stream = twitter.stream('statuses/filter', { track: term });
new Promise(function (resolve, reject) {
stream.on('data', function (tweet) {
console.log('tweet');
resolve(broadcast(clients, JSON.stringify(tweet)));
});
stream.on('error', function (error) {
reject(error);
});
}).catch(function (e) {
console.log('stream error catch: ', e);
// throw e;
});
twitterStream = stream;
return twitterStream;
} catch (error) {
console.log('error from util', error);
// throw error;
}
};
const broadcast = (clients, message) => {
clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
};
controller
import { stream } from './utils.js';
let twitterStream;
// Sets search term for twitter stream.
export const setSearchTerm = (req, res) => {
try {
const { term } = req.params;
console.log('setSearchTerm');
console.log('term: ', term);
if (twitterStream) {
console.log('getTweetPause');
twitterStream.destroy();
}
twitterStream = stream(term, req.app.locals.clients, twitterStream);
res.status(200).json({ message: 'Successful search request' });
} catch (error) {
res.status(500).json({ message: error });
}
};
file - utils.js
import WebSocket from 'ws';
import Twitter from 'twitter-lite';
import ck from 'ckey';
export const stream = (term) => {
const twitter = new Twitter({
// subdomain: 'api', // "api" is the default (change for other subdomains)
// version: '1.1', // version "1.1" is the default (change for other subdomains)
version: '2', // version "1.1" is the default (change for v2)
extension: false, // true is the default (this must be set to false for v2 endpoints)
consumer_key: ck.TWITTER_CONSUMER_KEY,
consumer_secret: ck.TWITTER_CONSUMER_SECRET,
access_token_key: ck.TWITTER_ACCESS_TOKEN_KEY,
access_token_secret: ck.TWITTER_ACCESS_TOKEN_SECRET,
});
let stream = twitter.stream('statuses/filter', { track: term });
return stream;
};
export const broadcast = (clients, message) => {
clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
};
controller
import { stream, broadcast } from './utils.js';
let twitterStream;
// Sets search term for twitter stream.
export const setSearchTerm = async (req, res) => {
try {
const { term } = req.params;
console.log('setSearchTerm');
console.log('term: ', term);
if (twitterStream) {
console.log('getTweetPause');
twitterStream.destroy();
}
const currentStream = stream(term);
twitterStream = currentStream;
await new Promise((resolve, reject) => {
currentStream.on('data', function (tweet) {
console.log('tweets: ');
broadcast(req.app.locals.clients, JSON.stringify(tweet));
resolve(tweet);
});
currentStream.on('error', function (error) {
reject(error);
});
});
res.status(200).json({ message: 'Successful HTTP request' });
} catch (error) {
console.log('error catch: ');
res.status(500).json({ message: error });
}
};

Sequelize update information

I've been struggling with this issue for a day now and can't seem to figure out a way to resolve it. This is the code I'm running
Client side:
const nameInput = document.querySelector("#nameInput");
const urlInput = document.querySelector("#urlInput");
const rowAlert = document.querySelector(".alertAppend");
const divAlert = document.createElement("div");
const nameUpdate = async (e) => {
e.preventDefault();
fetch("/auth/updateName", {
method: 'POST',
headers: {
'Content-Type' : 'application/json'
},
body: JSON.stringify({
name: nameInput,
url: urlInput,
})
})
.then(function (data) {
console.log('Request success: ', data);
})
.catch(function (error) {
console.log('Request failure: ', error);
});
};
submitName.addEventListener("click", nameUpdate);
API:
router.get("/updateName", auth, async (req, res) =>{
try {
const { name, url } = req.body;
const ime = name;
const uid = req.session.passport.user;
db.User.find({ where: { id: uid } })
.on('success', function (user) {
if (user) {
user.update({
name: ime,
webhook: url
})
.success(function () {})
}
})
res.json({ message: url});
} catch (err) {
if (err) res.status(500).json({ message: "Internal Error"})
}
});
For some reason it just runs the select query and never proceeds to update the user.
Chrome console output
Debug console output
Sequelize model in case it helps:
module.exports = function (sequelize, DataTypes) {
var User = sequelize.define("User", {
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true
}
},
password: {
type: DataTypes.STRING,
allowNull: false
},
name: {
type: DataTypes.STRING
}
})
return User;
}
The issue was in the API, it's supposed to be router.post
router.post("/updateName", auth, async (req, res) =>{
const { ime, url } = req.body;
const uid = req.session.passport.user;
console.log(ime);
db.User.findOne({where: {id: uid}})
.then(record => {
let values = {
name: ime,
webhook: url
}
record.update(values).then( updatedRecord => {
console.log(`updated record ${JSON.stringify(updatedRecord,null,2)}`)
res.status(200).json({ message: "success"});
})
}
})
.catch((error) => {
// do seomthing with the error
throw new Error(error)
})
});
You can try the following code
await db.User.update({
name: ime,
webhook: url
}, { where: { id: uid } });
When defining your model I don't see the webhook field

mongodb Error mongoose do not push object in array $pushAll

I have a simple app with User and Post models,
var mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/assoc", {useMongoClient:true});
mongoose.Promise = global.Promise;
//Post
var postSchema = new mongoose.Schema({
title: String,
content: String
});
var Post = mongoose.model("Post", postSchema);
//User
var userSchema = new mongoose.Schema({
email: String,
name: String,
posts: [postSchema]
});
var User = mongoose.model("User", userSchema);
I Create a user before (name: "gino") and push a post into:
// var newUser = new User({
// email: "a.b#c.it",
// name: "gino"
// });
//
// newUser.posts.push({
// title: "gino's post",
// content: "this is content"
// });
//
// newUser.save(function (err, user) {
// if (err) {
// console.log(err);
// } else {
// console.log(user);
// }
// });
Also create another post to check if Post model works:
// var newPost = new Post({
// title: "honky",
// content: "tonky"
// });
//
// newPost.save(function (err, post) {
// if (err) {
// console.log(err);
// } else {
// console.log(post);
// }
// });
When I try to find "gino" and push a new item into the posts array I have an error trying to save user (user.save) with this snippet:
User.findOne({name: "gino"}, function (err, user) {
if (err) {
console.log(err);
} else {
console.log(user);
user.posts.push({
title: "post",
content: "content"
});
user.save(function (err, user) {
if (err) {
console.log(err);
} else {
console.log(user);
}
});
}
});
When I run the app i got this:
{ MongoError: Unknown modifier: $pushAll
at Function.MongoError.create (appFolder\node_modules\mongodb-core\lib\error.js:31:11)
at toError (appFolder\node_modules\mongodb\lib\utils.js:139:22)
at appFolder\node_modules\mongodb\lib\collection.js:1059:67
at appFolder\node_modules\mongodb-core\lib\connection\pool.js:469:18
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
name: 'MongoError',
message: 'Unknown modifier: $pushAll',
driver: true,
index: 0,
code: 9,
errmsg: 'Unknown modifier: $pushAll' }
Someone can help me?
Try using findOneAndUpdate instead.
User.findOneAndUpdate(
{ name: "gino" },
{ $push: { posts: { title: 'post', content: 'content' } } },
{ new: true },
function (err, user) {
if(err) console.log("Something wrong when updating data");
console.log(user);
});
Hope it helps!
If you are using 3.5 MongoDB version or higher, can be an issue with $pushAll, which is deprecated.
I founded an option to work around setting usePushEach to true:
new Schema({ arr: [String] }, { usePushEach: true });
Founded in:
https://github.com/Automattic/mongoose/issues/5574#issuecomment-332290518
Can be useful to use the with .push.

How to send push notifications form javascript using quickblox

I am trying to send push notifications messages through Quickblox from my backend server. The code that does this goes like the following:
app.post('/requests', function(req, res) {
var mobileNumber = req.param('mobile_number');
if (typeof mobileNumber === 'undefined') {
return res.badRequest("Parameters missing: [mobile_number]");
}
var query = {
international_number: mobileNumber
}
User.findOne(query, function(err, user) {
if (err) {
return res.dbError(err);
}
if (!user) {
console.log("User not found");
return res.apiError("NOT_FOUND");
}
var request = new Request();
request.sender_id = req.user._id;
request.receiver_id = user._id;
request.status = 'pending';
request.save(function(err) {
if (err) {
return res.dbError(err);
}
var response = {};
response.image_url = user.image_url;
response.id = request._id;
// ¡TODO! Notify the end user -- Quickblox
QB.createSession(function(err, result) {
if (err) {
console.log(err);
return res.apiError();
}
console.log("**** SESSION CREATE ****")
console.log(result);
var params = {
login: req.user.qb_username,
password: req.user.qb_password
}
console.log("LOGIN PARAMS");
console.log(params);
QB.login(params, function(err, result) {
if (err) {
console.log(err);
return res.apiError();
}
console.log("**** USER LOGIN ****")
console.log(result);
var params = {
notification_type: 'push',
environment: 'production',
user : {
ids: user.qb_id
},
message: 'SSBsb3ZlIE0mTSdzISBFc3BlY2lhbGx5IHJlZCBvbmUh',
push_type: user.device.notification_channel
}
console.log("EVENTS CREATE PARAMS");
console.log(params);
QB.messages.events.create(params, function(err, result) {
if (err) {
console.log(err);
return res.apiError();
}
console.log("**** MESSAGE EVENT CREATE ****");
console.log(result);
console.log(result.event.subscribers_selector);
QB.messages.events.list(function(err, result) {
if (err) {
console.log(err);
return res.apiError();
}
console.log(result);
console.log("**** EVENTS LIST ****");
console.log(result.items);
res.apiSend(response);
});
});
});
});
});
});
});
Note that I am logging the response after every single Quickblox request. So the log after QB.messages.events.create() is the following:
**** MESSAGE EVENT CREATE ****
{ event:
{ active: true,
application_id: 18113,
created_at: '2015-01-13T10:32:45Z',
date: null,
end_date: null,
event_type: 'one_shot',
id: 1809320,
message: 'data.message=SStsb3ZlK00lMjZNJTI3cyUyMStFc3BlY2lhbGx5K3JlZCtvbmUlMjE=',
name: null,
occured_count: 0,
period: null,
updated_at: '2015-01-13T10:32:45Z',
user_id: 2185263,
notification_channel: { name: 'gcm' },
subscribers_selector:
{ environment: 'production',
tags_query: null,
user_ids: [Object] } } }
and when i list the events using QB.messages.events.list() i get the following response:
{ current_page: 1,
per_page: 10,
total_entries: 19,
items:
[ { event: [Object] },
{ event: [Object] },
{ event: [Object] },
{ event: [Object] },
{ event: [Object] },
{ event: [Object] },
{ event: [Object] },
{ event: [Object] },
{ event: [Object] },
{ event: [Object] } ] }
Therefore it says that there are 19 entries in the messages queue and everything seems to be OK.
However when I login to my Quickblox account and check the messages queue it is always empty and therefore no messages are scheduled to be sent. Note as well that subscriptions show the users subscribed to push notification services such as 'gcm' and 'apns'. Can anyone help me find out why is this happening please?
You need encode the message to base64.
You need to make sure your mobile app would know to understand the decoded message.
For example,
sending push notification to android qb_user_id: 20290
(and from me - my qb_user_id: 12121):
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
function send_push() {
var params = {
notification_type: 'push',
push_type: 'gcm',
user: {ids: [20290]},
environment: "production",
message: b64EncodeUnicode('{"message":"HELLO WORLD","user_id":12121,"device_type":"WEB","message_qb_id":"563a55a44cedaa83885724cf","message_type":"Text","send_status":"BeingProcessed","send_time":1446663588607}')
};
QB.messages.events.create(params, function(err, response) {
if (err) {
console.log("QB.messages.events.create::error:" +err);
} else {
console.log("QB.messages.events.create::response:" + response);
}
});
}
In this example, the mobile app is looking for a message in this format:
{"message","user_id","device_type","message_qb_id","message_type","send_status","send_time"}

Categories

Resources