Git Product home page Git Product logo

thess / callattendant Goto Github PK

View Code? Open in Web Editor NEW
13.0 13.0 6.0 14.82 MB

A python-based automated call attendant, call blocker, and voice messaging system running on a Raspberry Pi or equivalent. Screens callers and block robocalls and scams with a low-cost system and modem.

Home Page: https://thess.github.io/callattendant/

License: MIT License

Python 79.81% HTML 18.30% Shell 0.21% CSS 1.67%

callattendant's People

Contributors

emxsys avatar thess avatar zomgreg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

callattendant's Issues

Leap Year Problem?!

Suddenly, today (2/29/24), an incoming call (any incoming call) causes Call Attendant to crash and burn. Here is what I see:

Feb 29 08:59:09 callattendant[2731]: Approved LED blinking: 2 times

Feb 29 08:59:09 callattendant[2731]: Waiting for call...

Feb 29 08:59:09 callattendant[2731]: Running the Flask server

Feb 29 08:59:09 callattendant[2731]: * Serving Flask app 'callattendant'

Feb 29 08:59:09 callattendant[2731]: * Debug mode: off

Feb 29 08:59:35 callattendant[2731]: RING LED blinking: 10 times

Feb 29 08:59:36 callattendant[2731]: > Queueing call 206xxxxxxx for processing

Feb 29 08:59:36 callattendant[2731]: Incoming call from 206xxxxxxx

Feb 29 08:59:36 callattendant[2731]: > Checking next-call-permitted

Feb 29 08:59:36 callattendant[2731]: > Checking whitelist(s)

Feb 29 08:59:36 callattendant[2731]: Approved LED blinking: 10 times

Feb 29 08:59:36 callattendant[2731]: ValueError('day is out of range for month')

Feb 29 08:59:36 callattendant[2731]: ** Error running callattendant

Feb 29 08:59:36 callattendant[2731]: Shutting down...

Feb 29 08:59:36 callattendant[2731]: -> Stopping modem

Feb 29 08:59:36 callattendant[2731]: -> Closing modem serial port

Feb 29 08:59:36 callattendant[2731]: -> Stopping voice mail

Feb 29 08:59:36 callattendant[2731]: -> Releasing resources

Feb 29 08:59:36 callattendant[2731]: Shutdown finished

Feb 29 08:59:36 systemd[1]: callattendant.service: Main process exited, code=exited, status=1/FAILURE

Feb 29 08:59:36 systemd[1]: callattendant.service: Failed with result 'exit-code'.

The issue would seem to be whatever is causing "ValueError('day is out of range for month')".

How to convert to this fork?

Sorry for all of my newbie questions...

