Building SocialBot : Automating Social Media Content Creation with a Telegram Bot and OpenAI API

As a developer and content creator, I’m always exploring new ways to leverage technology to make life easier. One of the most time-consuming tasks in today’s digital world is creating content for social media. Whether it’s drafting a tweet or crafting a LinkedIn post, the need for engaging and consistent content can feel overwhelming.

But what if we could automate that process? Enter SocialBot — a Telegram bot that generates social media posts for you, using the power of OpenAI’s language models. In this blog, I’ll walk you through how to build this bot, explain the code, and suggest a file structure to keep everything clean and organized.

Why SocialBot?

Imagine you have a day filled with meetings, personal projects, or even just random thoughts that pop into your head. SocialBot can help you transform those moments into well-crafted social media posts tailored for platforms like LinkedIn, Facebook, and Twitter.

By the end of this blog, you’ll have a working Telegram bot that can:

  • Accept daily events or thoughts from you.

  • Generate social media posts based on those events using the OpenAI API.

  • Respond to commands directly within the Telegram app.

Setting Up the Project

Let’s dive into the process of setting up and coding SocialBot. We’ll start by creating a well-structured project that’s easy to maintain and scale.

Before we start coding, we need to create a Telegram bot. Telegram makes this process simple with BotFather. Follow these steps:

  1. Open Telegram and search for “BotFather”.

  2. Start a chat with BotFather by clicking on its name in the search results.

  3. Type /start to see a list of commands.

  4. Create a new bot by typing /newbot.

  5. Follow the instructions to choose a name and username for your bot. The username must end in “bot” (e.g., SocialBot).

  6. Once your bot is created, BotFather will provide you with a bot token — a long string of characters. This token is essential for interacting with the Telegram API and will be used in your project.

Here’s an example of what the token looks like:

123456789:ABCdefGHIjklMNOpqrSTUvwxYZ

Important: Keep your token safe and secure. Do not share it publicly or commit it to a public repository.

Step 1: Project Initialization

First, create a new directory for your project and initialize it as a Node.js project:

mkdir socialbot
cd socialbot
npm init -y

Install the necessary dependencies:

npm install telegraf mongoose dotenv axios

Here’s a brief overview of the packages we’re using:

  • Telegraf: A Telegram bot framework for Node.js.

  • Mongoose: A MongoDB object modeling tool for Node.js.

  • dotenv: For managing environment variables.

  • axios: A promise-based HTTP client for making API requests.

Step 2: Organizing the Project Structure

A well-organized file structure is crucial for managing a project, especially as it grows. Here’s how I’ve structured SocialBot:

socialbot/
│
├── src/
│   ├── config/
│   │   └── db.js
│   ├── models/
│   │   ├── Event.js
│   │   └── User.js
│   ├── bot/
│   │   ├── commands.js
│   │   └── events.js
│   └── utils/
│       └── openai.js
│
├── .env
├── server.js
├── package.json
└── README.md
  • src/config/db.js: Handles the MongoDB connection.

  • src/models/User.js and src/models/Event.js: Define the MongoDB schemas for storing user data and events.

  • src/bot/commands.js: Contains the bot’s command handlers.

  • src/bot/events.js: Manages event-related bot interactions.

  • src/utils/openai.js: Encapsulates the OpenAI API calls.

    Step 3: Writing the Code

    MongoDB Connection (db.js)

    In src/config/db.js, we set up the MongoDB connection:

      import mongoose from 'mongoose';
    
      const connectDB = async () => {
          try {
              await mongoose.connect(process.env.MONGO_URI, {
                  useNewUrlParser: true,
                  useUnifiedTopology: true,
              });
              console.log('Connected to MongoDB');
          } catch (err) {
              console.error('Database connection error:', err);
              process.exit(1);
          }
      };
    
      export default connectDB;
    

    This code connects to the MongoDB database using the URI from the environment variables.

User and Event Models

In src/models/User.js, we define the schema for storing user information:

import mongoose from 'mongoose';

const userSchema = new mongoose.Schema({
    tgId: { type: String, required: true, unique: true },
    firstName: { type: String },
    lastName: { type: String },
    username: { type: String },
    isBot: { type: Boolean },
    promptTokens: { type: Number, default: 0 },
    completionTokens: { type: Number, default: 0 },
});

export default mongoose.model('User', userSchema);

In src/models/Event.js, we define the schema for storing events:

import mongoose from 'mongoose';

const eventSchema = new mongoose.Schema({
    tgId: { type: String, required: true },
    text: { type: String, required: true },
    createdAt: { type: Date, default: Date.now },
});

export default mongoose.model('Event', eventSchema);

OpenAI Utility (openai.js)

In src/utils/openai.js, we encapsulate the OpenAI API call logic:

import axios from 'axios';

