Liczenie ilości użytkowników programu

0

Hey,
Napisałem program, udostępniłem go publicznie - jest fajnie... Słoneczko świeci, ptaszki ćwierkają... Pytanie - kto i czy w ogóle ktoś używa mojego programu?
W jaki sposób dowiedzieć się o bazie użytkowników swojego programu? Nie chodzi o żadne szczegóły - po prostu ile osób.

Wydaje mi się, że najprościej pozwolić użytkownikowi na poinformowanie o tym. Jak się to realizuje?
Wymyśliłem, że szybkim i prostym rozwiązaniem przy użyciu Delphi byłoby co następuje:

  • Użytkownik pobiera mój program i instaluje go,
  • Instalator pobiera godzinę i datę instalacji i zapisuje ją do pliku konfiguracyjnego INI na moim serwerze,
  • Mój serwer (prywatna strona internetowa) używa SSL (jeśli ma to znaczenie) - Jak zapisać te dane w tym pliku?

Używany do tego protokołu HTTP? A może FTP?
Chodzi o jak najprostszą implementację - dopisanie danych do pliku INI.

Proszę o jakieś podpowiedzi...

Ps: Tak wiem, prywatność - dane całkowicie anonimowe + za zgodą użytkownika!

6

Nie wiem czy dobrze rozumiem ale może zrób instalator który na końcu będzie miał checkbox Poinformuj autora... i jeżeli jest zaznaczony po prostu w przeglądarce otwiera się strona https://przyklad.pl/dodajuzytkowanika?imie=imie&datainstalacji=07-12-2022 oczywiście adres i parametry przykładowe (jak to nie dane wrażliwe to może być taki zwykły GET) a resztę już wykonuje się po stronie serwera nie wiem PHP albo nawet jakiś node.js zależy w czym zrobisz lub masz zrobioną stronę. O imię też możesz pytać w instalatorze albo po prostu formularz do wypełnienia na stronie.

6
Pepe napisał(a):

W jaki sposób dowiedzieć się o bazie użytkowników swojego programu? Nie chodzi o żadne szczegóły - po prostu ile osób.

Zacznij od zliczania samych pobrań instalatora, zliczania po stronie serwera.

Wydaje mi się, że najprościej pozwolić użytkownikowi na poinformowanie o tym. Jak się to realizuje?

Po co mu pozwalać? Jeśli nie kradniesz wrażliwych informacji z jego komputera, to możesz w tle takie informacje przesłać, a żeby to było uczciwe, opisać sprawę w licencji widocznej tuż przed właściwym procesem instalacji (jakie dokładnie informacje zostaną przesłane), którą użytkownik musi zaakceptować, aby pchnąć kreator dalej. Możesz też zrobić inaczej, czyli dodać (domyślnie zaznaczony) zwykły checkbox z informacją o tym, że autor otrzyma cynk o danej instalacji, wyłącznie na potrzeby prowadzenia statystyk użytkowania.

Przy czym skup się na tym, aby użytkownik widział jak na dłoni, że instalator powiadomi Cię o danej instalacji. Możesz dać checkbox, możesz go nie dawać i wymuszać przesłanie danych do Twojego serwera. Masz prawo prowadzić statystyki i telemetrię, ale użytkownik ma też prawo o wszystkim wiedzieć, zanim zainstaluje program. Dlatego też zrób czytelny interfejs, tak aby wszystkie informacje były widoczne i opcjonalnie łatwe do zmiany, tak aby użytkownik czuł, że jest traktowany uczciwie i z szacunkiem.

0

Telemetria to słowo, które powoduje strach i zniechęcenie.
Ja chcę tylko wiedzieć, czy czasem nie tracę niepotrzebnie czasu... chyba każdy z nas chciałby wiedzieć, czy dany program pobierają tylko boty, czy może prawdziwi ludzie - którzy naprawdę używają naszego softu.

Zliczanie pobrań instalatora nie ma sensu, ponieważ nie jest on dostępny z jednego źródła.
Zatem najlepszą opcją będzie użycie instalatora (mój jest napisany i tak w Delphi) i wysłanie do skryptu php, który po odebraniu parametrów zapisze dane do pliku...

Sprawdzę INDY i POST...

3

@Pepe:

