{"id":35253063,"url":"https://github.com/leowilkin/pact-id","last_synced_at":"2026-04-01T19:18:33.852Z","repository":{"id":288816840,"uuid":"969067275","full_name":"leowilkin/pact-id","owner":"leowilkin","description":"🌐📞 Cheap, international dialling with PaCT ID \u0026 Twilio","archived":false,"fork":false,"pushed_at":"2025-10-05T15:20:52.000Z","size":60,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-11T15:50:06.153Z","etag":null,"topics":["phone","phonenumber","twilio","twiml"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leowilkin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-19T10:05:06.000Z","updated_at":"2025-10-05T15:20:55.000Z","dependencies_parsed_at":"2025-04-21T08:49:07.627Z","dependency_job_id":null,"html_url":"https://github.com/leowilkin/pact-id","commit_stats":null,"previous_names":["leowilkin/pactid"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/leowilkin/pact-id","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leowilkin%2Fpact-id","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leowilkin%2Fpact-id/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leowilkin%2Fpact-id/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leowilkin%2Fpact-id/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leowilkin","download_url":"https://codeload.github.com/leowilkin/pact-id/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leowilkin%2Fpact-id/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31036730,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-27T07:48:52.080Z","status":"ssl_error","status_checked_at":"2026-03-27T07:48:19.562Z","response_time":164,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["phone","phonenumber","twilio","twiml"],"created_at":"2025-12-30T07:06:09.824Z","updated_at":"2026-04-01T19:18:33.841Z","avatar_url":"https://github.com/leowilkin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📞 PaCT ID - Personal and Cheap International Dialling\n\n**PaCT ID** is a Twilio-powered local-to-international calling bridge. It allows you to call and receive calls across borders using local Twilio numbers while preserving caller IDs — with a handy PWA frontend for mobile dialing.\n\n![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/leowilkin/pact-id/python.yml)\n![GitHub commits since latest release](https://img.shields.io/github/commits-since/leowilkin/pact-id/latest)\n![Website](https://img.shields.io/website?url=https%3A%2F%2Ftwilio.alphabetise.xyz%2Fstatus)\n![GitHub Repo stars](https://img.shields.io/github/stars/leowilkin/pact-id)\n\n\n\n\u003cdetails\u003e\n\n\u003csummary\u003eWhat does PaCT ID stand for?\u003c/summary\u003e\n\n**P**robably **C**heaper **T**o **I**nternationally **D**ial\n\nIronically, it's actually much cheaper. From 'research', Leo found that it costs like £0.025 per minute going from a UK -\u003e US, and his data plan is like £0.13 a minute, so _big savings_.\n\nSomeone's probably going to reverse engineer my server and find all my numbers, so it'll end out to be more expensive when they f me with twilio bills.\n\u003c/details\u003e\n\n---\n\n## 🌍 How It Works\n\n- **Inbound Calls from Others**  \n  - If someone calls your **US Twilio number**, it's forwarded to your **UK personal number** via your **UK Twilio number**, showing the original US caller ID.\n  - If someone calls your **UK Twilio number**, it's forwarded to your **US personal number** via your **US Twilio number**, showing the original UK caller ID.\n\n- **Outbound Calls from You**  \n  - If _you_ call the **UK Twilio number**, you're prompted to enter a number (e.g., a US number) [then press hash], and it connects using your **US Twilio number**, showing your personal UK number as caller ID.\n  - If _you_ call the **US Twilio number**, you're prompted to enter a number (e.g., a UK number) [then press hash], and it connects using your **UK Twilio number**, showing your personal US number as caller ID.\n\n---\n\n## ✅ Features\n\n- Local-to-international call bridging\n- Full preservation of original caller IDs\n- Web-based PWA dialler interface - [hosted seperately](https://github.com/leowilkin/pactid-pwa)\n- Secure Cloudflare Tunnel support\n- Call normalisation (07 and +44 formats accepted)\n- Configurable via environment variables\n\n---\n\n## 🛠 Prerequisites\n\n- A Linux VPS (e.g. Ubuntu 22.04 or later)\n- Python 3.8+ installed\n- `cloudflared` for secure tunnel to Twilio\n- Two Twilio phone numbers (1x US, 1x UK)\n- Your personal phone number(s) in both regions\n\n---\n\n## 🔧 Installation\n\n### 1. Clone the Repo\n\n```bash\ngit clone https://github.com/leowilkin/pactid.git\ncd pactid\n```\n\n### 2. Set up virtual environment\n\n```bash\npython3 -m venv venv\nsource venv/bin/activate\npip install -r requirements.txt\n```\n\n### 3. Create a `.env` file\n\n```bash\nnano .env\n```\n\n[See example](https://github.com/leowilkin/pactid/blob/main/.env.example)\n\n### 4. Create systemd Service\n\n```bash\nsudo nano /etc/systemd/system/twilio.service\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eIn development\u003c/summary\u003e\n\n\nIn that crispy new file, paste [this weird ass code](https://github.com/leowilkin/pactid/blob/main/systemd/python.ini) in, and apparently it makes it run automatically which is pretty neat.\n\nThen hit it with an enable \u0026 start\n\n```bash\nsudo systemctl daemon-reexec\nsudo systemctl daemon-reload\nsudo systemctl enable twilio\nsudo systemctl start twilio\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eIn production\u003c/summary\u003e\n\n\n\"Apparently\" using Flask servers in prod isn't such a good idea, so when you're running it for realsies, use [this systemd file](https://github.com/leowilkin/pactid/blob/main/systemd/gunicorn.ini)\n\nThen hit it with an refresh\n\n```bash\nsudo systemctl daemon-reexec\nsudo systemctl daemon-reload\nsudo systemctl refresh twilio\n```\n\u003c/details\u003e\n\n\n\n## 🌐 Configure Cloudflare Tunnel\n\n1. Go to [dash.cloudflare.com](dash.cloudflare.com), and enter Zero Trust\n2. Networks \u003e Tunnels\n3. Create a new tunnel \u003e Cloudflared \u003e name your tunnel\n4. Debian \u003e 64-bit\n5. Copy and paste the install code into your terminal\n6. Once completed, copy and paste the activation code into your terminal\n7. Next \u003e configure public hostname as twilio.yourdomain.com, and save\n\n## 🔁 Configure Twilio Webhooks\n\n\u003e [!IMPORTANT]  \n\u003e You cannot be on a trial account, as you have to have two numbers.\n\nSet the following webhook URLs for your Twilio numbers:\n\n| Number Type |               Webhook URL              |\n|-------------|:--------------------------------------:|\n| US Number   | https://twilio.yourdomain.com/voice_us |\n| UK Number   | https://twilio.yourdomain.com/voice_uk |\n\nThese should be set as the Voice \u0026 Fax \u003e A Call Comes In handler (Webhook + TwiML).\n\n## � Deploying on Coolify\n\nCoolify just needs a Dockerfile, so point it at this repo and set the build context to the repository root. The image exposes port `8080`; Coolify will map it automatically as long as you set the **Internal Port** to `8080` in the service settings.\n\n### Environment variables\n\nPopulate the following environment variables in Coolify (or use secrets) so the container can talk to Twilio:\n\n- `US_TWILIO_NUMBER`\n- `UK_TWILIO_NUMBER`\n- `PERSONAL_US`\n- `PERSONAL_UK`\n- `TWILIO_ACCOUNT_SID`\n- `TWILIO_AUTH_TOKEN`\n\nOptionally, override the defaults:\n\n- `PORT` – defaults to `8080`\n- `GUNICORN_WORKERS` – defaults to `2`\n- `GUNICORN_THREADS` – defaults to `4`\n\nOnce the container is running, Twilio can reach it at `https://\u003cyour-domain\u003e/voice_us`, `https://\u003cyour-domain\u003e/voice_uk`, and `https://\u003cyour-domain\u003e/text`.\n\n## �📱 Using the PWA Dialler\n\nHead on over to [leowilkin/pactid-pwa](github.com/leowilkin/pactid-pwa) to find out more - currently a WIP.\n\n## View Logs\n\nTo view the access logs for the service, on your terminal do:\n\n```bash\njournalctl -u twilio.service -f\n```\n\n## Testing\n\n### Outbound\n\nhttps://thetestcall.blogspot.com/\n\n### Inbound\n\nFind a friend!\n\n## Extra Features!\n\nSet your MOTD to a custom Linux PaCT ID message so you can remember all those commands easily!\n\nSimply:\n\n```bash\nnano /etc/motd\n```\n\nand paste:\n\n```bash\n👋 You're logged into $(hostname), your PaCT ID server!\n\nUseful commands:\n\n- systemctl stop twilio\n- systemctl start twilio \u0026\u0026 journalctl -u twilio.service -f\n- systemctl status twilio\n- nano /opt/twilio/bridge.py\n\nFully reload \u0026 restart?\n\n1. sudo systemctl daemon-reexec\n2. sudo systemctl daemon-reload\n3. sudo systemctl restart twilio.service\n\n\nWant to re-enable the default MOTD? https://gist.github.com/leowilkin/483f3968681a78f4f8eabf11228209f0\n```\n\nsimples 🤌\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleowilkin%2Fpact-id","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleowilkin%2Fpact-id","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleowilkin%2Fpact-id/lists"}