Last time I gave you a relay that can push to your own phone, in One App, Two Websites: Instant Ham Radio Reminders. This time I am adding a second Worker that watches satellite passes for you, and pushes you before a good one. Everything below is done in a browser, with your own hands. No terminal and no token are needed for the deployment itself. The terminal only appears once, for testing, and I will show you how to open it and what a good result looks like.
First, what moves and what does not. Only Cloudflare moves. You create one new Worker there, paste one bundled code file, fill in your own secrets, and turn on a cron trigger. Bark does not move: it is already on your phone from the last article, with the same device key — do not reinstall it, do not change the key. GitHub does not move either: you already have an account from the last article, you do not need a new repository and you do not need a token for this deployment. GitHub is only where the code file lives for you to copy. That is it.
The code for this article is not pasted below. The bundled file is about 56KB, and pasting it into a blog article would make the article unreadable. Copy it from the repository instead, from the one place it lives: https://github.com/bg7bag/bark-relay-worker , in the sat-worker folder, file dist-index.js. Open that file, click Raw, copy everything. That file is the same file I run. I will tell you how to check you copied it all, below.
One thing first, because satellite status changes and this article cannot change with it. The status notes below were checked on 2026-11-03. They are only good up to that date. Before you go out, check again yourself. Where to check is at the end of this article, with the addresses. If a satellite is reported silent that day, skip it. Do not call blind on an old list.
Before you touch Cloudflare: write these four things down on paper
Do this first. If you go looking for these values in the middle of the deployment, you will lose track of which page you are on.
- Your relay Worker’s address. In Cloudflare, open Workers & Pages, click your relay Worker from the last article — the one named bark-relay-worker — and copy the address shown in its Workers.dev section. That is your relay address. Do not add /push at the end. The satellite code adds it itself.
- Your relay passphrase. This is the shared passphrase you set for the relay Worker in the last article. Cloudflare encrypts secrets, so you cannot view it again. If you forgot it, stop here and reset it first: on the relay Worker, go to Settings, Variables and Secrets, edit RELAY_SECRET to a new passphrase, and deploy. Then, when you set up the satellite Worker below, use that same new passphrase on both Workers. If the two do not match, the relay will refuse the push with 401.
- Your latitude and longitude, in decimal form. Open Heavens-Above, set your own location, and copy the latitude and longitude numbers it shows for that location. Use decimal numbers only, for example latitude 51.50 and longitude -0.12 is only a format example, not your location. Do not type a city name, and do not use degrees, minutes and seconds. If you enter the wrong format, the Worker will find no passes and you will not know why.
- Your Bark device key, already saved from the last article. You do not need it again for this deployment, but keep it where you can find it. You will need it if you ever reset the relay.
If you cannot fill in items 1 to 3, do not start the deployment yet. Get those three first.
Stage 1: get one pass working by hand, before you automate anything
I teach it in two stages on purpose. Stage 1 is manual, and it works even if Stage 2 fails. Stage 2 is automatic, and it is only worth doing after Stage 1 works.
- Find a pass. Open Heavens-Above, or the AMSAT pass prediction page, or N2YO, set your own location, pick one satellite, and write down one pass: rise time, highest elevation, direction. Only pick a pass at 30 degrees or more for this first try. I will explain why in the next section.
- Send yourself a push by hand, 15 minutes before that pass rises, using the relay from the last article. Open a terminal — on a Mac, open Spotlight and type Terminal; on Windows, open Start and type Terminal — paste the relay test command from the last article, with the pass details in the title and body, and press Enter. A good result is a line back that says delivered:true, and a push on your phone at the same time. If you get anything else, stop and fix the relay first. Do not move on to Stage 2 with a broken relay.
- Go outside and work that pass by hand, using the steps in the “Work the pass” section below. Log it.
If Stage 1 works, you have already done a satellite pass reminder, by hand. Stage 2 only removes the need to sit and watch the clock.
Stage 2: deploy the automatic Worker on Cloudflare, step by step
1. Create the Worker
Sign in to dash.cloudflare.com with the account from the last article. If you have more than one account under your login, make sure you are in your own personal account before going on. Cloudflare changes its dashboard layout from time to time. If a button below has moved, use the search box at the top of the dashboard and search for Workers, KV, or Cron. Do not guess at a different button with a similar name.
On the left, find Workers & Pages, click Create, choose Worker, name it bark-sat-worker, and click Deploy. You now have an empty Worker. That is normal.
2. Paste the bundled code, not the source file alone
This step is where most people get stuck, so read it before you paste anything. The satellite code on GitHub has two forms. The source file, src/index.js, starts with a line that imports satellite.js. The Cloudflare dashboard editor cannot install that library for you, so pasting the source file alone will fail. The bundled file already contains satellite.js inside it. That is the file you paste.
- Open https://github.com/bg7bag/bark-relay-worker , open the sat-worker folder, open dist-index.js, click Raw, and copy everything. Select all, copy, and do not close that page until you have pasted it in the next step.
- Back on Cloudflare, open your new bark-sat-worker, click Edit code, delete everything in the editor, paste the bundled code you just copied, and click Deploy.
Check you pasted it all: in the editor, search for the text “bark-sat-worker is running”. If you find it, you pasted most of the file. Then go to the very end of the editor. You should see a license comment about satellite.js at the end. If the end stops in the middle of the code, you copied only part of the Raw page. Go back, reload the Raw page, copy again, and paste again.
Check at this point: the Worker deploys with no error. If it reports an import error, you pasted the source file, not the bundled file. Go back and copy dist-index.js instead.
3. Turn on the workers.dev route
Go back to the Worker’s page and look at the Workers.dev section. If it shows your Worker’s address, the route is already on. If opening the address shows “There is nothing here yet”, turn on this script’s workers.dev route separately. Open the address in a browser.
Check at this point: the page shows “bark-sat-worker is running.”
4. Fill in your own secrets and variables
On the Worker’s page, click Settings, find “Variables and Secrets”, and add these, one by one, using the values you wrote down before you started. Nothing here is mine, and nothing here goes in the code.
- SAT_LAT — your own latitude, in decimal form, from your paper list. Tick “Secret”.
- SAT_LON — your own longitude, in decimal form. Tick “Secret”.
- RELAY_SECRET — the same shared passphrase as your relay Worker. Tick “Secret”. It must match, or the relay will refuse the push with 401.
- RELAY_URL — your relay Worker’s address, as a plain variable, not a secret. Paste the relay address only, without /push at the end. The code adds /push itself.
Check at this point: SAT_LAT, SAT_LON and RELAY_SECRET show as encrypted, and RELAY_URL shows as a plain variable with your relay address.
5. Bind a KV namespace, so the same pass does not push twice
This step is recommended, not optional in my experience. Without it, the Worker only remembers what it already pushed inside one running copy, and Cloudflare runs many copies. The same pass can push twice.
- In Cloudflare, find KV. In the current dashboard it is under Storage, or search for KV in the dashboard search box. Create a namespace. Name it bark-sat-dedup.
- Back on your bark-sat-worker, go to Settings, find “KV Namespace Bindings”, click Add binding, set the variable name to DEDUP, and select the bark-sat-dedup namespace you just created.
If you skip this step, the Worker still works, but expect an occasional duplicate push. That is a known limit of the in-memory version, not a fault in your setup.
6. Turn on the cron trigger, or nothing will ever push
This is the second place people get stuck. Creating the Worker does not run it on a schedule. Without a trigger, it only runs when you open its address.
On your bark-sat-worker page, find Triggers, then Cron Triggers, and click Add Cron Trigger. Enter */5 * * * * — every five minutes — and save.
What this does: every five minutes, Cloudflare runs the Worker. The Worker fetches fresh orbit data from CelesTrak, works out the passes for your location, and pushes any pass whose rise is 10 to 20 minutes away and whose highest elevation is 30 degrees or more. A pass at 70 degrees or more gets “好圈” in front of its title. That is all the automation there is. No other website, no other app, moves.
7. Test it before you trust it
Open a terminal the same way as in Stage 1. Run the list check with your own satellite Worker address and your own passphrase in place of the placeholders, then press Enter:
curl https://your-sat-worker-address/list -H "X-Relay-Secret: your-shared-passphrase"
A good result is a list of upcoming passes in the next 24 hours, with satellite, rise time, highest elevation, and the push title and body for each one. If the list is empty, read the troubleshooting table below before you decide anything is broken.
Then run the dry-run check the same way, with /check instead of /list. It lists only what would be pushed right now, and pushes nothing. If no pass is 10 to 20 minutes away, the list will be empty. That is normal, not an error.
Then wait for a real pass window. When a pass is 10 to 20 minutes away, your phone should receive a push. The push will be a title only: the satellite’s Chinese name, then the rise time, for example “沙特卫星 1C 11-03 13:06”, with “好圈” in front if it is 70 degrees or more. There is no body. The real window is 10 to 20 minutes before the rise, so do not be surprised if it arrives at 18 minutes before. The highest elevation, the duration, the mode, and the uplink and downlink are not in the push; they are still in the /list output, which is read on screen.
Check at this point, all five must pass: the Worker address opens and shows it is running; the secrets and the relay address are set; the KV binding is in place; the cron trigger is listed as every five minutes; and /list returns passes for your location. Only then trust the push.
If it does not work: check in this order, do not guess
- Deploy reports an import error. You pasted src/index.js, not dist-index.js. Go back to the repository, open sat-worker/dist-index.js, click Raw, copy again, paste again.
- Push test returns 401 Unauthorized. Your RELAY_SECRET on the satellite Worker does not match the relay Worker. Reset it to the same passphrase on both Workers, deploy both again, and test again. You cannot view an old secret, only replace it.
- /list returns an empty list, with no error. First, check your paper list: is SAT_LAT and SAT_LON in decimal form, not a city name? Second, check whether there is actually a 30-degree pass in the next 24 hours for your location. An empty list can simply mean no good pass today. Third, check the Worker logs in Cloudflare for a TLE fetch error. If the log shows a fetch error, wait an hour and try /list again. Do not change your coordinates to force a result.
- /list returns an error about TLE. CelesTrak did not return orbit data for that satellite at that moment. Wait and try again. Do not edit the code to work around it.
- No push arrives, even though /list shows a pass. First, check Triggers: is */5 * * * * listed? If not, you forgot Step 6. Second, check the Worker logs for that pass window: did the cron run, and did it try to push? Third, check RELAY_URL: does it point at your relay Worker, without /push at the end? Fourth, send a manual push through the relay, as in Stage 1. If the manual push arrives and the automatic one does not, the problem is in the satellite Worker, not in Bark or the relay.
- The same push arrives twice. You skipped the KV binding, or the binding name is not DEDUP. Go back to Step 5 and bind bark-sat-dedup as DEDUP. If the binding is already in place and it still arrives twice, you are running the bundle from before 2026-11-03: its dedup key carried milliseconds that changed between runs, so it never matched. Copy sat-worker/dist-index.js from the repository again and paste it in, as in Step 2.
- The address opens as “There is nothing here yet”. The workers.dev route is off. Turn it on for this Worker, as in Step 3.
Pick a pass — my rule is 30 degrees first
For your first time, only pick a pass whose highest elevation is 30 degrees or more. That is the rule I use myself. A 30-degree pass is high enough that the signal is strong, the pass stays usable for several minutes, and a hill or a roof at the horizon does not kill it at the start. A low pass, 10 or 15 degrees, is a hard first try: the signal is weak, it fades in and out, and you spend the whole pass fighting the horizon.
At 60 degrees and above, contacts get better. The satellite is closer to overhead, the signal is stronger, and the fading is less. That is why I look for 60-degree passes when I want a good contact. The trade is that a high pass moves fast across the sky, so your antenna has to keep moving with it. Be ready for that. A 60 to 80 degree pass is, in my experience, the best working range: strong, and still trackable by hand.
One more number: start listening at about 10 degrees up, even on a 30-degree pass. Do not wait until the satellite is at its highest. By then half the pass is gone. Be outside, radio on, antenna pointed, at least five minutes before it rises.
To find a pass in the first place, I use a pass prediction site, not a guess. Open Heavens-Above, or the AMSAT pass prediction page, or N2YO, and set your own location first. Your location is yours — set it on the site, do not post it anywhere, and do not put it in this article’s comments. Then pick one satellite, and read the pass list: the time it rises, the time it sets, the highest elevation, and the direction it comes from and goes to. A pass is about ten minutes long. That is all the time you get.
Check the satellite’s status today
A pass prediction only tells you geometry. It does not tell you whether the repeater is on. That is a separate check, on the AMSAT status page, on the day of the pass. The four satellites in the code are below, with how each one turns on or goes quiet. There is no fixed clock time for any of them — on and off are decided by conditions, which is exactly why you check.
- International Space Station, ISS, NORAD 25544, FM. Uplink 145.990 MHz, tone 67.0 Hz. Downlink 437.800 MHz. The repeater is not always on. Crew work, school contacts, and other modes can take priority. Check the status page, and listen first. If you hear nothing, do not assume it is your radio.
- SaudiSat 1C, SO-50, NORAD 27607, FM. Uplink 145.850 MHz. Downlink 436.795 MHz. To wake it, send a 74.4 Hz tone for about two seconds first, then use 67.0 Hz for the contact. It goes quiet again after a period with no use, so wake it, then listen, then call.
- Fox-1B, AO-91, NORAD 43017, FM. Uplink 435.250 MHz, tone 67.0 Hz. Downlink 145.960 MHz. It goes silent in Earth’s shadow. If your pass is in eclipse, expect silence, no matter how high the pass is. On the uplink, step the frequency for Doppler as the pass goes on; the downlink stays put.
- DOSAAF-85, RS-44, NORAD 44909, SSB, linear, inverted. Uplink 145.935 to 145.995 MHz, lower sideband. Downlink 435.610 to 435.670 MHz, upper sideband. Beacon 435.605 MHz, CW. Listen for the beacon first. If you cannot hear the beacon, do not call blind. Because it is inverted, you tune the uplink and downlink in opposite directions for Doppler.
If you want to add another satellite later, do not add it from an old list. First find its mode and frequencies, then check the status page for recent reports, then check whether it has a timer, an eclipse rule, or a crew rule like the ones above. Then listen for one full pass without transmitting. Only after that, add it to the satellite list in the code, in the same format as the four above, and deploy the Worker again with the same steps. If editing the bundled code feels like too much, stick with the four for now. That is a fair choice, not a failure.
The reminder itself — keep it short, or Siri will not read it
The push from this Worker is title-only, on purpose: the satellite’s Chinese name, then the rise time, for example “沙特卫星 1C 11-03 13:06”, with “好圈” in front if it is 70 degrees or more. There is no body at all, because on my phone a push with a body is not spoken aloud. Do not lengthen the title in the code, and do not add a body. I wrote about this in the first article: from the speaker, Siri reads only the beginning, about ten to twenty words. The full message still shows on the screen, but what you hear without looking is just the start. If your title is long, what you hear is “Bark” and a few words, and you miss which satellite it is and when it rises. Then you have to stop what you are doing and look at the screen, which is exactly what the reminder was supposed to save you from.
A good title, as sent by this Worker: “沙特卫星 1C 11-03 13:06”, or with “好圈” in front for a 70-degree pass.
A bad title, if you ever change it: “SO-50 will rise at 14:32 from the northwest, maximum elevation 62 degrees, uplink 145.850, downlink 436.795, please get ready” — Siri will cut that off, and you will hear only the beginning.
As a backup, I also set a phone alarm with the same short label for a pass I really do not want to miss. The automatic push is the main reminder. The alarm is there in case the push has not arrived yet when I check /list myself before the pass.
Work the pass by hand
Program the frequencies before you go outside. Do not program them during the pass. Be outside five minutes before it rises, antenna pointed where the prediction says it will come from, radio on the downlink, volume up.
Listen first. If you hear the satellite, or other stations, or the beacon on RS-44, then call. If you hear nothing, do not call into silence for ten minutes. Call short: your callsign, once, then listen. A long call wastes the pass and steps on other stations. Tune for Doppler as you go: on FM, step the uplink; on RS-44, tune both sides in opposite directions. When the satellite sets, stop. Log the contact right away, while you remember it: time, satellite, station worked, signal report.
Where to check after today
Status notes in this article were checked on 2026-11-03. After that date, check these yourself, before every pass:
- AMSAT satellite status: https://status.amsat.org — this is the new address from 2026-11-04. The old address, https://www.amsat.org/status/ , redirects to it. If the old address stops working, use the new one first.
- AMSAT pass predictions: https://www.amsat.org/track/
- Heavens-Above, pass predictions for amateur satellites: https://www.heavens-above.com/ — set your own location first, then open the amateur radio satellites list.
- N2YO, satellite tracking and pass predictions: https://www.n2yo.com/
- CelesTrak, orbit data (TLE) behind most pass predictions: https://celestrak.org/
That is how I do it by hand, in a browser, with only Cloudflare moving. A good pass worked by hand teaches you what automation should do.
In this series: iPhone Low-Power Instant Ham Radio Reminders — why I use Bark. One App, Two Websites: Instant Ham Radio Reminders — register on GitHub and Cloudflare by hand and deploy the relay this article uses. Bark + SDR: Never Miss a Satellite Recording Again — a script watches the recording folder and pushes when a satellite recording finishes. Bark + SDR: Get Pushed Only When the Repeater Talks — a push only when squelch opens on one repeater frequency. Bark + SDR: A Push When the Band Opens to You — a push when WSJT-X decodes what you want. Bark + SDR: Know When Recording Finishes or Fails — a push when a long recording finishes, when disk space runs low, or when the expected file never appears.
卫星过顶提醒,亲手做:先从 30 度起
上一篇我给了你一个能往自己手机上推消息的转发器,见一个 App,两个网站:业余无线电即时提醒。这篇再加一个 Worker,帮你盯着卫星过顶,好的圈提前推你。这篇里部署本身不用终端、不用 Token,全是在浏览器里亲手做。终端只在测试时出现一次,我会告诉你怎么打开、好的结果长什么样。
先把一件事说清楚:到底动谁、不动谁。只动 Cloudflare 一个网站。在那儿新建一个 Worker,粘贴一个打包好的代码文件,填上你自己的密钥,再开一个定时触发器。Bark 不动:上一篇里已经装在你手机上了,设备密钥还是原来那个——别重装,别换密钥。GitHub 也不动:你已经有上一篇那个账号了,这次部署不用新建仓库、不用 Token。GitHub 只是代码文件放着给你抄的地方。就这么多。
这篇的代码我没有贴在下面。打包文件大概 56KB,贴进文章里文章就没法看了。从仓库里抄,抄的就是我跑的那个文件:https://github.com/bg7bag/bark-relay-worker ,进 sat-worker 文件夹,打开 dist-index.js,点 Raw,全选复制。下面我会告诉你怎么核对抄全了没有。
先说一件事,因为卫星的状态会变,这篇文章变不了。下面这些状态是我在 2026-11-03 核实过的,只到那一天为止。出门之前,你自己再去核实一遍。去哪儿核实,文章最后给了地址。那天如果报的是静默,就跳过那一圈,别照着旧表盲目呼叫。
动手之前:先把这四样东西写在纸上
先做这一步。部署到一半再去找这些值,你就分不清自己在哪个页面上了。
- 你的转发器地址。进 Cloudflare,打开 Workers & Pages,点上一篇那个转发器 Worker——名字叫 bark-relay-worker——抄它 Workers.dev 那一栏显示的地址。这就是你的转发器地址。后面不要加 /push,卫星代码自己会加。
- 你的转发器口令。就是上一篇转发器里设的那个共享口令。Cloudflare 里的密钥加密后是看不到明文的,忘了就只能重设:先停在这里,去转发器 Worker 的 Settings、Variables and Secrets 里,把 RELAY_SECRET 改成一个新口令,部署。然后下面卫星 Worker 里也用同一个新口令。两边不一样,转发器会回 401 拒绝推送。
- 你的经纬度,十进制小数。打开 Heavens-Above,把你自己的位置设好,抄它显示的纬度和经度数字。只用十进制小数,比如纬度 51.50、经度 -0.12 只是格式例子,不是你的位置。别填城市名,别用度分秒格式。格式填错,Worker 就找不到圈,你还不知道为什么。
- 你的 Bark 设备密钥,上一篇里已经存好了。这次部署用不着它,但先知道它放在哪。以后要是重设转发器,还会用到它。
这四样里前三样凑不齐,先别开始部署。先凑齐。
第一段:先亲手成功一次,再上自动
我故意分两段教。第一段是手动的,自动那段失败了,第一段也已经成功了。第二段是自动的,只有第一段通了,才值得做。
- 找一圈。打开 Heavens-Above,或者 AMSAT 的过顶预报页,或者 N2YO,把你自己的位置设好,选一颗星,记下一圈:升起时间、最高仰角、方向。第一次只挑 30 度以上的圈,为什么下一节再说。
- 在这一圈升起前 15 分钟,亲手给自己推一条,用上一篇的转发器。打开终端——Mac 上打开聚焦搜索输入 Terminal,Windows 上打开开始菜单输入 Terminal——粘贴上一篇的转发器测试命令,把这一圈的信息填进标题和正文,按回车。好的结果是返回一行 delivered:true,同时手机收到推送。返回别的,先把转发器修好,别带着坏的转发器进第二段。
- 出门亲手通联这一圈,步骤在下面“亲手通联这一圈”那一节。记日志。
第一段通了,卫星过顶提醒你已经亲手做成了。第二段只是省掉你坐在那儿看表的工夫。
第二段:在 Cloudflare 上部署自动 Worker,一步一步来
1. 新建 Worker
用上一篇那个账号登录 dash.cloudflare.com。名下要是有多个账号,先认准自己的个人账号再往下走。Cloudflare 的后台版式时不时会变,下面某个按钮要是挪了位置,就用后台顶部的搜索框搜 Workers、KV 或者 Cron,别猜一个名字像的别的按钮。
左边找到 Workers & Pages,点 Create,选 Worker,名字填 bark-sat-worker,点 Deploy。现在你有了一个空 Worker,这很正常。
2. 粘贴打包好的代码,别粘源文件
这一步最容易卡住,粘之前先读完。GitHub 上的卫星代码有两种样子。源文件 src/index.js 开头有一行引入 satellite.js,Cloudflare 网页编辑器装不了这个库,粘源文件会直接报错。打包好的文件已经把 satellite.js 打进去了,粘那个才行。
- 打开 https://github.com/bg7bag/bark-relay-worker ,进 sat-worker 文件夹,打开 dist-index.js,点 Raw,全选复制。复制完先别关这个页面,等下一步粘贴完再说。
- 回到 Cloudflare,打开新建的 bark-sat-worker,点 Edit code,把编辑器里原来的代码全删掉,把刚复制的打包代码粘贴进去,点 Deploy。
核对抄全了没有:在编辑器里搜“bark-sat-worker is running”这句话,搜得到,说明大头都粘进来了。再翻到编辑器最底下,应该看到一段关于 satellite.js 的许可说明。如果底下断在代码中间,说明 Raw 页面只抄了一部分。回去重新加载 Raw 页面,再抄一次,再粘一次。
到这一步,你应该看到:部署没有报错。如果报引入错误,说明你粘的是源文件,不是打包文件。回去复制 dist-index.js。
3. 打开 workers.dev 路由
回到 Worker 的页面,看 Workers.dev 这一栏。如果显示的是你的 Worker 地址,说明路由已经开了;如果打开地址显示的是“There is nothing here yet”,就去把这个脚本的 workers.dev 路由单独打开。在浏览器里打开你的 Worker 地址。
到这一步,你应该看到:页面上显示“bark-sat-worker is running.”
4. 填你自己的密钥和变量
在 Worker 的页面点 Settings,找到“运行时变量和密钥”,一个一个加,用动手之前写在纸上的值。这些东西都不在代码里。
- SAT_LAT——你自己的纬度,十进制小数,按纸上的填。勾上“密钥”。
- SAT_LON——你自己的经度,十进制小数。勾上“密钥”。
- RELAY_SECRET——跟转发器 Worker 一样的共享口令。勾上“密钥”。填得不一样,转发器会回 401 拒绝推送。
- RELAY_URL——你的转发器地址,是普通变量,不是密钥。只粘转发器地址,后面不要加 /push,代码自己会加。
到这一步,你应该看到:SAT_LAT、SAT_LON、RELAY_SECRET 都显示已加密,RELAY_URL 是普通变量,显示你的转发器地址。
5. 绑一个 KV,免得同一圈推两次
这一步我建议别省。不绑的话,Worker 只在某一个运行副本里记得自己推过什么,Cloudflare 跑着很多个副本,同一圈就可能推两次。
- 在 Cloudflare 里找 KV。现在的后台里它在 Storage 下面,或者用后台顶部的搜索框搜 KV。新建一个命名空间,名字叫 bark-sat-dedup。
- 回到 bark-sat-worker,点 Settings,找到“KV 命名空间绑定”,点添加绑定,变量名填 DEDUP,选刚建的 bark-sat-dedup。
不绑也能跑,就是偶尔会收到重复推送。这是内存版已知的局限,不是你配错了。
6. 开定时触发器,不然永远不会推
这是第二个容易卡住的地方。建了 Worker 不等于它会定时跑。没有触发器,它只在你打开地址的时候才跑,推送永远不会来。
在 bark-sat-worker 页面找到 Triggers,再找到 Cron Triggers,点添加定时触发器。填 */5 * * * *,就是每五分钟一次,保存。
这样做的效果是:每五分钟 Cloudflare 就跑一次这个 Worker。Worker 去 CelesTrak 拿最新的轨道数据,算你那个位置的过顶,把升起时间在 10 到 20 分钟以内、最高仰角 30 度以上的圈推给你。70 度以上的圈,标题前面会加“好圈”。自动化就这么多,别的网站、别的 App 都不用动。
7. 先测一遍,再信它
跟第一段一样打开终端,跑列表检查,把地址和口令换成你自己的,再按回车:
curl https://你的卫星Worker地址/list -H "X-Relay-Secret: 你的共享口令"
好的结果是未来 24 小时的过顶表,每一圈有星、升起时间、最高仰角,还有要推的标题和正文。表要是空的,先看下面故障表,别急着断定坏了。
同样办法把 /list 换成 /check 跑一遍。这是只看不推的演练,只列出现在就该推的圈,不真的推。如果没有圈在 10 到 20 分钟以内,表是空的,这很正常,不是错。
等一个真的过顶窗口。圈升起前 10 到 20 分钟,手机应该收到推送。推送只有标题:星的中文名,再加起的时间,比如“沙特卫星 1C 11-03 13:06”,70 度以上的圈前面还有“好圈”。根本没有正文。实际窗口是升起前 10 到 20 分钟,所以 18 分钟前收到也别惊讶,不算推错了。最高仰角、时长、模式、上行和下行不在推送里,这些还在 /list 的输出里,看屏幕的时候能查到。
到这一步,五条全对才算信得过:Worker 地址打开显示在跑;密钥和转发器地址都填了;KV 绑上了;定时触发器列着每五分钟一次;/list 能返回你那个位置的过顶表。五条全对,再信推送。
出问题了,按这个顺序查,别猜
- 部署报引入错误。 你粘的是 src/index.js,不是 dist-index.js。回去打开仓库 sat-worker/dist-index.js,点 Raw,再抄一次,再粘一次。
- 推送测试回 401。 卫星 Worker 上的 RELAY_SECRET 跟转发器 Worker 的不一样。两边改成同一个口令,都重新部署,再测一次。旧密钥看不到,只能换。
- /list 返回空表,没有报错。 先查纸上的值:SAT_LAT、SAT_LON 是不是十进制小数,是不是填了城市名。再查未来 24 小时里你那个位置到底有没有 30 度以上的圈,空表可能就是今天没有好圈。最后去 Cloudflare 里看 Worker 日志有没有取 TLE 报错,有报错就等一小时再跑 /list。别为了出结果去改经纬度。
- /list 报取 TLE 的错。 那会儿 CelesTrak 没给那颗星的轨道数据。等一等再试,别去改代码绕过去。
- 到了窗口还是没推送。 先查 Triggers:*/5 * * * * 在不在,没有就是第六步忘了。再查 Worker 日志,那个窗口定时任务跑了没有、有没有尝试推送。再查 RELAY_URL:是不是指着你的转发器 Worker,后面有没有多加 /push。最后按第一段的办法亲手推一条,亲手推到了、自动推不到,问题就在卫星 Worker,不在 Bark 和转发器。
- 同一条推送来了两次。 KV 没绑,或者绑定变量名不是 DEDUP。回去第五步,把 bark-sat-dedup 绑成 DEDUP。绑已经在、还是推两次,那就是用的 2026-11-03 之前的旧包:旧包的去重键带毫秒,每次跑都不一样,永远对不上。按第二步的办法,从仓库里重新抄 sat-worker/dist-index.js,再粘一次。
- 地址打开是“There is nothing here yet”。 workers.dev 路由没开。按第三步,给这个 Worker 单独打开路由。
挑一圈——我的规矩是先从 30 度起
第一次,只挑最高仰角 30 度以上的圈。这是我自己的规矩。30 度的圈够高,信号够强,能用的时间有几分钟,地平线上的山或者屋顶也不会一开始就把它挡死。10 度、15 度的低圈,第一次很难:信号弱,时有时无,整圈都在跟地平线较劲。
60 度以上的圈,通联会更好。星离头顶更近,信号更强,衰落也小。所以我想好好通联的时候,就找 60 度以上的圈。代价是高圈在天上走得快,天线得一直跟着转,得有准备。在我看来,60 度到 80 度是最好用的范围:够强,亲手还能跟得上。
还有一个数字:哪怕是 30 度的圈,也要从大约 10 度仰角就开始听,别等到星升到最高才动手。等到最高,半圈已经过去了。升起前至少五分钟就到外面,电台开着,天线指着预报说的来向。
找圈我不靠猜,我去查过顶预报。打开 Heavens-Above,或者 AMSAT 的过顶预报页,或者 N2YO,先把你自己的位置设好。位置是你自己的,在网站上设好就行,别发到任何地方,也别写在这篇文章的评论里。然后选一颗星,看过顶表:几点升起,几点落下,最高仰角多少,从哪个方向来、往哪个方向去。一圈过顶大概就十分钟,就这么点时间。
当天查一下这颗星的状态
过顶预报只告诉你几何位置,不告诉你转发器开没开。这是另外一查,过顶当天去 AMSAT 的状态页查。代码里的四颗星是下面这四颗,每颗是怎么开、怎么静默的。它们都没有固定的开关钟点,开和关都是看条件的,所以才要查。
- 国际空间站,ISS,NORAD 25544,FM。 上行 145.990 MHz,亚音 67.0 Hz。下行 437.800 MHz。转发器不是一直开的。机组工作、学校通联、别的模式都可能优先。先查状态页,再先听。如果什么都听不到,别先怪自己的电台。
- 沙特卫星 1C,SO-50,NORAD 27607,FM。 上行 145.850 MHz。下行 436.795 MHz。开机要先发 74.4 Hz 的亚音大约两秒,再用 67.0 Hz 通联。一段时间没人用,它又会静默下去,所以先开机,再听,再呼叫。
- 狐狸 1B,AO-91,NORAD 43017,FM。 上行 435.250 MHz,亚音 67.0 Hz。下行 145.960 MHz。进地影它就静默。如果这一圈正好在地影里,不管仰角多高,都别指望有信号。上行要跟着多普勒分段调,下行不动。
- 俄罗斯 DOSAAF-85,RS-44,NORAD 44909,SSB,线性,倒置。 上行 145.935 到 145.995 MHz,下边带。下行 435.610 到 435.670 MHz,上边带。信标 435.605 MHz,CW。先听信标,听不到信标就别盲目呼叫。因为是倒置的,多普勒要上下行反着调。
以后想加别的星,别照旧表加。先找到它的模式和频率,再去状态页看最近有没有人报过,再查它有没有定时关机、地影规则、机组规则,像上面这几颗一样。然后完整听一圈,不发射。听完再加到代码里的星表里,格式跟上面四颗一样,再按同样的步骤重新部署一次 Worker。觉得改打包代码太麻烦,就先用这四颗,这不丢人,不算失败。
提醒本身——标题要短,不然 Siri 不读
这个 Worker 推的只有标题,本来就是短的:星的中文名,再加起的时间,比如“沙特卫星 1C 11-03 13:06”,70 度以上的圈前面还有“好圈”。根本没有正文,因为有正文我这手机就不播报。别去代码里把标题改长,也别加正文。我在第一篇里写过:扬声器读出来的只有开头,大概十来个字到二十个字。完整消息还在屏幕上,但不看屏幕能听到的只有开头那一点。标题要是长了,你听到的就是“Bark”加上几个字,到底是哪颗星、几点过顶,全错过了。然后你就得停下手里的事去看屏幕,提醒本来就是为了省这一步。
Worker 发出来的好标题就是这样:“沙特卫星 1C 11-03 13:06”,70 度的圈前面加“好圈”。
如果你自己改标题,改成下面这样就坏了:“SO-50 将于 14:32 从西北升起,最高仰角 62 度,上行 145.850,下行 436.795,请做好准备”——Siri 读到一半就断了,你只听到开头。
备用办法是再设一个手机闹钟,标签就用同样短的一句话,专门留给实在不想错过的圈。自动推送是主力,闹钟是防着推送还没来的时候,你自己先查 /list 的那一手。
亲手通联这一圈
频率出门前就编好,别在过顶的时候现编。升起前五分钟就到外面,天线指着预报说的来向,电台放在下行频率上,音量开大。
先听。听到星了,听到别的台了,RS-44 听到信标了,再呼叫。什么都听不到,就别对着静默喊十分钟。呼叫要短:呼号喊一次,然后听。长呼叫浪费这一圈,也压住别的台。多普勒要跟着调:FM 调上行,RS-44 上下行反着调。星落下去了就停。马上记日志,趁还记得:时间、星、通联到的台、信号报告。
今天之后,去哪儿核实
这篇里的状态是我在 2026-11-03 核实的。过了那一天,每次出门前你自己去查:
- AMSAT 卫星状态:https://status.amsat.org ——这是 2026-11-04 起的新地址。旧地址 https://www.amsat.org/status/ 会转到新地址。旧地址要是不通了,先用新地址。
- AMSAT 过顶预报:https://www.amsat.org/track/
- Heavens-Above,业余卫星过顶预报:https://www.heavens-above.com/ ——先把你自己的位置设好,再打开业余卫星表。
- N2YO,卫星跟踪和过顶预报:https://www.n2yo.com/
- CelesTrak,轨道数据(TLE),多数过顶预报的源头:https://celestrak.org/
亲手做就是这样,在浏览器里,只动 Cloudflare。一圈亲手通联好了,才知道自动化该干什么。
这个系列里还有:我为什么用 Bark 来做提醒——我为什么用 Bark。一个 App,两个网站:业余无线电即时提醒——手动注册 GitHub 和 Cloudflare,部署这篇用的转发器。第 4 篇:卫星录音——录音文件夹里文件一完就推送。第 5 篇:中继守听——静噪打开才推送。第 6 篇:波段打开——WSJT-X 解出你要的台才推送。第 7 篇:录音状态——录音完成、磁盘不足、预计文件没出现都推送。