Po pierwsze, nie myśl w kategoriach PLIKU.
Wywołanie http nie ma nic do pliku, nawet pozornie udostępniony skrypt serwera www (funkcjonalność) nie musi mieć charakteru pliku.
Musisz zmienić sposób myślenia o tych rzeczach, przy złym myśleniu niemożliwe jest dobre wykonanie (chyba że przypadkowo)

Pepe napisał(a):

Używany do tego protokołu HTTP? A może FTP?
Chodzi o jak najprostszą implementację - dopisanie danych do pliku INI.

INI na serwerze ? Na pewno to dobrze przemyślałeś? Masz na to jakieś uzasadnienie ?
FTP dla tego co przedstawiasz top bez sensu
Za pośrednictwiem HTTP(S) wywołanie endpointu (jakkolwiek by to dumnie brzmiało - tutaj bardzo prosty endpouint) i WPIS DO BAZY na serwerze.

Język w jakim działasz na serwerze - obojętny. Poczynając od PHP na biedahostingach, każdy.

3

Ja do tych celów tworzę .msi który przy odpaleniu dopiero pobiera z serwera najnowszą wersje i ją instaluje, przy okazji zapisując na serwerze informacje które to .msi przekazało do pobrania.

6

Do prowadzenia takiej statystyki aktywności możesz prosty mechanizm sprawdzania czy jest nowa wersja twojego programu. Tym sposobem wilk syty i owca cała... użytkownik zawsze ma informację o najnowszej wersji Twojego programu Ty zaś masz informację ile osób używa twojego softu.

0

Przygotowałem testowy skrypt /telemetry.php

Tutaj pobieram wartość parametru "user"

	if (isset($_GET['user'])) {
		$PHP_TELEMETRY_USER_NAME = $_GET['user'];
	} else {
		$PHP_TELEMETRY_USER_NAME = "-1";
	}

Wpisując w przeglądarce zapytanie: https://pawelporwisz.pl/telemetry.php?user=Lala
uzyskuję wpis w pliku na serwerze, np:
[Lala]
User=Lala
Date=Środa, 7 grudnia 2022 (1757)

Wartość "Lala" jest poprawnie przekazywana do funkcji zapisującej plik

Teraz aplikacja w Delphi z idHTTP (Indy):

var
   SL_LIST  : TStringList;
begin
   SL_LIST := TStringList.Create;
   try
      IdOpenSSLSetLibPath(ExcludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName)));

      SL_LIST.Add('user=' + 'TEST'); // to można usunąć
      try
         result := Form1.IdHTTP.Post('https://pawelporwisz.pl/telemetry.php', SL_LIST);
         result := Form1.IdHTTP.Post('https://pawelporwisz.pl/telemetry.php?user=BYLE_CO', SL_LIST); // to dziala...

         Form1.Memo1.Lines.Add(Result); // tutaj dostaje wynik
      except
         Form1.Memo1.Lines.Add( SysErrorMessage(GetLastError));
      end;
   finally
      SL_LIST.Free;
   end;
end;

Po pierwsze, działa to tylko jak używam bibliotek SSL (libeay32.dll, ssleay32.dll) - wolę bez SSL, bo i po co mi to...
Nie jestem pewien, ale jak usunę https z adresu, to chyba też działa, tylko musze dać linię: Form1.IdHTTP.HandleRedirects := True;
Program działa - zapisuje dane do pliku - ale nie działa obsługa parametru -> user jest pusty (czyli zmienna $PHP_TELEMETRY_USER_NAME przyjmuje -1)!
Dlaczego?

Czyli przeglądarka prawidłowo interpretuje zapytanie, a program nie - dlaczego - coś trzeba przekazać dodatkowo?

EDIT:
result := Form1.IdHTTP.Post('https://pawelporwisz.pl/telemetry.php?user=Test', SL_LIST);
Taki zapis działa - wystarczy przekazać pustą listę, a parametry wpisać w adresie...

2
     result := Form1.IdHTTP.Post('https://pawelporwisz.pl/telemetry.php?user=BYLE_CO', SL_LIST); // to dziala...

zamiast metody POST możesz użyć prostszej w użyciu metody GET. Tym samym SL_LIST jest zbędne

 result := Form1.IdHTTP.get('https://pawelporwisz.pl/telemetry.php?user=BYLE_CO');

Zapis danych do pliku jest słabym rozwiązaniem ponieważ masz wtedy problem z wielodostępem i coś może być albo nadpisane albo nie zapisane

0

Dziękuję wszystkim za pomoc!
@kAzek: Twoja metoda wygrywa :)

