devto 2026-07-23 원문 보기 ↗
If you trade — or just hold anything denominated in dollars — you already know the drill: FOMC decisions, CPI prints, and NFP releases move markets in seconds, and the only warning you get is whatever tab you happened to leave open. This post walks through a small n8n workflow that polls an economic calendar every morning and pushes high-impact USD events straight to Telegram. Total build time: about 15 minutes. Total cost: $0 on free tiers.
ForexFactory's calendar is the de facto standard for retail traders, but it's built for humans, not machines:
You could pay for a commercial economic calendar API — most start around $30–100/month for the tier that includes forecast/previous values. That's overkill if all you want is "ping me when something big is scheduled today."
Disclosure up front: I built the actor used in this tutorial, so take the recommendation with that in mind.
economic-calendar-pro is an Apify actor that scrapes the ForexFactory calendar and returns clean JSON. It handles the annoying parts (timezones, session cookies, markup drift) and gives you filters for currency and impact level, plus optional webhook alerts. Each event comes out looking like this:
{
"title": "CPI m/m",
"country": "USD",
"currency": "USD",
"impact": "High",
"date_utc": "2026-08-12T12:30:00Z",
"forecast": "0.2%",
"previous": "0.3%",
"actual": "",
"week": "this",
"source": "forexfactory"
}
Because it runs on Apify, you don't host anything — you call one HTTP endpoint and get dataset items back synchronously.
Schedule (weekdays 07:00)
→ HTTP Request (run actor, get this week's USD high-impact events)
→ Filter (belt-and-suspenders: impact == high, currency == USD)
→ Telegram (one message per event)
If there are no qualifying events, the filter drops everything and nothing gets sent. Quiet days stay quiet.
docker run -p 5678:5678 n8nio/n8n works fine)/newbot, save the token. Then message your bot once and get your chat ID from https://api.telegram.org/bot<TOKEN>/getUpdates
Add a Schedule Trigger node. Switch it to a cron expression:
0 7 * * 1-5
That's 07:00 every weekday, which comfortably beats the 08:30 ET releases (CPI, NFP) and afternoon FOMC statements. Set your instance timezone in n8n settings if you haven't — cron runs in instance time.
Add an HTTP Request node (typeVersion 4.x):
https://api.apify.com/v2/acts/ichigowa~economic-calendar-pro/run-sync-get-dataset-items
Authorization: Bearer YOUR_APIFY_TOKEN
Content-Type: application/json
{
"weeks": ["this"],
"currencies": ["USD"],
"impacts": ["High"]
}
The run-sync-get-dataset-items endpoint is the useful one here: it starts the actor, waits for it to finish, and returns the dataset items directly in the response body. No polling for run status, no second request to fetch results. Bump the node's timeout to ~120 seconds since a cold actor run can take 30–60s.
Hit Execute step. On a day with a CPI print you'll get something like:
[
{
"title": "CPI m/m",
"currency": "USD",
"impact": "High",
"date_utc": "2026-08-12T12:30:00Z",
"forecast": "0.2%",
"previous": "0.3%"
},
{
"title": "Core CPI m/m",
"currency": "USD",
"impact": "High",
"date_utc": "2026-08-12T12:30:00Z",
"forecast": "0.3%",
"previous": "0.3%"
}
]
n8n automatically splits the array into one item per event, which is exactly what we want downstream.
The actor already filtered server-side, but I like a Filter node here anyway — it protects you if you later widen the actor input to all currencies and forget this workflow feeds Telegram. Two conditions, combined with AND:
{{ $json.impact }} equals High
{{ $json.currency }} equals USD
Cheap insurance, zero cost.
Add a Telegram node, operation Send Message, using the bot credentials you created. Set the chat ID, enable Markdown parse mode, and use:
🔔 *{{ $json.title }}*
Currency: {{ $json.currency }} | Impact: {{ $json.impact }}
Time (UTC): {{ $json.date_utc }}
Forecast: {{ $json.forecast || 'n/a' }} | Previous: {{ $json.previous || 'n/a' }}
Because the filter outputs one item per event, you get one message per event. On FOMC day that's typically two or three messages (rate decision, statement, press conference); most days it's zero or one.
Execute the whole workflow once manually to sanity-check, then toggle it Active. Sample output in Telegram:
🔔 Consumer Price Index (CPI) m/m
Currency: USD | Impact: High
Time (UTC): 2026-08-12T12:30:00Z
Forecast: 0.2% | Previous: 0.3%
A few failure modes I've seen people hit with this exact setup:
Authorization: Bearer apify_api_xxx... — a common mistake is pasting the token without the Bearer prefix, or using the account password instead of the API token.run-sync-get-dataset-items caps waits at 300 seconds. If the actor run exceeds your HTTP node timeout, raise the node timeout first; the actor itself rarely takes over a minute.weeks parameter fetches whole calendar weeks ("this", "next", "last"), so an empty result usually means your filters were too tight — e.g. impacts: ["High"] on a week with only medium-impact USD events. Impact values are capitalized: High, Medium, Low, Holiday.-."currencies": ["USD", "EUR", "GBP"] and drop the filter's currency condition.{{ $json.date_utc }} within the next hour, so you get a nudge right before the release rather than at breakfast.fomc-cpi-telegram-alert.json in the apify-datafeeds repo.Questions or broken edge cases, drop a comment — the actor is actively maintained and issue reports genuinely help.