skip to Main Content

I’m developing a chat bot for Telegram using DialogFlow, but I can’t go through two topics, and I can’t find the documentation for them.

The flow of the conversation, is the user answer some closed questions and send an image.
How do I get this image?
And to save her along with the other answers?

The answers need to be saved as a form/survey and not as a conversation history.

2

Answers


  1. I have a similar setup in my chatbot. I store the answers in a Firebase database.

    In order to interact with the Firestore Database you should implement a Fulfillment

    You can see a guide on how to implement Firebase for DialogFlow here

    Here you can see a sample of my code. In general lines after setting up the connection to the Firebase database you just want to map your intents to your functions using intentMap.set.

    As you said you are using closed answers you can set intets to handle the responses and each “final” intent will trigger a different function that will write a different message to the db.

    To write the response to the Firesbase database you just only need to implement admin.database().ref().push().set({}) with the information and the desired structure.

    In my example I also store the conversation Id from the chat payload and the date.

    'use strict';
    
    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    const {WebhookClient} = require('dialogflow-fulfillment');
    const {Card, Suggestion} = require('dialogflow-fulfillment');
    //const DialogflowApp = require('actions-on-google').DialogflowApp;
    
    process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
    
    admin.initializeApp({
      credential : admin.credential.applicationDefault(),
      databaseURL: 'ws://YOURDATABASE.firebaseio.com/'
    });
    
    exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
      const agent = new WebhookClient({ request, response });
      console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
      console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
      var userId;
      let conv = agent.conv();
      const ROOTREF = admin.database().ref();
    
      const actions = new Map();
      let intentMap = new Map();
      intentMap.set('Default Fallback Intent', fallback);
      intentMap.set('NoTunel',  handleWriteToDbNoTunnel(agent));
      agent.handleRequest(intentMap);
    
      function assignConv(agent){
        userId = agent.parameters.UserId;
        return admin.database().ref('Users/'+ userId).set({
            Apellido:"XXXX",
            Nombre:"XXXX",
            chatId:333, 
      });}
    
      function fallback(agent) {
        agent.add(`I didn't understand`);
        agent.add(`I'm sorry, can you try again?`);
      }      
      var token = "YOUR TOKEN HERE";
      var url = "https://api.telegram.org/bot"+ token;
      function handleWriteToDbNoTunnel(agent){
        const Dia = new Date();
        if(matricula !== "")
        return admin.database().ref('Limpieza/').push().set({
            chatId: request.body.queryResult.outputContexts[3].parameters.telegram_chat_id+'"',
            Field1: answer1,
            Field2: answer2,
            day: day.getTime()
          });
       }
    });
    

    Also if you want to store images with the user responses you can implement the getfile method from the telegram api and store the image code or the image itself

    Login or Signup to reply.
  2. I am adding this answer to slightly improve on Chris32’s answer.
    There is a better way to get the value of the Telegram Chat ID as I am using it in a personal project.

    I will go end to end to explain my approach.
    I have mapped some files to some specific intents. In my intent-mapper.js file, I have mapped Default Welcome Intent to welcome.js file as prescribed in the documentation for the Dialogflow Fufillment library for NodeJS (Please note that the library is deprecated and not being updated, personally I am using a fork of the repo that I have worked on personally).

    const intentMap = new Map();
    intentMap.set('Default Welcome Intent', welcome);
    .
    .
    

    Then, in welcome.js,

    const globalParameters = {
        'name': 'global-parameters',
        'lifespan': 9999, 
        'parameters': {}
    };
    globalParameters.parameters.telegramChatId = agent.originalRequest?.payload?.data?.chat?.id || -1;
    .
    .
    agent.setContext(globalParameters); 
    

    The telegramChatId variable in the global parameters context will save the value for the chat ID which can be passed to a helper function to send a message. In order to to retrieve the value from the global parameters, the code snippet is this.

    const globalParameters = agent.getContext('global-parameters');
    const telegramChatId  = globalParameters.parameters.telegramChatId;
    

    Then the Telegram message helper function is largely the same as in Chris32’s answer. The message can be any string and chatId can be passed as an argument to the following helper function.

    const TelegramBot = require('node-telegram-bot-api');
    const { telegramBotToken } = process.env.TELEGRAM_BOT_TOKEN;
    const bot = new TelegramBot(telegramBotToken, { polling: false });
    const sendTelegramTextMessage = (message, chatId) => {
        try {
            bot.sendMessage(chatId, message, {parse_mode: 'html'});
        } catch (err) {
            console.log('Something went wrong when trying to send a Telegram notification', err);//remove console.log()
        }
    };
    

    The reason I have put this all in a context since in my use case I am sending push notifications via Telegram once the user asks for it (this happens later in the conversation flow), so I have implemented it this way. The main point to note is that the agent object already has the detectIntentRequest variable saved inside it which in turn has the value we need as a part of its payload. Here’s a snippet of the same.

    Please note I have removed many lines from my code for brevity, but in a nutshell, the chat ID can be accessed from

    agent.originalRequest?.payload?.data?.chat?.id 
    

    And the value for the telegram bot token is a secret value which can be saved in an environment variable or Secrets Manager. Please note my answer explains a better way to retrieve the chat ID without needing to refer directly to the request object since Dialogflow Fulfillment library already caches the value in the body for us. The other stuff for receiving and sending images is explained in the main answer.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search