How to set variables using the originate command

hello ! i am using asterisk 18, and i am trying to trigger calls using a python script and the “originate” command
i can achieve the initialization of the call with this
originate Local/{number}@{context} extension s@context
in the docs i see that i can set some variables to the channel

``v(var1) - A series of channel variables to set on the destination channel.

but i cant put the whole command with the vars together

ive tried
originate Local/{number}@{context} extension s@context --set CHANNEL(variable,phonenumber)=“222222” --set CHANNEL(variable,name)=“user”
originate Local/{number}@{context} extension s@context,1,SET(__USERNAME=johndoe),SET(__PHONENUMBER=1234567890)
originate Local/{number}@{context} extension s@context,customer_name=John Doe,call_id=12345

which dont work, i dont know if iam missing somehitng

Thanks

Most of the time, I use PHP for dealing with Asterisk AMI, especially the originate command. However, here is the Python version of a working script for using the originate command and setting variables.

import socket
import time

def originate_call(dest, exten, pbx="127.0.0.1", port=5038, timeout=30):
    try:
        with socket.create_connection((pbx, port), timeout) as sock:
            commands = [
                "Action: Login\r\n",
                "UserName: admin\r\n",
                "Secret: 123456\r\n\r\n",
                f"Action: Originate\r\n",
                f"Channel: SIP/{exten}\r\n",
                f"Exten: {dest}\r\n",
                "Context: outbound\r\n",
                "Priority: 1\r\n",
                f"CallerID: {dest}\r\n",
                "Variable: __id=your_variable_value\r\n",  # Replace with actual variable value
                "Async: yes\r\n\r\n",
                "Action: Logoff\r\n\r\n"
            ]

            for command in commands:
                sock.sendall(command.encode('utf-8'))

            time.sleep(1)
            response = sock.recv(128).decode('utf-8')
            print(response)

    except socket.error as e:
        print(f"Socket error: {e}")

# Usage
originate_call(dest="123456789", exten="100")

Thanks for your reply, i am not using AMI, i just want to call the command in the command line, the asterisk -rx

I guess you can’t pass variables if you the command line version, I need to double-check, but pretty quite sure.

I don’t see how you get, from

to any of

Whilst the documentation is garbled and fails to use name or variable, and I haven’t looked at the source, to see what it actually does, I would expect something like:

originate (Local/{number}@{context},exten,s,context,1,,v(phonenumber=222222^name=user)

The main uncertainty is how names and values are delimited, and whether the usage of ^ is correct. NB there is a double comma for the timeout. Some _s may be needed.

I suspect the ability to set variables from the dialplan is very new, so make sure you have a sufficiently recent version. However, it may turn out to be in all the currently supported versions.

I didn’t know the add variable feature through the CLI has been added in recent versions of Asterisk. I really know it was not available in the past. I will check the documentation.

1 Like

I managed to confuse CLI and dialplan app. The CLI one may still not handle variables.

1 Like

For me, the best way is using AMI Originate. It gives you more flexibility and can be triggered from the dial plan or external software.

1 Like

It’s possible the OP really was trying to use CLI, but you are not going to be able deduce the CLI syntax from the application syntax.

Yes, i dont want to setup a new project elsewhere just to add some context to my originate
Thanks david!

that might be my last resource

I like to write as little code as possible.

    commands = [
        "Action: Login",
        "UserName: admin",
        "Secret: 123456",
        f"Action: Originate",
        f"Channel: SIP/{exten}",
        f"Exten: {dest}",
        "Context: outbound",
        "Priority: 1",
        f"CallerID: {dest}",
        "Variable: __id=your_variable_value",  # Replace with actual variable value
        "Async: yes",
        "Action: Logoff",
    ]

    for command in commands:
        sock.sendall((command + "\r\n").encode())

Also I would get rid of the try-block. Let the full traceback be displayed on error: it will give you more info as to where the error is.

You are likely to get broken pipe errors logged with this, and, although fairly harmless in such cases, some people don’t like error messages.

Then do a try-clause that specifically checks for such errors, and takes appropriate action. Like marking the socket connection as closed and needing reopening.

The original code as written was logging them anyway, albeit in a less-than-useful form.

It is Asterisk that would suffer the broken pipe.

Well, I’m sure Asterisk is big enough to look after itself.

As others mentioned, it’s not supported directly through the CLI.
Here’s the documentation from the CLI when running the command without parameters.

*CLI> channel originate
  There are two ways to use this command. A call can be originated between a
channel and a specific application, or between a channel and an extension in
the dialplan. This is similar to call files or the manager originate action.
Calls originated with this command are given a timeout of 30 seconds.

Usage1: channel originate <tech/data> application <appname> [appdata]
  This will originate a call between the specified channel tech/data and the
given application. Arguments to the application are optional. If the given
arguments to the application include spaces, all of the arguments to the
application need to be placed in quotation marks.

Usage2: channel originate <tech/data> extension [exten@][context]
  This will originate a call between the specified channel tech/data and the
given extension. If no context is specified, the 'default' context will be
used. If no extension is given, the 's' extension will be used.

If you’d like to create calls, using minimal code, and not bothering with AMI, look in to how Asterisk call files are used. Basically you define your call in a file, move the file to /var/spool/asterisk/outgoing the name does not matter, just call it something unique each time. You can even plan calls this way, by giving the call file a create time in the future.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.