const generatePost = async (events) => {
    const response = await axios.post(
        'https://api.openai.com/v1/chat/completions',
        {
            model: 'gpt-4',
            messages: [
                {
                    role: 'system',
                    content: 'Act as a senior copywriter...',
                },
                {
                    role: 'user',
                    content: `Here are the events: ${events.map(e => e.text).join(', ')}. Create posts...`,
                },
            ],
        },
        {
            headers: {
                Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
            },
        }
    );

    return response.data.choices[0].message.content;
};

export default generatePost;

This utility function will be called whenever we need to generate a post using the OpenAI API.

Bot Commands and Event Handling

In src/bot/commands.js, we handle the /start and /generate commands:

import UserModel from '../models/User.js';
import EventModel from '../models/Event.js';
import generatePost from '../utils/openai.js';

export const startCommand = async (ctx) => {
    const { id, first_name } = ctx.update.message.from;

    try {
        await UserModel.findOneAndUpdate(
            { tgId: id },
            {
                $setOnInsert: {
                    firstName: first_name,
                    username: ctx.update.message.from.username,
                },
            },
            { upsert: true, new: true }
        );
        await ctx.reply(`Hi ${first_name}, welcome to SocialBot!`);
    } catch (err) {
        console.error('Error during /start:', err);
        await ctx.reply('An error occurred. Please try again later.');
    }
};

export const generateCommand = async (ctx) => {
    const { id } = ctx.update.message.from;

    const events = await EventModel.find({
        tgId: id,
        createdAt: {
            $gte: new Date().setHours(0, 0, 0, 0),
            $lt: new Date().setHours(23, 59, 59, 999),
        },
    });

    if (events.length === 0) {
        await ctx.reply('No events found for today.');
        return;
    }

    try {
        const postContent = await generatePost(events);
        await ctx.reply(postContent);
    } catch (err) {
        console.error('Error generating post:', err);
        await ctx.reply('Failed to generate post. Please try again later.');
    }
};

In src/bot/events.js, we manage how the bot responds to user messages:

import EventModel from '../models/Event.js';

export const handleTextMessage = async (ctx) => {
    const { id } = ctx.update.message.from;
    const message = ctx.update.message.text;

    try {
        await EventModel.create({ text: message, tgId: id });
        await ctx.reply('Your event has been noted. Use /generate to create posts.');
    } catch (err) {
        console.error('Error saving event:', err);
        await ctx.reply('An error occurred. Please try again later.');
    }
};

Main Server File (server.js)

Finally, in server.js, we bring everything together:

import { Telegraf } from 'telegraf';
import dotenv from 'dotenv';
import connectDB from './src/config/db.js';
import { startCommand, generateCommand } from './src/bot/commands.js';
import { handleTextMessage } from './src/bot/events.js';

dotenv.config();
connectDB();

const bot = new Telegraf(process.env.BOT_TOKEN);

bot.start(startCommand);
bot.command('generate', generateCommand);
bot.on('text', handleTextMessage);

bot.launch();

process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));

Step 4: Environment Configuration

Create a .env file in the project root with your configuration:

MONGO_URI=mongodb://localhost/socialbot
BOT_TOKEN=your-telegram-bot-token
OPENAI_API_KEY=your-openai-api-key

Step 5: Deploying SocialBot

To keep SocialBot running 24/7, you’ll need to deploy it on a server. Services like Heroku, Vercel, or AWS are great options for hosting. You can also use services like ngrok to expose your local server to the web for testing.

Alternatives to OpenAI API

While OpenAI’s API is a powerful tool for text generation, here are a few alternatives you can explore:

  • Hugging Face’s Transformers: An open-source library with a wide range of pre-trained models.

  • GPT-J by EleutherAI: A strong open-source alternative to GPT-3.

  • Cohere API: Offers language generation with additional customization options.

Conclusion

Building SocialBot has been an exciting journey, blending the power of AI with the convenience of a Telegram bot. Whether you’re a developer seeking to experiment with bot-building or a content creator looking to simplify your process, SocialBot is a project worth exploring.

I hope this guide has been informative and inspiring. Feel free to tweak and expand on this project — perhaps adding features like scheduled posts or integrating other social media APIs.

If you enjoyed this blog, stay tuned for more content where I explore the intersection of technology, AI, and productivity!


This blog reflects my passion for development and continuous learning. Let’s keep building and exploring new possibilities together!

I have also learned all this online from Blog posts, youtube videos and online courses.


By Achutendra Singh Full Stack Developer | Passionate about tech, history, culture, and more. Connect with me to discuss the latest in web development and beyond!

/

0
Subscribe to my newsletter

Read articles from Achutendra Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Achutendra Singh
Achutendra Singh

Full Stack Developer with a passion for continuous learning. Connect with me to explore the fascinating world of technology and beyond!