telegraf / telegraf-session-redis

Redis session middleware for Telegraf
MIT License
50 stars 25 forks source link

doesn't save session inside Promise.then() #4

Closed pooyakn closed 7 years ago

pooyakn commented 7 years ago

Hi. I have a problem with modifying session inside promises. Telegraf default session works fine, but after changing to Redis session it doesn't work. This is my code. I left a comment next to the line that doesn't get saved.

const { infoButtonText, backButtonText,
    dietButtonText, cookingButtonText,
    traditionalMedicineButtonText } = require('./data/buttonTexts');
const { infoMarkup, defaultMarkup, navMarkup } = require('./markup/main');
const { hasPurchased } = require('./controllers/purchaseController');
const { redis, session } = require('./database/redis');
module.exports = function (app) {
    app.hears(infoButtonText, (ctx) => {
        ctx.session.state = 'infoList';
        return ctx.replyWithMarkdown('test', infoMarkup);
    });

    app.hears(backButtonText, (ctx) => {
        switch (ctx.session.state) {
            case 'infoList':
                return ctx.replyWithMarkdown('test', defaultMarkup);
            case 'diet':
            case 'cooking':
            case 'tarditionalMedicine':
                return ctx.replyWithMarkdown('test', infoMarkup);
        }
    });

    app.hears(dietButtonText, (ctx) => {        
        ctx.session.state = 'diet';
        ctx.session.dietIndex = ctx.session.dietIndex || 1; 
        console.log('index out is', ctx.session.dietIndex);
        ctx.replyWithMarkdown('test', navMarkup).then(() => {
            return checkPurchase(ctx);
        }).then((hasPurchased) => {
            if (hasPurchased === true) {
                if (ctx.session.dietIndex === 1) {
                    sendNote(ctx, 'diet', ctx.session.dietIndex).then(() => {
                        ctx.session.dietIndex = ctx.session.dietIndex + 1; // this line doesn't affect the session.
                        session.saveSession(`${ctx.from.id}:${ctx.chat.id}`, ctx.session); // I should save user session here, otherwise it's not available on the second run.
                        console.log('index in is', ctx.session.dietIndex); // it logs 2 here, but the second time it is still 1
                    });
                } else {
                    return ctx.reply('bar mohtava bishtar bezan badi ');
                }
            } else {
                if (ctx.session.dietIndex > 2) {
                    ctx.reply('bekhar')
                } else if (ctx.session.dietIndex === 1) {
                    sendNote(ctx, 'diet', ctx.session.dietIndex);
                    ctx.session.dietIndex = ctx.session.dietIndex + 1;
                } else {
                    return ctx.reply('bar mohtava bishtar bezan badi ');
                }
            }
        });
    });
}

function checkPurchase(ctx) {
    console.log(ctx.from.id);
    if (ctx.session.hasPurchased === true) {
        return Promise.resolve(true);
    } else {
        return hasPurchased(ctx).then((purchase) => {
            if (purchase === true) {
                ctx.session.hasPurchased = true;
                return Promise.resolve(true);
            } else {
                return Promise.resolve(false);
            }
        }).catch(err => console.log('Error:', err));
    }
}

function catchError(error) {
    console.log('Error:', err);
}

function sendNote(ctx, type, index) {
    return redis.get(`${type}_note_${index}`).then((note) => {
        return ctx.reply(note).then(() => {
            return ctx.reply('bezan badi');
        }).catch(catchError);
    });
}

Thanks.

dotcypress commented 7 years ago

Hey @Starless-Sky

I see couple of errors, see updated code:

const { infoButtonText, backButtonText,
    dietButtonText, cookingButtonText,
    traditionalMedicineButtonText } = require('./data/buttonTexts');
const { infoMarkup, defaultMarkup, navMarkup } = require('./markup/main');
const { hasPurchased } = require('./controllers/purchaseController');
const { redis, session } = require('./database/redis');
module.exports = function (app) {
    app.hears(infoButtonText, (ctx) => {
        ctx.session.state = 'infoList';
        return ctx.replyWithMarkdown('test', infoMarkup);
    });

    app.hears(backButtonText, (ctx) => {
        switch (ctx.session.state) {
            case 'infoList':
                return ctx.replyWithMarkdown('test', defaultMarkup);
            case 'diet':
            case 'cooking':
            case 'tarditionalMedicine':
                return ctx.replyWithMarkdown('test', infoMarkup);
        }
    });

    app.hears(dietButtonText, (ctx) => {        
        ctx.session.state = 'diet';
        ctx.session.dietIndex = ctx.session.dietIndex || 1; 
        console.log('index out is', ctx.session.dietIndex);
        return ctx.replyWithMarkdown('test', navMarkup).then(() => {
            return checkPurchase(ctx);
        }).then((hasPurchased) => {
            if (hasPurchased === true) {
                if (ctx.session.dietIndex === 1) {
                    return sendNote(ctx, 'diet', ctx.session.dietIndex).then(() => {
                        ctx.session.dietIndex = ctx.session.dietIndex + 1; // this line doesn't affect the session.
                    });
                } else {
                    return ctx.reply('bar mohtava bishtar bezan badi ');
                }
            } else {
                if (ctx.session.dietIndex > 2) {
                    ctx.reply('bekhar')
                } else if (ctx.session.dietIndex === 1) {
                    sendNote(ctx, 'diet', ctx.session.dietIndex);
                    ctx.session.dietIndex = ctx.session.dietIndex + 1;
                } else {
                    return ctx.reply('bar mohtava bishtar bezan badi ');
                }
            }
        });
    });
}

function checkPurchase(ctx) {
    console.log(ctx.from.id);
    if (ctx.session.hasPurchased === true) {
        return Promise.resolve(true);
    } else {
        return hasPurchased(ctx).then((purchase) => {
            if (purchase === true) {
                ctx.session.hasPurchased = true;
                return Promise.resolve(true);
            } else {
                return Promise.resolve(false);
            }
        }).catch(err => console.log('Error:', err));
    }
}

function catchError(error) {
    console.log('Error:', err);
}

function sendNote(ctx, type, index) {
    return redis.get(`${type}_note_${index}`).then((note) => {
        return ctx.reply(note).then(() => {
            return ctx.reply('bezan badi');
        }).catch(catchError);
    });
}
pooyakn commented 7 years ago

@dotcypress Thanks. You saved my life! I didn't know I should always return.

dotcypress commented 7 years ago

@Starless-Sky no problem ;) Also, check this conversation: https://github.com/telegraf/telegraf/issues/80