Skip to content

Instantly share code, notes, and snippets.

@sietsevdschoot
Last active April 10, 2024 20:13
Show Gist options
  • Save sietsevdschoot/acf0daa46c5e678d7878530a2173c03e to your computer and use it in GitHub Desktop.
Save sietsevdschoot/acf0daa46c5e678d7878530a2173c03e to your computer and use it in GitHub Desktop.
Powershell script to replace phone numbers by contactnames in WhatsApp-Chat-Exporter generated .html files of Whatsapp conversations.
using namespace System.Text.RegularExpressions
using namespace System.IO
[CmdletBinding()]
param(
[IO.FileInfo] $GoogleContactsVcf = "$PSScriptRoot\contacts.vcf",
[IO.DirectoryInfo] $WhatsappConversationsFolder = "$PSScriptRoot\WhatsApp-Key-DB-Extractor\extracted\result\"
)
if (!(Test-Path "$PsScriptRoot\ConvertFrom-Vcf.ps1")) {
# Temporary solution while pull request hasn't been reviewed.
$url = "https://raw.githubusercontent.com/sietsevdschoot/ConvertFrom-Vcf/feature/make-gmail-vcf-compatible/ConvertFrom-Vcf.ps1"
Invoke-WebRequest -Uri $url | Select-Object -exp Content | Out-File $PsScriptRoot\ConvertFrom-Vcf.ps1
}
Function ExtractVcfContacts {
param(
[IO.FileInfo] $vcfContactsPath
)
$contacts = & "$PSScriptRoot\ConvertFrom-Vcf.ps1" $vcfContactsPath.FullName -IsGoogleContactsVCardFormat
$contacts
| Select-Object "Full Name", @{ Name="PhoneNumbers"; Expression={ ExtractPhoneNumbers $_ } }
| Where-Object { $_.PhoneNumbers }
}
Function ExtractPhoneNumbers($contact) {
$phoneNumbers = ,@((@($_.Phone1, $_.Phone2, $_.Phone3, $_.Phone4)
| ForEach-Object { ($_ -replace "\W", $null).Trim() })
| Where-Object { $_ -match "\d{9,13}" })
# For Dutch numbers, remove the leading zero for mobile numbers when the country code is specified.
$phoneNumbers = $phoneNumbers
| ForEach-Object{ (($_.TrimStart('0') -replace "^3106", "316")) }
$phoneNumbers
}
$extractPhoneNumberRegex = "(?<=[ ]|\t|\n|\r)\d{10,13}(?=[ ]|\t|\n|\r)"
Function FindFileContactInfo {
param(
[IO.DirectoryInfo] $conversationsFolder,
[PsCustomObject[]] $contacts
)
$files = Get-ChildItem $conversationsFolder.FullName -Filter *.html
foreach ($file in $files) {
$content = Get-Content $file.FullName -Raw
$phoneNumbers = $content
| Select-String -Pattern $extractPhoneNumberRegex -AllMatches
| Select-Object -exp Matches | Select-Object -exp Value
| Select-Object -Unique
$phoneNumberMatches = @{}
foreach ($phoneNumber in $phoneNumbers) {
$matchedContacts = $contacts | Where-Object { ($_.PhoneNumbers | Where-Object { $phoneNumber -match $_ }) }
if ($matchedContacts) {
$phoneNumberMatches[$phoneNumber] = (@($matchedContacts) | Select-Object -exp "Full Name")
}
else {
$phoneNumberMatches[$phoneNumber] = $null
}
}
[PsCustomObject] @{
File = $file;
Contacts = $phoneNumberMatches
}
}
}
Function UpdateFileContents {
param(
[PsCustomObject[]] $results
)
$entriesWithFoundContacts = $results | Where-Object{ ($_.Contacts.Values | ForEach-Object { $_ }) }
foreach ($entry in $entriesWithFoundContacts) {
$content = Get-Content $entry.File.FullName -Raw
foreach($contact in $entry.Contacts.GetEnumerator()) {
$content = $content -replace $contact.Key, $contact.Value
}
$content | Set-Content $entry.File.FullName
if ($entry.Contacts.Keys -Contains $entry.File.BaseName) {
$contactName = $entry.Contacts[$entry.File.BaseName]
$sanitizedContactName = $contactName -replace ("($(([Path]::GetInvalidFileNameChars() | %{ [Regex]::Escape($_) }) -join "|"))"), $null
$newName = (Test-Path (Join-Path $entry.File.Directory.FullName "$sanitizedContactName$($entry.File.Extension)")) `
? "$sanitizedContactName_$([Guid]::NewGuid().ToString("N"))$($entry.File.Extension)" `
: "$sanitizedContactName$($entry.File.Extension)"
Rename-Item -Path $entry.File.FullName -NewName $newName -Verbose
}
}
}
$myContacts = ExtractVcfContacts $GoogleContactsVcf
$results = FindFileContactInfo -conversationsFolder $WhatsappConversationsFolder -contacts $myContacts
UpdateFileContents $results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment