A production-ready Telegram bot for the Foursquare Placemaker community that enables users to contribute to the global places database directly from their mobile devices. Now with one-command setup using ngrok (no custom domain or SSL required) and support for 100+ LLM providers via litellm.
"Placemakers are the dedicated, passionate members of our global open source community who contribute to our shared understanding of places around the world. Welcome to our community of builders, developers, and local experts who help others unlock the best experiences, anywhere in the world."
This bot makes the process of adding and updating place data more accessible to the Placemaker community, allowing contributions from anywhere using Telegram.
The Mini App within the Telegram bot is served by Fused:
- Foursquare Location Data UDF
- Location-Based Entry: Start by sharing your current location to add nearby places
- Guided Place Submission: Step-by-step process for complete place information
- Category Selection: Choose from common place categories or enter custom ones
- Rich Place Attributes: Add detailed information including:
- Contact information (phone, website, email)
- Operating hours
- Chain status
- Amenities (WiFi, parking, outdoor seating, etc.)
- Photo Uploads: Submit up to 3 photos of the place (storefront, interior, features)
- Foursquare Map Integration: Explore existing Foursquare location data through an embedded web app
- Conversational Interface: User-friendly keyboard buttons and inline options
- Auto-ngrok + Auto-webhook: Tunnel and webhook are configured automatically by Docker
- Universal LLM Support: Use any of 100+ LLM providers via litellm (OpenAI, Anthropic, Azure, Bedrock, Vertex AI, Cohere, HuggingFace, and more)
- Docker & Docker Compose
- A Telegram Bot Token from @BotFather
- An API key for your preferred LLM provider (OpenAI, Anthropic, etc.)
- Foursquare API Key
- ngrok account (to obtain
NGROK_AUTHTOKEN)
- Clone the repo and navigate:
git clone https://github.com/yourusername/foursquare-placemaker-bot.git
cd foursquare-placemaker-bot- Configure environment variables:
cp example-env .env
nano .envFill in your configuration:
# Core API Keys
TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here
FOURSQUARE_API_KEY=your_foursquare_api_key_here
# Webhook Configuration
NGROK_AUTHTOKEN=your_ngrok_authtoken
WEBAPP_PORT=8000
USE_WEBHOOK=true
WEBHOOK_PATH=/webhook
AUTO_SET_WEBHOOK=true
# LLM Configuration (using litellm)
# Default: OpenAI GPT-4.1-nano
LLM_CHAT_MODEL=gpt-4.1-nano
LLM_PARSE_MODEL=gpt-4.1-nano
OPENAI_API_KEY=your_openai_api_key_here
# To use a different provider (e.g., Anthropic Claude):
# LLM_CHAT_MODEL=claude-3-5-sonnet-20241022
# LLM_PARSE_MODEL=claude-3-5-sonnet-20241022
# ANTHROPIC_API_KEY=your_anthropic_api_key_here
# See example-env for more provider examples (Azure, Bedrock, Vertex AI, etc.)
# Optional: Structured logging
APP_ENV=dev
SERVICE_NAME=conversation_bot
LOG_LEVEL=INFO
LOG_TO_FILE=false
LOG_FILE=logs/placemaker_bot.log
LOG_ROTATE_WHEN=midnight
LOG_ROTATE_INTERVAL=1
LOG_BACKUP_COUNT=7- Deploy with one command:
chmod +x deploy.sh
./deploy.shThe script will:
- Start the bot and an ngrok tunnel (Docker Compose)
- Discover the public
https://*.ngrok.ioURL - Automatically register your Telegram webhook to
https://<ngrok>/webhook
To view the ngrok dashboard: http://localhost:4040
You can also run without webhooks using polling:
- Set in
.env:
USE_WEBHOOK=false- Start containers (ngrok service is optional in this mode):
docker-compose up -d --buildThe bot will use long polling; ngrok/webhook is not required.
| Variable | Description | Default | Required |
|---|---|---|---|
TELEGRAM_BOT_TOKEN |
Your Telegram bot token from BotFather | - | ✅ |
FOURSQUARE_API_KEY |
Your Foursquare API key | - | ✅ |
NGROK_AUTHTOKEN |
ngrok auth token (enables public https URL) | - | ✅ (webhook mode) |
WEBAPP_PORT |
Port for the Flask web server | 8000 |
❌ |
USE_WEBHOOK |
Use webhook mode (true) or polling (false) | true |
❌ |
WEBHOOK_PATH |
Path for webhook endpoint | /webhook |
❌ |
AUTO_SET_WEBHOOK |
Auto-discover ngrok URL and set webhook | true |
❌ |
| LLM Configuration | (via litellm - supports 100+ providers) | ||
LLM_CHAT_MODEL |
Model name for chat (e.g., gpt-4.1-nano, claude-4-5-sonnet) |
gpt-4.1-nano |
❌ |
LLM_PARSE_MODEL |
Model name for structured outputs | gpt-4.1-nano |
❌ |
OPENAI_API_KEY |
OpenAI API key | - | ✅ (for OpenAI) |
ANTHROPIC_API_KEY |
Anthropic API key | - | ✅ (for Claude) |
AZURE_API_KEY |
Azure OpenAI API key | - | ✅ (for Azure) |
AWS_ACCESS_KEY_ID |
AWS access key | - | ✅ (for Bedrock) |
AWS_SECRET_ACCESS_KEY |
AWS secret key | - | ✅ (for Bedrock) |
AWS_REGION_NAME |
AWS region | us-east-1 |
❌ |
| See litellm docs for other providers | |||
| Logging | |||
APP_ENV |
Deployment environment name for logs | dev |
❌ |
SERVICE_NAME |
Service name added to logs | conversation_bot |
❌ |
LOG_LEVEL |
Log level (DEBUG, INFO, WARNING, ERROR) |
INFO |
❌ |
LOG_TO_FILE |
Enable file logging in addition to stdout | false |
❌ |
LOG_FILE |
File path for logs when LOG_TO_FILE=true |
logs/placemaker_bot.log |
❌ |
LOG_ROTATE_WHEN |
Rotation schedule for logs | midnight |
❌ |
LOG_ROTATE_INTERVAL |
Rotation interval (units depend on when) |
1 |
❌ |
LOG_BACKUP_COUNT |
Number of rotated files to keep | 7 |
❌ |
- Start a chat with your bot on Telegram
- Use the
/startcommand to begin - Share your location or explore the Foursquare data
- Follow the guided process to add a new place
- Confirm the submission
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a new branch (
git checkout -b feature/amazing-feature) - Make your changes
- Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
The bot implements a conversation flow with 12+ states (search and add flows).
# Build and run with Docker Compose
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down
# Rebuild and restart
docker-compose down && docker-compose up -d --build- Health endpoint (inside the tunnel):
GET /health - ngrok dashboard:
http://localhost:4040 - Logs are JSON-formatted to stdout by default; enable file logging with rotation via
LOG_TO_FILE=trueandLOG_FILE/rotation vars - Correlated requests: send
X-Request-IDheader to the webhook, or a UUID will be generated and included in responses - Check webhook status:
curl -X GET "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getWebhookInfo" - Reset webhook:
curl -X GET "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/deleteWebhook"
Made with ❤️ for the Placemaker community