Repository navigation
feat(skills): move SendGrid sends to PostHog in every SDK language #459
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Silthus
wants to merge
272
commits into
main
Choose a base branch
from
feat/migrate-email-sendgrid
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+454
−1
Open
Changes from all commits
Commits
Show all changes
272 commits
Select commit
Hold shift + click to select a range
50b5f27
fix(skills): keep migrate-email's chain query uncached on its rerun
Silthus 8f77354
fix(skills): keep cc, bcc, headers, tags and attachments sites on Res…
Silthus d871b8e
Merge feat/migrate-email-resend into feat/migrate-email-resend-cutover
Silthus b9d785e
Drop local templates and parked fields from the cutover steps
Silthus 5edeb92
feat(migrate-email): set migratedFrom on the posthog-node client
Silthus 64cf8ef
fix(migrate-email): ask for the PostHog template ID before a template…
Silthus 85f6096
fix(migrate-email): check each PostHog template and its sender before…
Silthus a759ff4
fix(migrate-email): ask about a repeat import and test a send that na…
Silthus 5c8a34b
fix(migrate-email): ask for the PostHog template ID and sender before…
Silthus e053dab
Merge feat/migrate-email-resend into feat/migrate-email-resend-cutover
Silthus efa4933
fix(skills): read Dirent.path when parentPath is missing in the migra…
Silthus 5e40f2a
Merge feat/migrate-email-resend into feat/migrate-email-resend-cutover
Silthus 2c36853
fix(migrate-email): match account.md's template-content rule to Step 3
Silthus 8dcf6e7
fix(migrate-email): keep a site on Resend when its idempotency key do…
Silthus 07dbf3a
fix(migrate-email): name PostHog's idempotency key rule exactly
Silthus a1376c0
Merge feat/migrate-email-resend into feat/migrate-email-resend-cutover
Silthus 21f683e
fix(migrate-email): end Step 8's email check when the person declines…
Silthus d157859
docs(migrate-email): say where a send without distinctId lands
Silthus 5dcdd21
docs(migrate-email): test Step 8 on a site that passes distinctId
Silthus 78d36da
feat(skills): move SendGrid sends to PostHog in every SDK language
Silthus 0a95802
fix(migrate-email): close round-1 review findings on the SendGrid layer
Silthus 7d8c4f9
fix(migrate-email): let each provider's mapping decide which language…
Silthus 4c37a14
fix(migrate-email): close round-2 review findings on the SendGrid layer
Silthus 4fc8d41
docs(migrate-email): say why cc, bcc and attachments stay on Resend
Silthus 9664659
docs(migrate-email): name the real reason a field stays on Resend
Silthus 4e5a672
docs(migrate-email): give scheduled sends and topics a reason too
Silthus b9bf2df
Merge remote-tracking branch 'origin/feat/migrate-email-resend-cutove…
Silthus 29e44dc
docs(migrate-email): name why each kept field stays
Silthus 8d88206
fix(migrate-email): keep a site on Resend when its key length is unbo…
Silthus 3cdf4f2
fix(migrate-email): keep a network error raising where an HTTP-only c…
Silthus f6e3f17
Merge commit '8d88206613708da974fa19a267f8c10b151292ec' into feat/mig…
Silthus 5e26f02
fix(migrate-email): keep sends that ignored a refusal going, quote Li…
Silthus 2001fe3
fix(migrate-email): let a field that stood for an account setting be …
Silthus 42de36d
fix(migrate-email): name untracked sends in the added-field exception
Silthus 5863a99
fix(migrate-email): quote Resend fallbacks with single quotes only
Silthus c2fd123
fix(migrate-email): keep network_error on the Node error a sendgrid r…
Silthus 98ab5a8
fix(migrate-email): decide the send shapes real code showed
Silthus 8fce47a
fix(migrate-email): cover SendGrid's callback send and snake_case keys
Silthus 8ac97d7
Merge commit '5863a997198f52c9f98df1209e7b49383e404ce9' into feat/mig…
Silthus 7f9b671
fix(migrate-email): keep uncalled send functions as sites, name more …
Silthus fa45f3e
fix(migrate-email): leave a catch of every error as it is
Silthus f504ac6
fix(migrate-email): read config values once, and follow template IDs …
Silthus c7b8c10
fix(migrate-email): keep SendGrid template sites when tracking is off…
Silthus 9b390bd
fix(migrate-email): keep SendGrid sites with mixed or unknown account…
Silthus e1967c7
fix(migrate-email): a rate-limit branch skips PostHog's quota_limited
Silthus 32deb28
fix(migrate-email): keep PostHog's code next to the status in SendGri…
Silthus ee0a324
fix(migrate-email): one PostHog catch for several provider handlers, …
Silthus 6440c0f
fix(migrate-email): mirror a provider's suppression removal only when…
Silthus c48ef83
fix(migrate-email): a mirrored suppression removal also clears entrie…
Silthus 9baece4
fix(migrate-email): a template value counts as its declared type, and…
Silthus 127bc07
fix(migrate-email): a template value from unchecked input keeps the s…
Silthus eed16c6
fix(migrate-email): record the PostHog key as set only after a check …
Silthus 2d91936
fix(migrate-email): accept spaces around = in the key check
Silthus f37c460
Merge remote-tracking branch 'origin/feat/migrate-email-resend-cutove…
Silthus 074130e
fix(migrate-email): check the last assignment of the PostHog key
Silthus 9a0f03c
Merge remote-tracking branch 'origin/feat/migrate-email-resend-cutove…
Silthus 5c92245
docs(migrate-email): ask for the transactional_email:write scope
Silthus f5080a7
Merge remote-tracking branch 'origin/feat/migrate-email-resend' into …
Silthus eae6399
Merge #451 at f5080a7 (key scope transactional_email:write) into feat…
Silthus 254dbb9
fix(migrate-email): name the transactional email scope in the preflight
Silthus 464644f
Merge branch 'feat/migrate-email-resend' into feat/migrate-email-rese…
Silthus 4b0f257
feat(migrate-email): move Resend sends in every PostHog SDK's language
Silthus c4ed38c
fix(migrate-email): keep the app booting and check the whole project …
Silthus a658c75
fix(migrate-email): use the one Rust client the app's features build
Silthus cffc009
feat(migrate-email): carry posthog-sdks.md's rules into the rewrite f…
Silthus 6ab1cc2
Merge the migration lane's per-SDK rules into feat/migrate-email-all-…
Silthus f6b6af8
fix(migrate-email): check the merged SDK rules against the SDK heads
Silthus ef2c2e9
fix(migrate-email): give Elixir email its own instance when the app u…
Silthus fbd1e83
fix(migrate-email): never pass nil for Elixir's host or token
Silthus c53e0ad
Merge #472 at fbd1e83 (a rewrite file per SDK) into feat/migrate-emai…
Silthus 78d56ce
fix(migrate-email): fall back past a nil :posthog host in Elixir
Silthus 317a9cb
Merge #472 at 78d56ce (Elixir falls back past a nil host) into feat/m…
Silthus bb711c5
fix(migrate-email): list the error names once and state reply-to per SDK
Silthus 0f6d4f0
Merge #472 at bb711c5 (error names listed once, reply-to per SDK) int…
Silthus 5398fd9
fix(migrate-email): give email its own client behind a reverse proxy
Silthus 78a308c
Merge #472 at 5398fd9 (own email client behind a reverse proxy) into …
Silthus 6924d48
test(migrate-email): pin keeping the secret key off the proxied client
Silthus a8d0023
Merge #472 at 6924d48 (proxy test also checks the app client keeps no…
Silthus 4b15d2e
feat(migrate-email): bring stored templates into the code
Silthus 735bd63
feat(migrate-email): fill SendGrid substitutions in the code
Silthus 2ebcce0
feat(migrate-email): bring Resend templates into the code
Silthus 4ce6c2d
docs(migrate-email): record engagement events only when engagement ca…
Silthus 62d1116
fix(migrate-email): keep SendGrid sites with opens untracked instead …
Silthus 7761f99
fix(migrate-email): list no PostHog click event for SendGrid clicks, …
Silthus 0192a3d
fix(migrate-email): keep an app's PostHog key, and a Resend HTTP call…
Silthus d2e2848
Merge #451 at 0192a3d (keep an app's PostHog key, and an HTTP call's …
Silthus 5c996de
fix(migrate-email): keep email off a disabled client, and pass numeri…
Silthus 20036d6
Merge #451 at 5c996de (no email on a disabled client, numeric IDs as …
Silthus dddd616
fix(migrate-email): keep undeadlined HTTP sites on Resend and keep im…
Silthus 8234d71
fix(migrate-email): record the send's own sender, replace markers in …
Silthus e9953c0
fix(migrate-email): map Go's other Resend error checks and keep Outlo…
Silthus ecd0366
fix(migrate-email): render variables in Go's Outlook blocks and scope…
Silthus 7e5a468
fix(migrate-email): keep encoded URL values as they are in Go templates
Silthus e22fa6c
Merge branch 'main' into feat/migrate-email-resend
Silthus 7afab6e
Merge branch 'feat/migrate-email-resend-cutover' into feat/migrate-em…
Silthus ae88e6e
Merge branch 'feat/migrate-email-resend' into feat/migrate-email-rese…
Silthus 83f0f4a
Merge remote-tracking branch 'origin/feat/migrate-email-all-sdks' int…
Silthus 6b41f33
feat(migrate-email): move the shared step changes from the SendGrid l…
Silthus 7889e1f
Merge the core skill into feat/migrate-email-sendgrid, keeping only t…
Silthus a366b71
fix(migrate-email): list Resend webhook handlers, keep ignored argume…
Silthus f279e43
fix(migrate-email): keep provider content inert in code literals, and…
Silthus 8d1f697
Merge remote-tracking branch 'origin/feat/migrate-email-all-sdks' int…
Silthus e03b4a8
fix(migrate-email): keep the site's subject when a SendGrid version h…
Silthus 487262b
fix(skills): close the migrate-email preparation gaps the QA swarm found
Silthus 413dcd7
fix(migrate-email): SendGrid substitution tags, account mail settings…
Silthus 00b9aa3
fix(skills): tighten the migrate-email key check and template rules
Silthus 4211ef3
fix(migrate-email): SendGrid client wrappers and deadlines, account G…
Silthus bde5bb6
Merge branch 'feat/migrate-email-resend' into feat/migrate-email-rese…
Silthus 708f7f1
fix(migrate-email): keep each site's own HTTP deadline
Silthus 56158d1
fix(migrate-email): keep marketing sends on the provider
Silthus 8de2222
fix(migrate-email): a bare name inside a SendGrid each reads only the…
Silthus 04e7c84
fix(migrate-email): read the provider's report notes without the impo…
Silthus 7c388d1
Merge branch 'feat/migrate-email-resend' into feat/migrate-email-rese…
Silthus 02f46ca
fix(migrate-email): escape SendGrid subject values, one client per de…
Silthus 922ae71
fix(migrate-email): Handlebars subject escape, SendGrid secret rules,…
Silthus 0186ee2
fix(migrate-email): answer the round 1 review of the rewrite and veri…
Silthus 30f3873
fix(migrate-email): match baseline typecheck errors without their line
Silthus dc18f5d
fix(migrate-email): count each baseline typecheck error
Silthus c33bf45
Merge branch 'feat/migrate-email-resend-cutover' into feat/migrate-em…
Silthus a2994e9
fix(migrate-email): keep a named recipient on Resend
Silthus bde40bc
Merge remote-tracking branch 'origin/feat/migrate-email-resend' into …
Silthus e4221d8
Merge remote-tracking branch 'origin/feat/migrate-email-resend-cutove…
Silthus 82d6ebf
fix(migrate-email): settle deadlines, attribute quoting, and suppress…
Silthus 497d017
fix(migrate-email): keep a site on Resend when it needs a suppressed …
Silthus 69edcdd
fix(migrate-email): keep a Resend SDK send with an abortable signal o…
Silthus 22df812
Merge remote-tracking branch 'origin/feat/migrate-email-resend-cutove…
Silthus e36fd64
fix(migrate-email): own email clients, long deadlines, clicks and tem…
Silthus 08c9d15
test(migrate-email): drop the tests that match the skill's own wording
Silthus bb14da9
fix(migrate-email): blank .NET host, long .NET deadlines, shared temp…
Silthus eeeb620
fix(migrate-email): keep a Go site whose template fills CSS from a value
Silthus 64bb2a2
fix(migrate-email): count brought-in templates as code content, stop …
Silthus 8ead8e1
fix(migrate-email): keep enable_local_evaluation off the Python async…
Silthus 959a01b
chore: merge feat/migrate-email-all-sdks into feat/migrate-email-send…
Silthus 5786004
fix(migrate-email): converge SendGrid with the finished core
Silthus 0de8dee
fix(migrate-email): keep SendGrid's untracked links out of PostHog's …
Silthus cfc202d
fix(migrate-email): name the outcome of SendGrid's untracked clicks
Silthus 0158aef
fix(migrate-email): keep sites that branch on one kind of network fai…
Silthus f6978e7
fix(migrate-email): keep separate connect limits, require ext-curl fo…
Silthus ad23a92
fix(migrate-email): keep a Go request's transport limits
Silthus 7ccc0ee
fix(migrate-email): keep a Python whole-request limit on the provider
Silthus 64c26bd
fix(migrate-email): carry SendGrid's click notes through the plan
Silthus 6f12513
chore: merge feat/migrate-email-all-sdks into feat/migrate-email-send…
Silthus 558187b
fix(migrate-email): defer SendGrid's network and connect limits to St…
Silthus 4075cdd
fix(migrate-email): keep SendGrid's Ruby http_options timeouts under …
Silthus e4d0a4b
fix(migrate-email): move SendGrid Ruby sites whose timeouts match pos…
Silthus 3aac186
docs(migrate-email): name the outcome of SendGrid's Ruby split limits
Silthus eef1481
fix(migrate-email): settle untracked clicks, timeout kinds, and the m…
Silthus efb8451
fix(migrate-email): read Faraday's timeout by its adapter
Silthus f658354
fix(migrate-email): keep a site whose handler needs an event PostHog …
Silthus 22cfedc
Merge feat/migrate-email-all-sdks (f658354) into feat/migrate-email-s…
Silthus 106bf25
docs(migrate-email): point SendGrid clicks and timeouts at the core r…
Silthus a66e15b
fix(migrate-email): upgrade mocked send tests to the HTTP boundary
Silthus b0f6e45
docs(migrate-email): keep SendGrid's sensitive-template plan note and…
Silthus 18ab351
fix(migrate-email): fake fetch instead of keeping a send mock
Silthus ced460c
Merge commit '18ab3510a0b5cb457fab6a6b3d6079d8078bbc2d' into HEAD
Silthus e14c1fc
fix(migrate-email): keep a Ruby site with a partial Net::HTTP timeout
Silthus a943460
fix(migrate-email): note a must-be-sensitive template in its plan row
Silthus 45c5716
fix(migrate-email): keep network failures off Resend's 503 branch
Silthus d51979c
fix(migrate-email): allow a loopback app host in Go and .NET tests
Silthus 17c6ca1
feat(migrate-email): ask before adding an open pixel to untracked email
Silthus 3b34f45
Merge feat/migrate-email-all-sdks (17c6ca1) into feat/migrate-email-s…
Silthus 023fc06
docs(migrate-email): point SendGrid opens and webhook events at the c…
Silthus 3904508
docs(migrate-email): scope SendGrid's webhook stay to events a moved …
Silthus cff58f5
fix(migrate-email): route a network failure the way Resend's code did
Silthus 96e10a2
Merge commit 'cff58f516b33b2fe5eb3c0a5d2704f874f7c3d85' into HEAD
Silthus 6f7abcb
fix(migrate-email): test with a standard-library server, never a mock…
Silthus 8776c81
fix(migrate-email): ask about a test dependency only where one is needed
Silthus 63c3dfe
fix(migrate-email): ask before adding any test tool, in every language
Silthus 21e1d27
feat(migrate-email): re-import the suppression list weekly while site…
Silthus a65bb90
fix(migrate-email): check the project before a suppression re-import
Silthus b28e13b
fix(migrate-email): write the re-import's project check out in Step 5
Silthus b2dfe53
fix(migrate-email): confirm the production project before a re-import
Silthus 731b092
fix(migrate-email): read the project token with project-get
Silthus 8929f93
fix(migrate-email): switch the MCP back after a re-import
Silthus e5735c8
fix(migrate-email): name the production project in a by-hand re-import
Silthus 8b9757e
fix(migrate-email): let a re-import without the tool say so
Silthus 349a407
fix(migrate-email): let a re-import say why it got no list
Silthus 2df1f26
fix(migrate-email): read the project token with project-get
Silthus 090ac92
Merge #451 (feat/migrate-email-resend-cutover) into feat/migrate-emai…
Silthus da31113
Merge feat/migrate-email-all-sdks (090ac92) into feat/migrate-email-s…
Silthus 069a749
docs(migrate-email): point SendGrid suppression writes at the weekly …
Silthus d8dd2d4
fix(migrate-email): ask for re-imports only when the provider keeps a…
Silthus 94d44d3
fix(migrate-email): record a provider with no list before the tool check
Silthus 5553a6b
docs(migrate-email): keep SendGrid templates whose subject values Pos…
Silthus 2b8d0d6
fix(migrate-email): end a re-import early when the provider keeps no …
Silthus d4b7a13
docs(migrate-email): keep the throw of SendGrid's .NET retry handler …
Silthus 5e0607f
fix(migrate-email): keep sites a Resend webhook handler acts on, and …
Silthus fcef5e1
docs(migrate-email): keep .NET sites behind SendGrid's retry handler …
Silthus eeed7cb
fix(migrate-email): check every error in a rewritten line against its…
Silthus 5f5debd
fix(migrate-email): check for a provider without a suppression list b…
Silthus cb26a5f
Merge #451 (feat/migrate-email-resend-cutover) into feat/migrate-emai…
Silthus bd24f05
docs(migrate-email): key the .NET retry stay on the handler's retries…
Silthus 77b680b
fix(migrate-email): give Step 8 one rule for which typecheck errors a…
Silthus e7a7f3f
Merge #451 (feat/migrate-email-resend-cutover) into feat/migrate-emai…
Silthus a31db3b
docs(migrate-email): keep SendGrid retry failures and untracked plain…
Silthus 67b925a
docs(migrate-email): read a subuser's SendGrid account, escape plain …
Silthus e983e39
docs(migrate-email): key SendGrid account reads on the sending key, h…
Silthus 1d85155
fix(migrate-email): tie the kept Resend error names to posthog-node, …
Silthus 75fa8f8
docs(migrate-email): ask the SendGrid import filters in every run and…
Silthus 013a98e
Merge #450 (feat/migrate-email-resend) into feat/migrate-email-resend…
Silthus 19b1b90
fix(migrate-email): mark secret emails sensitive, check template keys…
Silthus c46ba49
docs(migrate-email): ask the SendGrid import filters with the report …
Silthus fdea2d3
fix(migrate-email): send sensitive only with rendered content, and on…
Silthus 8c03676
docs(migrate-email): ask the SendGrid import filters before taking en…
Silthus 2fe8430
fix(migrate-email): check the app's Node version and count removed er…
Silthus 6c45e23
Merge remote-tracking branch 'origin/feat/migrate-email-resend-cutove…
Silthus 4087e6c
fix(migrate-email): carry the key, sensitive and Node checks; count r…
Silthus d35d356
docs(migrate-email): apply the SendGrid import filters to entries add…
Silthus 26e5396
docs(migrate-email): give the by-hand SendGrid filters as rules in th…
Silthus 808f61d
fix(migrate-email): name each SDK's sensitive flag; list the moved keys
Silthus 3bec683
docs(migrate-email): write the SendGrid filter rules in every report,…
Silthus 5b55af4
docs(migrate-email): ask for the SendGrid Allow List's entries right …
Silthus fd58f93
fix(migrate-email): move the template keys to after cutover; edge reason
Silthus 1fc3ae4
docs(migrate-email): name missing Allow List entries in a SendGrid re…
Silthus f1ba031
fix(migrate-email): scope the runtime check to where each site runs
Silthus a0b01bc
fix(migrate-email): check every server that shares the SDK's manifest
Silthus 8f51a57
fix(migrate-email): keep every site on a manifest an unsupported serv…
Silthus 6b0083e
fix(migrate-email): count workspace and root lockfile installs in the…
Silthus ef71e1f
fix(migrate-email): keep a site whose HTTP client retries a request w…
Silthus 6fdfdf7
fix(migrate-email): count only a retry setup that covers the POST
Silthus 6d4801f
fix(migrate-email): name the retry setups as examples, not a full list
Silthus caff403
fix(migrate-email): read the retry setup's options before counting it
Silthus 7aad014
fix(migrate-email): count a requests adapter whose max_retries is a n…
Silthus a090b5b
chore: merge main after #450 landed
Silthus 66dc2b2
Merge branch 'feat/migrate-email-resend-cutover' into feat/migrate-em…
Silthus 6d3d8b0
fix(migrate-email): keep a site that reads Resend's response headers
Silthus 610e703
fix(migrate-email): name each SDK's retry delay in its rewrite file
Silthus d186900
fix(migrate-email): keep a send that turns Resend's plain-text part off
Silthus 088f35b
fix(migrate-email): cover react and run-time empty text, word the tem…
Silthus 3b204b7
fix(migrate-email): check the text-part rule in Step 3, count Go's em…
Silthus f3bb668
fix(migrate-email): ask whether a copied Resend template turns its pl…
Silthus 355df95
fix(migrate-email): offer the full-access key for the plain-text ques…
Silthus 74040e5
fix(migrate-email): note every template's plain text, offer the key o…
Silthus b99cea5
fix(migrate-email): sync suppression calls on the reasons PostHog stores
Silthus 9eb4180
fix(migrate-email): report suppression-list calls instead of syncing …
Silthus 1bcc53c
fix(migrate-email): say only hard bounces block a moved send
Silthus daf563e
fix(migrate-email): give the add item a check the app can make
Silthus d00e808
fix(migrate-email): ask in Step 3 which sites rely on a suppression add
Silthus 2fe5090
fix(migrate-email): ask about hand-added suppressions too
Silthus b006c9b
fix(migrate-email): keep the sites when nobody can say who relies on …
Silthus cd9e38a
fix(migrate-email): ask about the suppression list before the templat…
Silthus 4db6763
fix(migrate-email): list the suppression note in the plan file rules
Silthus 0a6ae00
fix(migrate-email): keep Rust sites on runtimes other than Tokio
Silthus f98eb3b
fix(migrate-email): require Tokio's timers for the Rust async client
Silthus 418cc5a
chore: merge main after #451 landed
Silthus 1b2752a
Merge remote-tracking branch 'origin/feat/migrate-email-all-sdks' int…
Silthus fb5e78a
chore: merge main after #472 landed
Silthus 8b33b8e
fix(migrate-email): follow #472's suppression steps for SendGrid
Silthus 3bba58e
refactor(migrate-email): slim sendgrid references to what the core do…
Silthus 225c098
refactor(migrate-email): slim sendgrid, restore the retry stays a cut…
Silthus File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
104
context/skills/migrate-email/references/sendgrid/account.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| # SendGrid account | ||
|
|
||
| What the migration needs from the person's SendGrid account. The agent never changes the account: it reads what the person exports or allows. | ||
|
|
||
| **EU subusers.** An app on an EU subuser sends through `api.eu.sendgrid.com`, or sets the client's data residency to `eu`, as `sdk-reference.md` says. For such an app, use `api.eu.sendgrid.com` in every request of this file instead of `api.sendgrid.com`. | ||
|
|
||
| **Subusers.** A send uses the suppression lists, templates, and settings of the account its API key belongs to: the parent account or one of its subusers. SendGrid's `on-behalf-of` header, which a client's subuser option such as `setImpersonateSubuser` in Node.js or `GetRequestSubuser` in Go sets, doesn't work with the Mail Send API, so it never sends for another account. Ask the person which account the app's sending key belongs to, make the read-only key below in that account, and switch to that account in SendGrid for every question and export of this file. When sites send with keys of different accounts, or a site picks its key at run time, such as per tenant, ask the person which account's lists Step 5 imports: the sites that send only with that account's key move, and every other site stays, with the reason `sends for another SendGrid account`. When the person can't say which account a key belongs to, its sites stay, with the reason `SendGrid account not checked`. | ||
|
|
||
| ## DNS records | ||
|
|
||
| A domain authenticated at SendGrid carries these records. Keep all of them until the cutover is done. The SendGrid dashboard shows the exact names under Settings, then Sender Authentication. | ||
|
|
||
| | Record | Name | What it does | | ||
| |---|---|---| | ||
| | `CNAME` | `em<digits>`, such as `em1234` | Return path for SendGrid's bounces, and its SPF | | ||
| | `CNAME` (DKIM) | `s1._domainkey`, `s2._domainkey` | Signs SendGrid's mail | | ||
| | `CNAME` | `url<digits>` and a second label of digits | Link branding, only when it is set up | | ||
| | `TXT` (DMARC) | `_dmarc` | Optional, shared by every provider on the domain | | ||
|
|
||
| - A domain set up without automated security has an `MX` and an SPF `TXT` record on `em<digits>`, and a DKIM `TXT` record at `m1._domainkey`, in place of the CNAMEs. | ||
| - PostHog's sender uses its own label for its MAIL FROM, `feedback` by default. Never give PostHog a label SendGrid uses. | ||
|
|
||
| ## Read-only key | ||
|
|
||
| The app's own SendGrid key is usually a key with the Mail Send permission only, and it can't read templates or suppressions. When the person chooses the API over the dashboard, ask them to create a restricted key in SendGrid (Settings, then API Keys) with read access to Template Engine and Suppressions only, store it in `SENDGRID_READ_API_KEY` in the git-ignored env file, and write it into the plan as Step 3's plan layout says. Its last use is the suppression import in Step 5. At the end of Step 5, on every way out of it, ask the person to delete the key in SendGrid and remove its variable from the env file, and note in the plan whether they did. The report reminds them when they didn't. Never print the key, and never write it into another file. | ||
|
|
||
| The steps call this key the full-access provider key. | ||
|
|
||
| ## Tracking | ||
|
|
||
| A send follows the account's open and click tracking for each of the two that its `trackingSettings` doesn't set. What PostHog does with opens and clicks is in `mapping.md` under "Open and click tracking". Ask the person once whether open tracking and click tracking are on in SendGrid (Settings, then Tracking), and whether click tracking also covers plain-text emails, and note the answers in the plan. | ||
|
|
||
| A site's emails had no open pixel when its `trackingSettings` sets `openTracking` with `enable: false`, or sets no `openTracking` while the account's open tracking is off. When it sets none and the person can't say whether open tracking is on, nobody can tell whether they had one. Step 3 says under "Opens the provider didn't track" what either means. | ||
|
|
||
| SendGrid didn't track a site's clicks when its `trackingSettings` sets `clickTracking` with `enable: false`, or sets no `clickTracking` while the account's click tracking is off. It didn't track the links in a plain-text part either, unless `clickTracking` sets `enableText: true`, or sets no `clickTracking` while the account's click tracking covers plain-text emails: a site whose plain-text part has a link SendGrid didn't track counts as one whose clicks SendGrid didn't track. When it sets no `clickTracking` and the person can't say whether click tracking is on, or whether it covers plain text for a site whose plain-text part has a link, nobody knows whether SendGrid tracked them. Step 3 says under "A template in PostHog" what either means for a site that moves to a template made in PostHog. | ||
|
|
||
| ## Mail settings | ||
|
|
||
| More account settings change every send that doesn't set them, and no send field of PostHog's does the same. In the same question, ask the person whether each one is on in SendGrid: | ||
|
|
||
| - **Subscription tracking** (Settings, then Tracking): SendGrid added an unsubscribe link to each email, or filled the tag that stands for it. When it is on, every site whose `trackingSettings` doesn't set `subscriptionTracking` stays, and the reason is `account subscription tracking on`. | ||
| - **Google Analytics** (Settings, then Tracking): SendGrid added `utm_` parameters to every link. When it is on, every site whose `trackingSettings` doesn't set `ganalytics` stays, and the reason is `account google analytics on`. | ||
| - **Legacy Email Template** (Settings, then Mail Settings, when the account shows it): SendGrid wrapped every email in that template. When it is on, every site stays, and the reason is `account legacy email template on`. | ||
| - **Footer** (Settings, then Mail Settings): SendGrid appended the footer's HTML to the HTML part and its text to the text part. When it is on, ask the person for the footer's HTML and text. Each site that moves in the code form appends them to its `html` and `text`, as SendGrid did, and the plan notes it. A site that moves to a template made in PostHog sends no `html` or `text`: ask the person to put the footer at the end of that template too, and note it in the plan. When the person can't give the footer, every site stays, and the reason is `account footer not copied`. | ||
|
|
||
| When the person can't say whether one of these is on, the sites it would change stay, and the reason is `account mail settings not checked`. Note the answers in the plan. | ||
|
|
||
| ## Template content | ||
|
|
||
| A site whose template moves needs the content of its active version: Step 3 checks it, and Step 7 brings it into the code, or the person makes a template in PostHog from it when they ask for one. The API returns the content. | ||
|
|
||
| **Copy from the dashboard.** In SendGrid: Email API, then Dynamic Templates, then the template, then its active version. Ask the person for the template's id, the version's subject, its HTML from the code editor, and its plain text when it has one. | ||
|
|
||
| **Read from the API.** `GET https://api.sendgrid.com/v3/templates/{template_id}` with `Authorization: Bearer $SENDGRID_READ_API_KEY`. The answer holds `id`, `name`, `generation` (`dynamic` or `legacy`), and `versions`, a list of `{ id, active, name, subject, html_content, plain_content }`. Take the version whose `active` is `1`. | ||
|
|
||
| Read the person's copies where they saved them. An API answer goes only into the temporary file Step 3 writes, which is deleted as `template-to-code.md` says. Never write the content into the plan or the report. | ||
|
|
||
| ## Suppression list | ||
|
|
||
| SendGrid keeps several suppression lists. It skips an address on any of them on every send. | ||
|
|
||
| **For Step 3's question.** SendGrid's suppression list, in Step 3's question about the sites that rely on it, is Bounces, Spam Reports, Invalid Emails, and Global Unsubscribes together. A person adds to them by hand under Suppressions, and the app with the calls `mapping.md` names under "Calls that change the suppression list", such as an unsubscribe handler that adds a global unsubscribe. A global unsubscribe stopped every send to the address at SendGrid, transactional ones too, unless the send bypassed it, and a moved send reaches it, as "Leave out the other lists" says: name Global Unsubscribes in the question. A site that sets `asm` or `mailSettings` already stays, as `mapping.md` says, so the question leaves out group unsubscribes and the bypass settings. | ||
|
|
||
| Whenever the person adds entries to PostHog's list by hand, in the import or a re-import, such as when the import tool is missing, ask only whether the Address Allow List and Bounce Purge are on, as "For the report" says, and for Bounce Purge's two day counts. Tell them the rule of each one that is on: leave out the addresses and domains on the Allow List, which they read in SendGrid themselves, and the bounces older than the day count for their kind, as "Leave out what SendGrid delivered to anyway" says. A setting they can't say is on gets no rule. | ||
|
|
||
| **Export from the dashboard (preferred).** In SendGrid: Suppressions, then each of Bounces, Spam Reports, and Invalid Emails, then **Export CSV**. Ask the person where they saved each file. Read the header row to find the address column. | ||
|
|
||
| **Read from the API.** With `Authorization: Bearer $SENDGRID_READ_API_KEY`: | ||
|
|
||
| - `GET https://api.sendgrid.com/v3/suppression/bounces` | ||
| - `GET https://api.sendgrid.com/v3/suppression/spam_reports` | ||
| - `GET https://api.sendgrid.com/v3/suppression/invalid_emails` | ||
|
Silthus marked this conversation as resolved.
Resolved
|
||
|
|
||
| Each answers a list of `{ created, email, reason, status }`. Page with `limit=500` and `offset`, adding 500 each time, until a page has fewer than 500 entries. Wait and retry on `429`. | ||
|
|
||
| **Map each entry.** | ||
|
|
||
| | SendGrid list | PostHog `reason` | | ||
| |---|---| | ||
| | Bounces | `bounce` | | ||
| | Invalid Emails | `bounce` | | ||
| | Spam Reports | `complaint` | | ||
|
|
||
| **Leave out what SendGrid delivered to anyway.** Before you take the entries, ask the person what "For the report" asks about the Address Allow List and Bounce Purge, unless they answered it in this run, and, when the Allow List is on, ask for its entries. Apply each one on its own: | ||
|
|
||
| - **Address Allow List** on: leave out every entry of the lists whose address or domain is on it. | ||
| - **Bounce Purge** on: leave out each bounce older than its number of days from its `created` time. A `status` that starts with `5` is a hard bounce, and one that starts with `4` is a soft one. | ||
|
|
||
| When you take the entries yourself, a setting the person can't say is on, or whose entries or day counts they can't give, leaves out nothing, and the other one still applies. In a re-import, tell the person each setting's rule and how many entries it left out, that it was not checked, or, for an Allow List whose entries they couldn't give, `Address Allow List entries not given`. | ||
|
|
||
| **Leave out the other lists.** | ||
|
|
||
| - **Blocks** are temporary refusals by a receiving server, not a sign that the address is bad. | ||
| - **Global unsubscribes and group unsubscribes** are marketing preferences, and PostHog's opt-outs apply to marketing messages only. At SendGrid a global unsubscribe also stopped transactional mail, unless the send bypassed it. Once the sends move, these addresses get transactional email again. The report gives their count, as "For the report" says. | ||
|
|
||
| ## For the report | ||
|
|
||
| The count of global unsubscribes and of group unsubscribes, which the import leaves out. Count the rows of the person's exports (Suppressions, then each of Global Unsubscribes and Group Unsubscribes, then **Export CSV**), or the entries of `GET https://api.sendgrid.com/v3/suppression/unsubscribes`, paged as above, and of `GET https://api.sendgrid.com/v3/asm/suppressions`, with the read-only key. When the person has neither, write `unsubscribes not counted`. | ||
|
|
||
| Ask the person once, whether or not the import runs, whether two settings are on in SendGrid (Settings, then Mail Settings). With the **Address Allow List**, SendGrid delivered to an address on it, or at a domain on it, whatever its lists said. With **Bounce Purge**, SendGrid deleted a bounce once it was older than the days set for hard bounces or for soft bounces. When Bounce Purge is on, ask for its two day counts. Then write: | ||
|
|
||
| - Each setting that is on and its rule, never an address or an Allow List entry: the Allow List leaves out the addresses and domains on it, and Bounce Purge the bounces older than the day count for their kind, where a `status` that starts with `5` is a hard bounce and one that starts with `4` is a soft one. Whoever adds entries to PostHog's list by hand, before cutover or in a re-import, leaves out the same entries. After the import, add under the phase how many entries each one left out. | ||
| - When Bounce Purge is on: bounces that SendGrid would have purged later stay suppressed in PostHog until someone removes them. | ||
| - Each setting the person can't say is on, and Bounce Purge without its day counts: `<setting> not checked`, because PostHog may suppress addresses that SendGrid still delivered to. After an import in which the person couldn't give the Allow List's entries: `Address Allow List entries not given`, for the same reason. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.