1

I am a newbie in telegram bots creation and want to make a simple bot which allows a user to choose between a singer or actor photo in the commands and then using the flickr API send it to the chat:

const Telegraf = require('telegraf')
const { Router, Markup } = Telegraf
const axios = require('axios')
const api_key = '123'

const telegram = new Telegraf('123')

const inlineMessageRatingKeyboard = Markup.inlineKeyboard([
    Markup.callbackButton('Singer', 'singer'),
    Markup.callbackButton('Actor', 'actor')
]).extra()


const getSingerPhoto = () => {
    axios.get(`https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=${api_key}&tags=gerard+way&format=json&nojsoncallback=1`)
        .then(photosInfo => {
            const photosArray = (photosInfo.data && photosInfo.data.photos && photosInfo.data.photos.photo) || null;
            const photoObject = (photosArray && photosArray[photosArray.length * Math.random() | 0]) || null;
            let { server, id, secret } = photoObject;
            telegram.action('singer', (ctx) => {
                ctx.replyWithPhoto({
                    url: `https://live.staticflickr.com/${server}/${id}_${secret}_q.jpg`
                })
            })
        })
        .catch(error => console.log(error));
}

telegram.on('message', (ctx) => ctx.telegram.sendMessage(
    ctx.from.id,
    'What kind of photo do you want?',
    inlineMessageRatingKeyboard
)
)

telegram.command('singer', getSingerPhoto());

telegram.action('actor', (ctx) => {
    ctx.replyWithPhoto({
        source: './way.png'
    })
})

telegram.startPolling()

Flickr API is okay - I get the photo array (photosArray) and then take a random photo object (photoObject) from it, then I put it to the necessary photo URL (https://live.staticflickr.com/${server}/${id}_${secret}_q.jpg) and it generates okay too.

The problem is that it's always exactly the same photo, I have to always restart the bot to generate a new photo URL. What am I doing wrong, how to avoid it and send a random photo every time a user calls the command singer? Any help will be appreciated.

Radllaufer
  • 187
  • 1
  • 2
  • 10
  • Is the random generated photo always the same? So if getSingerPhoto() is executed, it returns the same images? Or is it happening when you send the image to telegram? – Alex Berger Feb 09 '21 at 09:02
  • "Is the random generated photo always the same" - yes, the photo changes only if I restart bot. getSingerPhoto() executes only once, no matter how many times I invoke it in using 'singer', command. If I use it without brakets (just getSingerPhoto) it doesn't execute at all and it looks strange for me :( – Sasha Chekmareva Feb 17 '21 at 18:10

1 Answers1

0

As i see in your code you executing getSingerPhoto only once

telegram.command('singer', getSingerPhoto());

just change it to

telegram.command('singer', getSingerPhoto);

edit:

i'm not familiar with telegraf api, but i also see that you registering action inside a response of axios, so that's why photo being cached

telegram.action('singer', (ctx) => {
              ctx.replyWithPhoto({
                  url: `https://live.staticflickr.com/${server}/${id}_${secret}_q.jpg`
              })
          })

so, instead add ctx param in getSingerPhoto(ctx) that you will get from command/action, just call it inside and remove another action that you have inside

edit2: completed code:

const getSingerPhoto = (ctx) => {
    axios.get(`https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=${api_key}&tags=gerard+way&format=json&nojsoncallback=1`)
        .then(photosInfo => {
            const photosArray = (photosInfo.data && photosInfo.data.photos && photosInfo.data.photos.photo) || null;
            const photoObject = (photosArray && photosArray[photosArray.length * Math.random() | 0]) || null;
            let { server, id, secret } = photoObject;
            ctx.replyWithPhoto({
                url: `https://live.staticflickr.com/${server}/${id}_${secret}_q.jpg`
            })
        })
        .catch(error => console.log(error));
}

telegram.action('singer', getSingerPhoto);
  • Сhanging telegram.command getSingerPhoto() to getSingerPhoto stops command executing at all (I don't know why). "Just call it inside and remove another action that you have inside" - it didn't help (works the same way, but maybe I have written smth wrong, can you please give me an example of what you meant ?). Thanks a lot for your answer anyway!:) – Sasha Chekmareva Feb 17 '21 at 18:14
  • @SashaChekmareva hey, right, you don't need command it should be action, added code sample to response under edit2. I'm sure that it should work as I tested it :) – Vlad Goldman Feb 18 '21 at 08:35