W ostateczności do obsługi protokołu HTTP użyłem komponentów:

  • NetHTTPClient
  • NetHTTPRequest

Dane zapisuje sobie do pliku, który ma strukturę INI (dzięki temu, jak pobiorę ten plik do bardzo łatwo mi parsować wyniki, ewentualnie w przyszłości).
Sekcją jest Data i Godzina
Plik zawiera informacje typu:

[07.12.2022 1928]
User=Pawel
Date=Środa, 7 grudnia 2022 (1930)
IP=
Host=
Port=13401
UserAgent=

Użyłem metody Get - dzięki @grzegorz_so
Lista w metodzie Post służy do określenia pliku, a ja tego nie potrzebuję, w moim trywialnym przypadku.
Mimo adresu https, program działa i nie wymaga bibliotek SSL. Czyli wydaje się, że wszystko działa.
Jeszcze potestuję i jestem gotowy do implementacji (jeśli się na nią zdecyduję).

2
Pepe napisał(a):

@kAzek: Twoja metoda wygrywa :)

To było wiadomo od początku.

[07.12.2022 1928]
User=Pawel
Date=Środa, 7 grudnia 2022 (1930)
IP=
Host=
Port=13401
UserAgent=

Czy rozumiesz że jak dwóch klientów jednocześnie pobiorą twój program to masz szansę cały plik INI stracić bo będzie tam kaszana?
Po kiego ci podwójna data w pliku?
Już 3-osoby poradziło ci użyć bazy zamiast pliku, myślisz że są to głupie nieprzemyślane rady nie poparte doświadczeniem?
UserAgent zawsze będzie znany, aczkolwiek nie koniecznie musi to być zgodne z prawdą.
Po kiego ci IP i Host razem? (Czasami Host nie jest zdefiniowany, zaś wg IP dostaniesz host w prosty sposób, aczkolwiek pamiętaj o proxy oraz maskardzie)
Dodaj jeszcze pole ProgramCode i używaj tą bazę dla wszystkich swoich produktów.

2

@Pepe Jeśli koniecznie chcesz trzymać dane w pliku, to zapisuj dane każdego użytkownika w oddzielnym pliku. Nazwę pliku możesz wygenerować w oparciu o treść parametru ?user=
To nie jest dobre rozwiązanie, ale gwarantuje Ci że plik z danymi użytkownika nie wysypie się

1

Jak @PrzemysławWiśniewski napisał, niech program sprawdza czy jest nowa wersja. Ja tak robię po 10 sekundach od uruchomienia programów. Oczywiście użytkownicy są powiadomieni dlaczego muszą puścić program na zaporze (lub nie jeśli nie chcą sprawdzania).
Podsunąłeś mi pomysł co do statystyk. Ja jednak załatwię to chyba REST-em i w ten sposób stworzę sobie bazę użytkowania programu.
Powiadomię o tym użytkowników i nawet dam możliwość zablokowania przekazywania tych danych.

Co do danych, nie jestem pazerny. Pobiorę coś unikatowego, np. numer seryjny dysku twardego aby z tej danej utworzyć klucz w bazie danych, oraz datę uruchomienia programu.

1

Panowie,
Widzę, że niektórzy koniecznie chcę udowodnić mi że nie mam racji i koniecznie muszę użyć baz danych.
Pisząc, że nie używam baz danych na mojej stronie, nie znaczy że ich nie znam, lub nie potrafię obsługiwać. Po prostu nie potrzebuję tej funkcjonalności, dla tak prostego zastosowania.
Mój plik tekstowy się nie wysypie. Bo nie ma takiej opcji. Od 20 lat stosuje podobny zapis dla pobieranych plików i nie zdarzyło się to. Plik jest blokowany na czas zapisu - prawdopodobieństwo, że w tym samym czasie więcej niż jedna osoba zechce instalować mój program jest znikome. Jeśli nawet się to zdarzy i coś się stanie (dane się nie zapiszą, plik się uszkodzi) - nic się nie stanie! To nie bank, nic od tego nie zależy. Te dane są tylko dla mojej wiadomości - próba dowiedzenia się czy jest sens tworzyć za darmo oprogramowanie, używane przez być może 10 osób.

Zatem, dziękuję za troskę. Wiem co robię. Wątek miał pomóc mi jak zrealizować to jak najprościej - dzięki waszej pomocy udało się to. Nie idźmy ta drogą :)