I started out with one of the other forks (also based on galacticstudios' version - specifically this one https://github.com/advfr/callattendant/ as it had all the GPIO stuff commented-out). I now want to move to this fork as it appears to be the most active I have found so far and, perhaps, most advanced.

I have everything working in my current version with the service running on start via systemctl and the stuff already configured in the .calltattendant folder. I hope to perturb all of this to the minimum extent possible. But I have no idea how to best accomplish this.

Thanks in advance for any tips.

Inaccurate text in Call Detail page

If the call was blocked due to blocked name pattern list...

It clearly shows the call as blocked in red, as it should be.

But below it says "This caller is allowed but..." and this seems at best confusing and at worst incorrect.

Capture

Best

How to use a known modem's /dev file?

I know that my modem (at least for testing) is connected to a serial port /dev/ttyS2. I can see that it searches for and finds/uses this. Is there some way to just have that used instead of the searching? Thanks

Incorrect Timezone in Call Log Display

Never seen this in my original CA install on Ubuntu in a virtual box. But now working on a CA install for a friend on Armbian on an old Android TV computer...

I guess that when I started work on this Armbian machine I did not notice that the timezone was not set correctly and so the time was off. Then I noticed that the clock app display was also wrong in the same way. Finally, when looking at the call log in the UI, I woke up and noticed this. So I went into the settings and set the timezone correctly. This changed the clock app. And in a terminal the date command yields the correct results. Additionally, in a python3 terminal printing datetime.now() yields the correct results.

However, even after rebooting the machine, incoming calls are logged in CA with incorrect times that map to the original, timezone error that was in place when CA was installed/configured.

I see nothing about this in the app config file. Yet something seems to be "sticking" somewhere. Does anyone have any idea what I need to do to fix this?

Thanks!

Addition to Screening/Voice Mail?

I have a friend whose telecom supplier offers a call screening service as part of his package (what a lucky guy!) and I have long coveted something his package does. When someone calls who is not recognized as either allow or block, it screens by saying something like "Your call is being screened. Prove you are a human and press # to be connected." If the user presses # then the phone rings through, otherwise they are disconnected...

I know that exactly this cannot be accomplished using Call Attendant. But I suspect that something close could be implemented. In the screening process, perhaps it can say something like "Your call is being screened. If you are a human, press # to be temporarily unblocked, hang up, and immediately call back." Then if # is pressed, Call Attendant can toggle the Permit Next Call state and then hang up? I feel like I have read somewhere about a commercial call-blocking box that does just this. So it is not without precedence.

When doing all this (perhaps it makes sense always when the Permit Next Call is toggled on) there should be a the means to automatically toggle Permit Next Call state back off within some timeout period? To me, it makes no sense to have Permit Next Call be turned on and simply left on indefinitely (at least I think that it what it does). So a configurable timeout of x minutes makes sense to have.

Looking at the code and considering my very limited python experience, I MIGHT be able to add this myself. From what I can tell, all of the "bones" for this are there. And the threading.Timer mechanism looks enough to me like Javascript's setTimeout() that it could be used easily enough. But at best, I would be stumbling around in the semi-darkness. So perhaps this would be a good enhancement?

Thanks

Really minor spelling type error in the web UI

In the string returned under the else below, add the word "be"...

Thanks

@app.route('/callers/permitnextcall')

def Callers_permit_next_call():

nextcall = NextCall(app.config['MASTER_CONFIG'])

if nextcall.toggle_next_call_permitted():

    return '1Next call will be permitted.'

else:

    return '0Next call will **be** handled normally.'

Error deleting messages

I was finally able to get a working copy of this project with:
pip3 install 'callattendant @ git+https://github.com/thess/callattendant'

While playing around I generated a couple of messages but when I went to delete them, I got the following error:

pi@rpi3bplus:~ $ callattendant
Command line options:
  --config=None
  --data-path=None
  --create-folder=False
Initializing Modem
Opening serial port
Looking for modem on /dev/ttyACM0
*** US Robotics modem detected ***
Serial port opened on /dev/ttyACM0
Modem initialized
MSG LED pulsing
Starting the Flask webapp
MSG count: 2
Running the Flask server
Approved LED blinking: 2 times
Waiting for call...
 * Serving Flask app 'callattendant'
 * Debug mode: off
Removing message
[2024-03-03 08:40:29,554] ERROR in app: Exception on /messages/delete/1 [GET]
Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 1463, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 872, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 870, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 855, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
  File "/home/pi/.local/lib/python3.9/site-packages/callattendant/userinterface/webapp.py", line 948, in messages_delete
    message = Message(get_db(), current_app.config.get("MASTER_CONFIG"))
TypeError: __init__() missing 1 required positional argument: 'event'

List of available / compatible modems

Is there a list of available / compatible modems?

I have a Sentry Call Blocker that recently died and this project looks like an excellent replacement but finding a modem appears to be more difficult that I expected.

Import and Export Permitted and/or Blocked numbers

I can't find any documentation on the format of the .csv files.

I guessed that the .csv format could be surmised from an example so I added a number or two to each list and then attempted to export them. This resulted in the following error(s):

[2024-03-03 09:29:41,331] ERROR in app: Exception on /callers/permitted/export [GET]
Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 1463, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 872, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 870, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 855, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
  File "/home/pi/.local/lib/python3.9/site-packages/callattendant/userinterface/webapp.py", line 748, in callers_permitted_export
    return callers_export(query, 'callattendant_permitlist.csv')
  File "/home/pi/.local/lib/python3.9/site-packages/callattendant/userinterface/webapp.py", line 734, in callers_export
    return send_file(
TypeError: send_file() got an unexpected keyword argument 'attachment_filename'
[2024-03-03 09:32:39,805] ERROR in app: Exception on /callers/blocked/export [GET]
Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 1463, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 872, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 870, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/pi/.local/lib/python3.9/site-packages/flask/app.py", line 855, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
  File "/home/pi/.local/lib/python3.9/site-packages/callattendant/userinterface/webapp.py", line 639, in callers_blocked_export
    return callers_export(query, 'callattendant_blocklist.csv')
  File "/home/pi/.local/lib/python3.9/site-packages/callattendant/userinterface/webapp.py", line 734, in callers_export
    return send_file(
TypeError: send_file() got an unexpected keyword argument 'attachment_filename'

Add query of next call permitted state in web app

Hi Ted. I see you are currently fiddling with this. While doing so, might I suggest adding the ability to check the next call flag state via the web app? Something like this in webapp.py:

@app.route('/callers/querynextcall')
def Callers_query_next_call():
    nextcall = NextCall(app.config['MASTER_CONFIG'])
    if nextcall.is_next_call_permitted():
        return '1Next call will be permitted.'
    else:
        return '0Next call will be handled normally.'

It mimics the existing /callers/permitnextcall - just without the actual toggling of the flag's state.

I use this small mod from my Android CA UI. Thanks.

Not getting date/time on console log

I have tried setting CA to all combinations of development/production, debug/not and in no case do I end up seeing date/time stamps in the console log. What am I doing wrong here? Thanks

Capture

Change or Configure MQTT retention on publishing?

As I have started to investigate the MQTT stuff, I have noticed that my two MQTT clients (on Android and Windows) were getting repeated messages. Seemed like they were happening when the clients started/re-started. So I posted here on Reddit about this since I am an MQTT idiot.

I got a quick response suggesting that this line in mqttindicators.py may be the cause:

client.publish(self.topic_prefix + topic, message, retain=True)

They said "When you set retain=true for a message is basically tells the broker to remember the message and to send it to everyone who subscribes to that topic in the future. So when your client reconnects and subscribes again it receives the message again."

So this may be a candidate for change or configuration?

As I wrote in that post, at least for me, "The sending/receipt of these messages are far from mission-critical. I am just trying to compensate for a lack of caller-id-enabled phone handsets by sending MQTT messages to Android smart phones and Windows desktops on my LAN. I really don't need/want high levels of service quality and repeated sending of messages. I am seeking a one-and-done kind of thing. So when the phone rings, the screening app sends out the MQTT messages and I am trying to show them on the receiving devices in semi-real time so I can know who is calling at that time (and know if I want to pick up or not)."

Now I am not sure that my use-case is consistent with other CA users. As I said earlier, I am an MQTT idiot. Thanks!

Something else about .wav files...

Maybe it is just me and my install. But after installing following instructions (I did, however, use pip rather than pip3 since I am on Ubuntu and read somewhere that this was a more appropriate way to go), I ended up with an empty resources folder under ~/.callattendant and I had to manually copy the .wav files from ~/home/davidw/callattendant/lib/python3.10/site-packages/callattendant/resources into that location in order to stop getting failures when starting callattendant. Is that intended? Thanks

[Request] Make Raspberry Pi GPIO optional

I'm attempting to install callattendant on a Libre LePotato running Raspbian (although this request also could apply to an actual Raspberry Pi).

I don't have a "hat" with any extra hardware and don't believe I need one. The default config file has GPIO_LED_* settings but does not have a global enable/disable setting.

The original emxsys/callattendant#171 contains a commit that removes the GPIO support, emxsys/callattendant@8d7fb7c.

I'd like to see this "removal" be made into an option.

Going off hook is often not happening on USR 5637

I finally received my new (used) USR 5637 and have it hooked up. I have already flashed the most recent firmware and it appears to support voice activity.

And, indeed, things do seem to work for the most part. However, many times when a call is screened (I cannot yet see a pattern to it), the log shows "Going off hook..." but the phone keeps ringing and ringing - at least until I hang up or the call goes to my local telecom's voice mail system. And then I start seeing what I expect to see in the log. Stuff like:

Jan 16 14:26:26 callattendant[3548]: RING LED blinking: 10 times
Jan 16 14:26:32 callattendant[3548]: >> Playing greeting...
Jan 16 14:26:36 callattendant[3548]: >> Starting voice mail...
Jan 16 14:26:36 callattendant[3548]: MSG LED blinking
Jan 16 14:26:36 callattendant[3548]: > Waiting for key-press...
Jan 16 14:26:45 callattendant[3548]: Timeout limit exceeded: 8
Jan 16 14:26:45 callattendant[3548]: Exiting wait_for_keypress(8): Timeout - wait time limit reached.
Jan 16 14:26:45 callattendant[3548]: MSG LED turned off
Jan 16 14:26:45 callattendant[3548]: MSG count: 0
Jan 16 14:26:45 callattendant[3548]: > Going on hook...
Jan 16 14:26:45 callattendant[3548]: Waiting for next call...

Sometimes this actually works. I can hear a greeting and even record a voice message and play it back via the web UI. But I would say that the majority of the time, I encounter this mis-behavior.

Here are the screening variables from my config file:

SCREENED_ACTIONS = ("answer", "greeting", "voice_mail")
SCREENED_GREETING_FILE = "general_greeting.wav"
SCREENED_RINGS_BEFORE_ANSWER = 0

Any suggestions?

How To Search Permitted and/or Blocked Numbers via the Web UI?

It seems like all searches are performed against the call log - even it the currently displayed page is NOT the call log. Seems it would be useful to be able to search by name or number against the Permitted and Blocked Numbers if the search is initiated from those pages instead of the Calls page. Is this possible? Can the header, where the search bar is located, "know" which page is currently displayed? Thanks

Caller Name in Top Permitted Callers on Dashboard Are Not Ideal...

I have noticed that in the Top Permitted table on the Dashboard, the name shown along with the count for a given number may not be as informative as it could be. Consider this and look at the number 425-xxx-9625:

CA_Desktop

It is shown with the name "Potential Spam" - which it originally was. But I have since allowed the number and added a real name (mine) so in the call log for that number you see:

CA_Call_Log

It would be good if the Top Permitted Callers table reflected the updated name.

Caller pressed: 000

I am now having some luck now with the voice messaging and pressing 0 to be permitted. Hurrah!

So far, my limited testing is from my LG V40 cell phone and my wife's Kyocera DuraXE flip phone. The V40 seems to work as intended/expected. However, every time I press 0 on the DuraXE, callattendant registers more than one 0 on the single key press. Last time was 3 of them, other times even more. I know this as on the console I see the following (which appears to come out of voicemail.py's voice_messaging_menu() function) right after self.modem.wait_for_keypress() is invoked:

Caller pressed: 000

When I look at modem.py's wait_for_keypress(), it looks like it should be ignoring any save the 1st digit:

if len(digit_list) > 0:
return True, digit_list[0]

But it seems that more than just one digit is being returned (and then being printed to the console). And if this is the case, the following tests of digit against a single character in voicemail.py's voice_messaging_menu() will not work as expected.

I do not know, but I suspect this has something to do with how the DuraXE sends DTMF. Perhaps this affects other phones as well? Anyone else see this?

Thanks

Problem trying to use Early 2.0

I think I have done things right. And I have configured the MQTT items to send caller id info.

But when a call comes in, CA crashes and I see this:

May 05 11:06:21 callattendant[6151]: > New call log entry #539
May 05 11:06:21 callattendant[6151]: ['WIRELESS CALLER',
May 05 11:06:21 callattendant[6151]:  'xxxxxxxxxx',
May 05 11:06:21 callattendant[6151]:  'Permitted',
May 05 11:06:21 callattendant[6151]:  'Mobile',
May 05 11:06:21 callattendant[6151]:  '05-May',
May 05 11:06:21 callattendant[6151]:  '11:06 AM',
May 05 11:06:21 callattendant[6151]:  '2024-05-05 11:06:21']
May 05 11:06:21 callattendant[6151]: RuntimeError('Working outside of application context.\n\nThis typically means that you attempted to use functionality that needed\nthe current application. To solve this, set up an application context\nwith app.app_context(). See the documentation for more information.')
May 05 11:06:21 callattendant[6151]: ** Error running callattendant
May 05 11:06:21 callattendant[6151]: Shutting down...
May 05 11:06:21 callattendant[6151]: -> Stopping modem
May 05 11:06:21 callattendant[6151]: Modem thread exiting
May 05 11:06:21 callattendant[6151]: -> Closing modem serial port
May 05 11:06:21 callattendant[6151]: -> Stopping voice mail
May 05 11:06:21 callattendant[6151]: Message Event triggered
May 05 11:06:21 callattendant[6151]: -> Releasing resources
May 05 11:06:21 callattendant[6151]: -> Stopping MQTT client
May 05 11:06:21 callattendant[6151]: Shutdown finished
May 05 11:06:21 systemd[1]: callattendant.service: Main process exited, code=exited, status=1/FAILURE

I have googled "python Working outside of application context" and most of what I see refers to Flask.

Does this ring any bells?

Thanks

Strange Results When Searching Call Log

Hi. We get a number of calls where the CID name is something like "Washington Call" and I wanted to see if these ever came from other states. So in the dashboard, on the call log page, I performed a name search on call. The results are strange:
Capture
As you can see, it says there are 77 rows returned, that rows 1-25 are being displayed, and that there are multiple pages in the search results. However, only 8 rows are shown. Clicking on the other pages give a result like this:
Capture3

So using a Sqlite DB Browser, I issued the query:
select * from calllog where name like '%call%'
and I get the following results:
Capture2
As you can see, the query here also claims 77 rows in the result. However, I can see all of them in the DB browser. Strange!

I checked the monitor on CA while performing this query from the dashboard. I saw nothing untoward occur - like an error.

This may prove difficult to reproduce. And it is strange indeed. But it is not a major problem (at least for me).

Thanks, as always...

Having problem enabling MQTT

I set:
STATUS_INDICATORS = "MQTT"

When I I found I had to add paho-mqtt but still got this error:

TypeError: init() missing 1 required positional argument: 'callback_api_version'

Not sure how to proceed. All works if I set:
STATUS_INDICATORS = "NULL"

RD02-D400 modem

Hi, I am trying to use a Conexant/Dell rd02-d400 with my callattendant.

It is detected and set as a "Conextant-based modem" :
Initializing Modem Opening serial port Looking for modem on /dev/ttyACM0 _send_and_read('AT','OK',5) '\r\n' 'OK\r\n' _send_and_read('ATI0','OK',5) '\r\n' '56000\r\n' '\r\n' 'OK\r\n' ******* Conextant-based modem detected ********** Serial port opened on /dev/ttyACM0 Initializing modem settings _send_and_read('ATZ','OK',5) '\r\n' 'OK\r\n' _send_and_read('ATV1','OK',5) 'ATV1\r\r\n' 'OK\r\n' _send_and_read('ATE0','OK',5) 'ATE0\r\r\n' 'OK\r\n' _send_and_read('AT-SCID=1;+VCID=1;-STE=3','OK',5) '\r\n' 'OK\r\n' _send_and_read('AT&W0','OK',5) '\r\n' 'OK\r\n' _send_and_read('AT&V','OK',5) '\r\n' 'ACTIVE PROFILE:\r\n' ('B1 E0 L2 M1 N0 Q0 T V1 W0 X4 Y0 &C1 &D2 &G0 &J0 &K3 &Q5 &R1 &S0 &T5 &X0 ' '&Y0\r\n') ('S00:000 S01:000 S02:043 S03:013 S04:010 S05:008 S06:003 S07:090 S08:001 ' 'S09:006\r\n') ('S10:014 S11:085 S12:050 S18:000 S25:005 S26:001 S36:007 S38:020 S46:138 ' 'S48:007\r\n') 'S95:000 \r\n' '\r\n' 'STORED PROFILE 0:\r\n' 'B1 E0 L2 M1 N0 Q0 T V1 W0 X4 Y0 &C1 &D2 &G0 &J0 &K3 &Q5 &R1 &S0 &T5 &X0 \r\n' ('S00:000 S02:043 S06:003 S07:090 S08:001 S09:006 S10:014 S11:085 S12:050 ' 'S18:000\r\n') 'S36:007 S40:104 S41:195 S46:138 S95:000 \r\n' '\r\n' 'STORED PROFILE 1:\r\n' 'B1 E1 L1 M1 N0 Q0 T V1 W0 X4 Y0 &C1 &D2 &G0 &J0 &K3 &Q5 &R1 &S0 &T5 &X0 \r\n' ('S00:000 S02:043 S06:003 S07:090 S08:001 S09:006 S10:014 S11:085 S12:050 ' 'S18:000\r\n') 'S36:007 S40:104 S41:195 S46:138 S95:000 \r\n' '\r\n' 'TELEPHONE NUMBERS:\r\n' '0= 1=\r\n' '2= 3=\r\n' '\r\n' 'OK\r\n' Modem initialized

I though everything was fine, but when I make an inbound call, the only output I get is :
RING RING LED blinking: 10 times

No phone number or anything else.

I just looked at the "modem.py" file and it seems that the conexant settings are specific to the Zoom 3095 modem. I suppose it could be the wrong config for my device, but I have no idea how to deal with that. Do you have any advice ?

Instalation

Know is a stupid question, but please, help...
How do you install this specific fork compared to original?
Thank you in advance

Not an issue, really. More like newbie questions...

Hello and thanks in advance for helping this newbie...

I am trying to do some basic testing so I can see how this might work for me. For this purpose, I am using an old Hayes Modem http://articles.yuikee.com.hk/technotes/POTS/accura288.html. I know it supports caller id. And it seems from what is noted in the reference page "it appears that most voice commands are simply not implemented". Rats!

For my simple needs, I really don't need/want anything beyond this:

  1. Incoming call with caller id info comes in

  2. The number and/or name from caller id info is checked

  3. If determined to be blocked, simply hang up on the call and wait for the next call

  4. If determined NOT to be blocked, simply let the phone ring and ring - at least until our telecom's voice mail answers

It seems like the modem's caller id support SHOULD be enough to get this done and I really am not sure that I need any real voice call support in the modem. Is this correct?

This modem has 2 RJ-11 ports. I have it set up with the line coming from my telecom's fiber modem goes into the line port and then the phone port is connected to all of the other extensions in my home. When an incoming call arrives, all of the phone extensions ring...

I have been able to force the app to directly open my modem's serial port file (without needless searching as it is always on /dev/ttyS2). And it seems like things are at least partially working after I changed this line in modem.py:

ENABLE_FORMATTED_CID = "AT+VCID=1"

to

ENABLE_FORMATTED_CID = "ATS0=2#CID=1"

and setting the following in the config file (as I am in the USA):

PHONE_DISPLAY_FORMAT = "###-###-####"
COUNTRY_CODE = "B5"
SCREENING_MODE = ("whitelist", "blacklist")
BLOCK_ENABLED = True
BLOCK_SERVICE = "NOMOROBO"
BLOCKED_ACTIONS = ("answer",)
SCREENED_ACTIONS = ("answer",)
PERMITTED_ACTIONS = ('ignore',)

I then started the app, went to the web interface, and added my cell phone's number (xxx-yyy-zzzz below) to the block list and tried to call. In the stdout, I see:

b'RING\r\n'
b'DATE = 0103\r\n'
b'TIME = 0953\r\n'
b'NMBR = xxxyyyzzzz\r\n'
b'NAME = WIRELESS CALLER\r\n'
> Queueing call xxxyyyzzzz for processing
Adding to caller queue:
{'DATE': '0103',
 'NAME': 'WIRELESS CALLER',
 'NMBR': 'xxxyyyzzzz',
 'TIME': '0953'}
Incoming call from xxxyyyzzzz
> Checking next-call-permitted
> Checking blacklist(s)
> New call log entry #1
['WIRELESS CALLER',
 'xxxyyyzzzz',
 'Blocked',
 '',
 '03-Jan',
 '09:53 AM',
 '2024-01-03 09:53:18']
--> xxxyyyzzzz Blocked:
> Going off hook...
b'RING\r\n'
b'RING\r\n'
>>> Lock acquired in pick-up()
_send_and_read('AT+FCLASS=8','OK',5)
b'\r\n'
b'ERROR\r\n'
>>> _read_response returned ERROR
'Error in pick_up: Failed to put modem into voice mode.'
>>> Lock released in pick-up()
Waiting for next call...

HOWEVER,

The phone kept ringing and ringing. It was not hung up as I'd hoped it would be.

Also, I note that my one caller id enabled handset does NOT show any caller id information. Without using this app, it normally does. So I wonder if this app is somehow eating this information and not passing it along? Is that expected? Is it a function on how I have wired the phone line cables (see above)?

Thanks very much for any insight you can give me. I feel that I am close to an acceptable "solution" here.

Happy new year!

Add the ability to update config file from within the web UI?

I have been so happy with my own CA installation, I have convinced some friends - who are also inundated with spam calls - to try it out on an old Android TV box that I have converted to run Armbian. Initial setup shows it is working and that is impressive!

However, these users are not very tech-saavy and the CA machine will run headless, connected by Wifi so they can get to the UI from their own web browsers. For 90% of things, I think that will be ok. And, in a pinch, I should be able to reach the box via ssh from one of their computers while I remote control it using Team Viewer for the remaining 10% - like clearing the call log in the database periodically and making config changes.

But most users might not have this capacity. I have already written on the subject of clearing the call log from the user interface... But I cannot help but wonder if there isn't some fairly straight forward way to change the config file from the user interface and restart CA? It is great that we can see/study the config file via the UI. But it would be great if the Settings page offered a button to edit the file's contents, save (after creating a backup), and re-start CA.

I fully realize that this is a loaded gun. And there should be warnings a-plenty. But it might bring at least simple changes into the reach of less technical users.

Thanks as always!

Missing thankyou_callback.wav file?

After a clean install of this, when I run callattendant I get complaints about this file not being found. I do not see it anywhere. Is this a problem? For now I have simply copied and renamed another .wav file to this name and no complaints any longer...

Thanks

Supplied app.cfg has errors

The supplied app.cfg has errors (see below). The diff which follows reflects the changes necessary to eliminate the errors. If app.cfg is intended to mirror the settings when no config file is present, then there may be other errors I haven't discovered yet.

pi@rpi3bplus:~/.callattendant $ callattendant --config=app.cfg
Command line options:
  --config=app.cfg
  --data-path=None
  --create-folder=False
The VOICE_MAIL_MESSAGE_FOLDER symlink is not present. Creating /home/pi/.local/lib/python3.9/site-packages/callattendant/userinterface/static/messages symlink
* BLOCKED_ACTIONS must include either 'answer' or 'ignore'
* SCREENED_ACTIONS must include either 'answer' or 'ignore'
* PERMITTED_ACTIONS must include either 'answer' or 'ignore'
ERROR: Configuration is invalid. Please check app.cfg
pi@rpi3bplus:~/.callattendant $
pi@rpi3bplus:~/.callattendant $ diff app.cfg debug.cfg
112c112
< BLOCKED_ACTIONS = ("greeting", "voice_mail")
---
> BLOCKED_ACTIONS = ("answer", "greeting", "voice_mail")
126c126
< SCREENED_ACTIONS = ("greeting", "record_message")
---
> SCREENED_ACTIONS = ("answer", "greeting", "record_message")
146c146
< PERMITTED_ACTIONS = ("greeting", "record_message")
---
> PERMITTED_ACTIONS = ("ignore",)

Paradoxically, a simple block listed call produces more audible "RINGS" than one that is screened.

I just added a 1st ring suppressor in line between my VOIP service RJ-11 and all the handsets in my home. I remain having a direct connection between the VOIP service RJ-11 and CA. So I have been doing some testing. And what I am finding is a bit surprising to me.

If a call comes from a number and ends up being screened (where SCREENED_ACTIONS = ("answer", "greeting", "voice_mail")), I hear no rings on any of my home handsets. This is just what I am seeking!

But if a call comes from the same number after it has been placed on the blocked list (where BLOCKED_ACTIONS = ("answer", )), I end up hearing a ring on at least one of my home handsets. And this is disappointing as I am trying to avoid that ring!

I have tested this a number of times - albeit always from the same calling number.

I find this rather paradoxical and hard to explain since it seems, from the console log, that CA does more work before going off hook (which should stop the ringing, no?) in the case of the screened call than the block listed one. In the case of the screened call, the blocking patterns have to be processed and this is not done/needed in the case of the blocked listed one. I am sure this is only a very short time but it IS there.

Here is the console log from the block listed call (see line 26):
log.txt

Here is the console log from the screened call (see line 27):
log2.txt

I have no idea why this is happening. But I would like to try and make it stop.

One thing I do notice in the block listed call log is that in my case - where BLOCKED_ACTIONS = ("answer", ) - I see CA performing what would seem to be some un-needed work before hanging up:

Sep 04 11:09:14 callattendant[3376]: _send_and_read('AT+FCLASS=8','OK',5)
Sep 04 11:09:14 callattendant[3376]: '\r\n'
Sep 04 11:09:14 callattendant[3376]: 'OK\r\n'
Sep 04 11:09:14 callattendant[3376]: _send_and_read('AT+VSD=128,0','OK',5)
Sep 04 11:09:14 callattendant[3376]: '\r\n'
Sep 04 11:09:14 callattendant[3376]: 'OK\r\n'
Sep 04 11:09:14 callattendant[3376]: _send_and_read('AT+VLS=1','OK',5)
Sep 04 11:09:14 callattendant[3376]: '\r\n'
Sep 04 11:09:14 callattendant[3376]: 'OK\r\n'

If I understand this, at least on my current setup, all that CA has to do is send ATH after going off hook (perhaps after some very short delay?).

I seriously doubt this has any impact on my current problem. But if this was not happening perhaps going off hook would happen more quickly and avoid the ring I am hearing.

Thanks for any suggestions...

Web UI Main Page - Why are screened calls included in the Permitted Counts at the bottom left?

Is anyone else confused by having screened calls - especially those where the caller does not do anything but hang up - included with the permitted count shown at the left/bottom of the page under the heading "Top Permitted Callers"?

Actually, I am surprised that there are only 2 categories here at the bottom when, almost everywhere else on the page ("Recent Calls" and "Calls Per Day"), 3 categories are used. It seems like there is enough room at the bottom to have 3 blocks "Top Permitted Callers", "Top Screened Callers", and "Top Blocked Callers".

Maybe it is just me???

Niggling Really - But it would be good to normalize column names in the database...

There are columns for phone number (unformatted) in 3 tables of the database: CallLog, WhiteList, BlackList. In the CallLog, it is called simply Number. In the others, it is called PhoneNo. While researching/characterizing another bug, this confused me. For the sake of clarity, consistent naming is a good thing.

A niggle that perhaps few would ever see/notice.

Thanks

Add shouldIanswer as screener

Hello all.
Based on the model proposed by Cloud_forge
emxsys/callattendant#146
I have been using this different screening service for some time, but suddenly it has stopped and is returning a "403 Forbidden". This service is servicing european numbers and is the reference for these countries.
Could any aof you, with better knowledge check what is going on with this?
Thank you in advance

Screened call - Press 0 or 1 not working

I am using a StarTech USB56KEMH2 modem on a Libre LePotato. Permitted and Blocked lists are working but a Screened call plays the greeting telling me to press either 1 or 0. Neither of these appears to work.

I have enabled debug but I'm not sure what to look for.

crashed.. garbled info in caller log

i didnt bother posting entire caller log.. just the last bit... it looks like the caller information got garbled.. static maybe? but callattendant couldnt handle it and exited.. maybe needs like a protection that if it gets garble it cant exit.. maybe be able to log it seperatly when its garbled.. i dunno

but here is the log

callattendant error log.txt

Regular expression list documentation problem

The following is what is shown at the top of the regular expression list page:

Edit the Block (blacklist) and Permit (whitelist) regular expressions here. Each line of text should have the format:
   <regex> [: <description>]
that is, a [regular expression](https://docs.python.org/3/library/re.html#regular-expression-syntax), **optionally followed by a colon** and a human-readable description of who is being black or whitelisted.

The problem with this is the part in bold. The code in webapp.py's stringlist2dict() explicitly splits the lines based up ": " - note the trailing white space:

line.split(': ', 1)

Without it, the regular expressions are not executed properly. I have discovered this via personal experience.

So this should actually be changed to something like:

optionally followed by a colon, a single white space, and a human-readable description of who is being black or whitelisted.

FYI

UI Problem Trying to Remove a Permitted Number From the Permitted List

Ok, running the very latest here...

I have a number that got added to the permitted list after the caller pressed zero and called back. At that time, there was no name in the caller id - it showed the number as the name as well. And the same number has called back perhaps 10 times.

I went to give that number/caller a "real" name. Rather than search the permitted list from that page, I simply clicked on the number in the main dashboard page. From there I clicked Change and then I clicked Remove from Permitted List since there was no way, it seemed, to update the Name at that point. I was going to re-add to the permitted list with the correct name after the Remove was complete.

Sadly, doing the Remove somehow has caused a problem. I have clicked it several times now and perhaps that contributed. But I end up, after clicking Remove, with the UI not changing at all to reflect the Remove. It usually allows me to re-add immediately. And if I go back to the Dashboard main page and come in again, everything looks/acts the same.

But I have looked in the database white list and the number is no longer in there at all. So at some point, the DB got cleaned. It is not in the black list. But it is in the call log 10 times.

I decided to try something similar with a call that was previously blocked - by a regex pattern. From the dashboard, I click the number. On the Viewing Caller page, there is a button offering me to remove from the block list. And clicking that gets me the same result as above. Checking the DB the number is, of course, not in the block list. When a call is blocked by a regex, the number is not added to the blacklist, I think. The UI thinks that because it was blocked, there should be an entry in the block list DB. But there isn't one.

I know this is not quite the result I get above. But my theory is that my first Remove did actually perform the remove from the white list. Now the two cases are essentially the same. The UI thinks that because a call is permitted or blocked that there is a record in the white/black list. In this case, presenting the Remove from button confuses everything.

I hope I am being clear here.

Thanks

This seems to reveal an issue with the UI.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.