@robertz68: Mój program aktualizujący (z którego jestem dumny :P) również uruchamiany jest z pewnym ustalonym opóźnieniem i owszem, mógłby realizować tę funkcjonalność... Problem jest taki, że jest on konfigurowalny i można go wyłączyć (poza tym, uruchamia się przy każdym otwarciu programu (lub co ustalony czas) - zatem nie spełnia to moich wymagań). Pomysł z unikalnym numerem jako ID jest bardzo dobry (na czas testów przyjąłem datę i czas odpalenia, co jest wystarczająco unikalne).

4
Pepe napisał(a):

[07.12.2022 1928]
User=Pawel
Date=Środa, 7 grudnia 2022 (1930)
IP=
Host=
Port=13401
UserAgent=

Jeśli kiedykolwiek przyjdzie Ci do głowy trzymać datę w pliku tekstowym (obojętnie w jakim celu i formacie), to broń bug nie trzymaj takich informacji jako formatowanych dat, czyli tak jak wyżej w kluczu Date — zmienisz peceta lub localsy i to jebnie. Jeśli już, to trzymaj liczbowe time stampy — są w bibliotece standardowej funkcje do takich konwersji.

0

@furious programming:

Jeśli już, to trzymaj liczbowe time stampy

Zgoda. Tylko że plik tekstowy z takim zapisem daty jest nieczytelny dla użytkownika. Mam na myśli podgląd takiego pliku.
Zawsze można timestamp zapisać w niezależnej od locals'u znormalizowanej postaci tekstowej . Np. "2022-02-15T0947Z" albo
"2022-02-15 0947"

0

a log z php i sprawdzenie wywołań skrypt_szpiegujacy_usera.php nie wystarczy?

0

Jeśli instalator musi zostać pobrany, to wystarczy, że zobaczysz ile razy to wystąpiło, np. z loga serwera WWW. Liczba użytkowników programu na pewno będzie nie większa niż ilość pobrań. To pozwoli zorientować się, czy warto "iść dalej" i sprawdzać ilość faktycznych instalacji.
Jeśli twój program jest już używany, to ani zliczanie ilości pobrań, ani faktycznych instalacji nie da ci rzetelnej informacji, której potrzebujesz, bo będzie dotyczyć tylko nowych użytkowników.
Trzeba jeszcze rozwiązać problem aktualizacji, aby nie zaliczyć po raz kolejny użytkownika, który już był już "policzony" :)

0

@skrzat Tak, w przypadku, gdy program pobierany jest tylko z mojej strony to prawda. Mogę potrzebne informacje pobrać z logów serwera. Ale, program można pobrać z różnych źródeł, choćby z torrentów.
W miarę rzetelne dane dostarczy tylko instalacja programu (oczywiście, można instalator rozpakować, ale to bez sensu) - mam wtedy pewność, że ktoś przynajmniej spróbował :P
Pobieram unikalny identyfikator PC, więc nawet jak się powtórzy (ktoś ponownie pobierze i zainstaluje) to będę o tym wiedział (albo jak ktoś zainstaluje aktualizacje). Na dzień dzisiejszy to niewinna zabawa - jak będę miał milion użytkowników, to się będę martwił - przy tych kilku-setkach nic naprawdę nie ma znaczenia...

0

Taki Lamerski 😂 sposób jaki miałem ale w innej sprawie. Bardzo proste ale skuteczne jest użycie synapse i ftpsend do wysyłania na serwer do jednego katalogu krótkiego pliku txt z danymi jakimi chcesz, żeby kopie Twojego programu przesyłały. Każdy pliczek z katalogu powinien mieć inną nazwę aby nie było powtórzeń (bo pliki się ponadpisują )
Następnie tworzysz malutki programik który działa tylko u Ciebie i scala te małe pliki tekstowe(kasując oryginał i zwalniając nazwę) w prostą baze danych gdzie masz wszystko zliczone. Albo wyświetla Tobie scalone dane w formie linijek tekstu z danymi.
Numerowałem swoje pliki jako np 1.txt, 2.txt itd a następnie zwalniałem. Pozwala to generować nazwy plików za pomocą pętli while…np
Do przesyłania dużych ilości danych , połączeń itd to się nie nadaje bo jest powolne. Ale dla jednego połączenia z informacją o instalacji jest mega proste i dość szybkie. Nie wymaga sporych umiejętności programistycznych.

1 użytkowników online, w tym zalogowanych: 0, gości: 1