UCCX Callback script help

Hi Guys,
My first foray into IPCC based scripting and I've run into a few problems.
Firstly, what I'm trying to do, is allow a user to press a button during during the queue process, which then allows them to manually input their call back number.
Once an agent becomes available, the system calls the agent and the callback number and connects them..
I've attached the script that I'm working with, and the log file.
What I'm seeing is, I can get one call queued, and it works fine, the agent comes online, the system calls the agent prompts them to initiate the callback (press any key) and then connects them to the user.
When I have multiple callbacks in the queue I get the "Narky Lady" informing me we have system problems. This happens to all the queued callbacks.
The second part is I'm getting "Event queue time exceeded" and the call is being dropped out of the queue after the callback has been queued.
I'm running CUCM 7.0.1.11000-2 & UCCX 7.0(1)_Build168
Any help would be appreciated, or if someone could point me to a working example?
Thanks

There are several items that could be causing the issue. I'm assuming that the Place Call step is calling a route point and ultimately a script that is placing the call in queue.
How many sessions do you have available for this second queue application?
Prior to your Place Call step, you need to dequeue the call and terminate the original call leg.
Remove the Set Contact Info step from the Wait For Agent section.
I'm not sure why you have the Play Prompt after the call has been connected. I would play the caller in the Get Digit String under the Wait For Agent section.
Those changes should get this to work as long as my original assumptions are correct.
You may want to consider some additional factors in your next revision of this script:
-What if an agent hangs up on the queue callback request? You can use the On Exception Goto and catch the ContactInactiveException to work around this issue.
-You will need to handle the busy, invalid, and unsuccessful nodes in the Call Redirect step. I would suggest creating a loop and having it requeue the call again up to 3 times.
-When you get the callback number, make sure to get 7 or 10 digits depending on your requirements. You amy also need to prepend a 1 to those numbers outside of your local area codes.
-This script may be strange for agents to handle because they don't have the name of the caller. You could have the caller record their name and play it in the callback loop with the phone number.

Similar Messages

  • UCCX Callback implementation timeout problem

    I am working on an implementation of the "Callback" function for queued callers based on the Cisco sample scripts
    BaseLineAdvQueuing and BaseLineMesageCallback.   The function works correctly.  If my agents are all in Not Ready state and callers select to leave a callback number and message then their "callback" calls are queued successfully.  When an agent is made "Ready" the callback calls are delivered in the correct order and the callbacks are processed successfully.  My problem is that the "Callback" calls time out and disappear from the queue after about 30 minuted.  If an agent becomes ready after 40 minutes there are no calls delivered to them.  I have tracked this via the Real Time Reports which show active sessions for the queued Callback calls.  These disappear from the Real Time Report after 30 mins.   Is there a way to extend this timeout?.
    Regards,
    David

    Have you checked your MIVR logs for the WFMaxExecutedStepsExceededException error?
    The logic in the Advanced Queuing script is such that it loops the Get Digit String step once ever 6 seconds.  Even if I didn't consider all the steps that your callers go through before getting there, this small section will execute 1,000 steps in 50 minutes.  Subtract off your steps above and this could easily be 20 or 30 minutes.
    The Callback script is less likely the culprit as it executes 3 steps every 30 seconds, which is 166 minutes or 2.7 hours.
    My guess is that both of you are hitting the max steps on your main script.  Check your MIVR logs to know for sure.  Post your script and I'll review it.
    Also, what is your UCCX System Parameter for Max Steps set to?
    Anthony Holloway
    Please use the star ratings to help drive great content to the top of searches.

  • Callback script - Just last Callback number works!

    Hi,
    I have created a Callback script, the issue is if there is one CallBack number, it works fine, if there are multiple Callback Number, as soon as Agent is ready,
    his Phone rings but when he picks it up, there is fast busy, however, the last Call back number works fine ( for example if there are three Callback numbers left, Agent Phones ring three times, but only the last one works.) - when there is fast busy it seems that system brings up CTI ports but with no Callback Number.
    See attached.
    Thanks,
    Hamed

    Hi Neal,
    Thank you for your help. I changed the extension from .aef to .txt, hope if you can open it.
    See attached.
    Hamed

  • Can Stratus pass an app id to the callback script?

    Never mind, I looked at this the wrong way.
    My question was: can Stratus pass my callback script some
    kind of application id so I can distinguish which AS3 app is making
    the request in case I'd have more than one app.
    Obviously that's something I can control myself in the
    WebServiceUrl setting.

    Just print it out as a Javascript variable.

  • Gallery script help, please

    Gallery script help, please
    Hello,
    I'm new to actionscript in general, I do know a little...
    I foung a gallery script, modified many things, the images
    open fine, everything is working, but here's the thing:
    the gallery is in 3 sections, red, blue and yellow.
    I would like to know how, what, and where to put a script so
    that if a "the small red image #1" is clicked, I can load any sort
    of a movie on top of the "the BIG red image #1" or #2 or 3 and so
    on...same goes for the blue and yellow...
    If I figured things correctly on my own...the small thumbnail
    images of the gallery are not buttons, that's why I can't attach a
    movie (let's say) to them...but it is all written in script, using
    the horizontal and vertical position of the mouse to open the large
    images of the gallery...
    So, I don't know how to figure things out, to attach a
    specific movie to a specific thumbnail...
    p.s.: I think the script that controls the gallery is in
    symbol 120
    I really would appreciate the help
    Merry Christmas in advance to everyone
    Sandra
    here are all the files...
    http://www.gentro.ca/sandra_test.zip

    There's a great tutorial on kirupa...
    click
    here for link

  • Firefox not responding, freezes, sometimes responds after a few minutes, other times a pop-up appears asking if I want to stop script - help please

    firefox not responding, freezes, sometimes responds after a few minutes, other times a pop-up appears asking if I want to stop script - help please

    Start Firefox in [[Safe Mode]] to check if one of the add-ons is causing the problem (switch to the DEFAULT theme: Tools > Add-ons > Themes).
    * Don't make any changes on the Safe mode start window.
    See:
    * [[Troubleshooting extensions and themes]]
    * [[Troubleshooting plugins]]
    If it does work in Safe-mode then disable all extensions and then try to find which is causing it by enabling one at a time until the problem reappears.
    * Use "Disable all add-ons" on the [[Safe mode]] start window to disable all extensions.
    * Close and restart Firefox after each change via "File > Exit" (Mac: "Firefox > Quit"; Linux: "File > Quit")

  • UCCX Scripting help

    I've got very little experience with scripting in the UCCX 9.1.2 and have a customer I've recently upgraded that would like to add a variable to an existing script. 
    They need to add the ability to steer the caller to an inclement weather message should the need arise.  I know I could do this by creating an if then statement in the work hours section that basically says if the number of logged in agents during normal work hours equals 0 send it to a trigger that is tied to a mailbox that has a message saying no one is available.  I could then use the alternate greeting to advise of inclement weather and let the end user manage that greeting.
    My issue is that I dont know scripting well enough to input the correct syntax in the if then expression. 
    Is there anyone that could help me with this?  The script is attached. 
    If there is an easier way that I'm unaware of to accomplish this, I'm open to any suggestions. 
    Thanks in advance for any help and for taking the time to look at this!!            

    Hi there,
    You should move this post over to the Contact Center sub forum
    https://supportforums.cisco.com/community/netpro/collaboration-voice-video/contact-center?view=discussions&start=0
    Lots of excellent people over there who can help
    Cheers!
    Rob
    "Seek it out and ye shall find  " 
    - OneRepublic

  • UCCX Script help

    What the script trys to accomplish,  & I cant seem to figure out.
    Someone calls in if their ANI is recognized (check against a database of numbers for authentication) - send them to another piece of the script.
    Seems easy but I do not know how to:
    1 automatically confirm the digits I.E. compare string from database to ANI
    2. Once confirmed automatically send them to the second piece of the script, using location info from database.
    Ex. So if I call into the script it knows my cell phone and recognized me and knows Im calling in from the new jersey (because thats in the database) and sends me to the new jersey label in the script.
    Database has phonenumbers and location info in it. Can this be done? any insight would help. Im running ccm 7 and UCCX 7.
    Julius

    Sounds pretty straight forward.
    Create labels for each point in the script you want each location to jump to.
    Add a Get Call Contact Info step and assign the calling number to a variable.
    Do a DB Get into the database to search for the ANI, assign the location to another variable if it's matched
    Do a Switch on the location and for each location in the switch, put a GoTo the appropriate label.
    Chuck the script in reactive mode and put a call through it to make sure your database has numbers formatted correctly matching what is getting presented as the ANI from the gateways.
    Hope that helps.
    Cheers,
    Nathan

  • UCCX Conferencing in third call? Scripting help needed

    All,
    I've got a customer requirement where they want to be able to place a call into the contact centre, give the contact centre the digits to dial and have the contact centre place the call on their behalf.  I've got no trouble with that bit.
    The next requirement is that the call placed is recorded, even if the calls in are not from cisco phones (i.e. mobiles).  We have a redbox recorder that does the recording and in order for it to commence a recording session, it needs to see a setup message through CM to check that it's an extension that is to be recorded.
    For example, I use an IP phone that IS being monitored to make a call.  The Redbox sees the setup and will record the call flow.
    I use an IP phone that is NOT being monitored to make a call.  The Redbox sees the setup and will not record the call.
    In order to get calls recorded from the contact centre, I'm thinking of conferencing in a third phone that Redbox is set to record and have it auto answer on silent, but I can't figure out how to get the three calls conferenced together to keep the call flow recorded.
    Any thoughts on how to achieve this?  Or has anyone else out there used another method?
    All help greatly appreciated!
    LH
    #15331

    There is no mechanism within CCX that allows you to initiate a conference or join two contacts together. Your only options will be to transfer the triggerin
    g contact to another destination with a Call Redirect or Call Consult Transfer.  If you create a second contact and use a Place Call step, you can interact with both contacts in the script but never join them together.

  • UCCX New implementation help

    Hi Everyone,
    I am fairly new to the UCCX environment i need help in creating scripts.
    We are currenetly implementing a project for be6000 with UCCX.
    Things i have done:
    1. I have already created few users in the CUCM
    2. I have completed the CUCM and UCCX integration
    3. I have already gone through the UCCS admin guide which is not helpful and does not make sense to me as newbie.
    4. uploaded the prompts to UCCX.
    I would like to know exact detailed steps of creating agents and assigning skills to them creating triggers.
    Also need to create a simple script which works as follows:
    incoming call-->welcom msg and language selection-->press1 for sales 2 for support--> play a wait message-->transfer the call to the agent or if agent are busy or not available just send the call to the voicemail on cutomers will.
    It may seem quite simple to you but difficult for a newbie.
    If you people can help me out i would need step by step procedure for creating scripts and requested things as i cannot make out from the admin guide.
    If any script similar my scenario is available on UCCX where in i can just change the prompts would be great.

    Hi all,
    with all due respect, I disagree. There are a lot of good engineers, both Cisco employees and folks working for external companies.
    This forum is not "dry", but if you come here absolutely unprepared with a question like "here's a list of requirements to build a contact center from scratch, give me a step-by-step explanantion", then sorry, we are not going to help you. Why, you might ask. Simple: it would be too much to be explained. A contact center is an advanced topic.
    I cannot accept arguments like "my employer won't pay for the UCCX training" or "I am usually doing something else but no one would accept this task so I got it, I don't really care about it, I just want to finish it and forget it as soon as possible". If you want to do something right, then learn it. Yes, even in your spare time.
    G.

  • Need Scripting Help PLEASE

    Hi I have very little experience with UCCx and even less experience with scripts and I'm having a problem with my main_cs_001.aef script. I've attached the callflow for this scipt. Basically when I manually close my call center for let's say Inclement Weather, I dial the main number and enter an 8 which prompts me for a password, which in turn allows me to make a selection based on the reason I want to close the call center. The options are as follows
                        1. Techn outage
                        2.  Holidays
                        3.  Inclement Weather
                        4.  Emergency
                        0. Default Greeting    
    This is where the problem happens when I make choose an option in this case option 3. Callers hear what I want them to hear but I cannot reset to the default greeting the next day.  So the callers still hear the Inclement Weather greeting and no calls go thru. I've looked at the script  and discovered that an .xml file called aaprompt.xml holds the value of the choice made. If I edit aaprompt.xml and enter a value of 0, then callers are able to call in.  How can I make it such that the value of aaprompt.xml is set back to 0 after a certain time?  I was thinking a 24hr period would be a good time to have that reset. I've included the script, the flowchart, and the .xml file. Thank you in advance for any help you can provide.
    james

    Hi I have very little experience with UCCx and even less experience with scripts and I'm having a problem with my main_cs_001.aef script. I've attached the callflow for this scipt. Basically when I manually close my call center for let's say Inclement Weather, I dial the main number and enter an 8 which prompts me for a password, which in turn allows me to make a selection based on the reason I want to close the call center. The options are as follows
                        1. Techn outage
                        2.  Holidays
                        3.  Inclement Weather
                        4.  Emergency
                        0. Default Greeting    
    This is where the problem happens when I make choose an option in this case option 3. Callers hear what I want them to hear but I cannot reset to the default greeting the next day.  So the callers still hear the Inclement Weather greeting and no calls go thru. I've looked at the script  and discovered that an .xml file called aaprompt.xml holds the value of the choice made. If I edit aaprompt.xml and enter a value of 0, then callers are able to call in.  How can I make it such that the value of aaprompt.xml is set back to 0 after a certain time?  I was thinking a 24hr period would be a good time to have that reset. I've included the script, the flowchart, and the .xml file. Thank you in advance for any help you can provide.
    james

  • UCCX "Whisper" tone help

    Have 2-800's coming in to one group and they have to answer the phone differently for each number.  Wanted to do a whisper tone prior to call being dropped in?  IF not how do I change the caller ID the UCCX IVR ports send so it would say "Noah's" or "Einstein Bros", TAC wasn't able to help me with this....
    Elie

    Hi Elie
    If the agents do not pay attention to the CAD they can use the IP Phone Agent, there is a way to keep the Enterprise Data field in the main screen of the IP Phone Agent service so when they look at the screen they will be able to see the Enterprise Data that says Noah's or Einstein. It would not be necesary to create different CSQs, but as Aaron said before you will need to create two applications, one called Noah and the other called Einstein, both of them can use the same script and send the call to the same CSQ.
    So you will transform the 800 Noah to the trigger of the Noah application and the other 800 to the Einstein trigger, after that in the script you can use the Get Call Contact Info where you take the parameter "called number" and store the value in a variable, after that with an "if" statement you can check if the called number of the Get Call Contact Info is equal to the Noah application trigger then you set a variable called "number800" to Noah and if the called number of the Get Call Contact info is equal to the Einstein application trigger the you set the variable "number800" to Einstein, after that you push this variable to the Enterprise Data Field.
    For you to show in the main screen the Enterprise Data you need to create an Application User named telecaster an associate the agent's IP phone to it, also this Application User need to be a member of the Standard CTI Enable.
    Gabriel.

  • If/then checkbox script help in Adobe Acrobat Form...

    If have an order form that has two different pricing fields (regular price per item & subscription price per item) for each line item and then a quantity and then a total field. Lastly, there is a checkbox on the form that indicate if they are signing up for a monthly subscription.
    What I am trying to do is create a script that totals each line by the regular price multipled by the quantity or subscription price by quantity if the subscription check box is checked ("Yes"). So far, I've tried several scripts I found in the forum but no luck at all.
    The check box is near the billing fields toward the bottom so all the line items appear first in the top section of the form. So, an individual would fill out each line and the calculations would just total each row (reg price * qty) as you go down the form...then when you check the subscription box all the line totals would change to reflect the subscription pricing for each row (which can be different). Just need help with one row and I can duplicate for each row.....
    Here is what I have that does NOT work yet.....:
    (function () {
    if (this.getField("sub").value==="Yes") {
         var b1 = this.getField("Price1b");
         var c1 = this.getField("Qty1");
         var d1 = this.getField("Price1");
         event.value = b1.value * c1.value;
    } else event.value = d1.value * c1.value;

    One last strange thing is that when I then do the "Value is the Sum simple total of the row total fields (where the script is) and then click the check mark for subscription, the number in the grand total field shows the opposite value as the row total field (so when you click the subscription check box, the row total goes to the subscription price and the grand total field then shows the full price)....can't figure out why that happens......?
    Any ideas?

  • PowerShell Scripting help to combine two scripts

    I have a script that helps automate virtual server builds.  The script creates a specification document which is used to perform the actual builds.
    # Spec-And-Build.ps1 - Loops through a directory and performs an
    # end to end specification generation and build on each request in that directory
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [string]$RequestDir,
        [Parameter(Mandatory=$true)]
        [string]$SpecDir,
        [Parameter(Mandatory=$false)]
        [pscredential]$Credential_CPR,
        [Parameter(Mandatory=$false)]
        [pscredential]$Credential_VDC,
        [Parameter(Mandatory=$false)]
        [pscredential]$Credential_Admin
    if (!$Credential_CPR) {
        $Credential_CPR = Get-Credential -Message "CPR Domain Credentials."
        if (!$Credential_CPR.UserName.ToUpper().StartsWith("CPR\")) {
            $Credential_CPR = New-Object pscredential(
                ("CPR\" + $Credential_CPR.UserName), $Credential_CPR.Password)
    if (!$Credential_VDC) {
        $Credential_VDC = Get-Credential -Message "VDC Domain Credentials."
        if (!$Credential_VDC.UserName.ToUpper().StartsWith("VDC\")) {
            $Credential_VDC = New-Object pscredential( `
                ("VDC\" + $Credential_VDC.UserName), $Credential_VDC.Password)
    if (!$Credential_Admin) {
        $Credential_Admin = Get-Credential -UserName "Administrator or root" `
            -Message "Enter the Administrator or root password for the new VM. The user name here will be ignored"
    .\Gen-VMSpec-Many.ps1 -RequestDir $RequestDir -SpecDir $SpecDir -Credential_VDC $Credential_VDC
    $caption = "Continue Build"
    $message = "Please validate the generated specification files in $SpecDir - Then click Continue to start build"
    $opContinue = new-Object System.Management.Automation.Host.ChoiceDescription "&Continue","help"
    $opAbort = new-Object System.Management.Automation.Host.ChoiceDescription "&Abort","help"
    $choices = [System.Management.Automation.Host.ChoiceDescription[]]($opContinue,$opAbort)
    $answer = $host.ui.PromptForChoice($caption,$message,$choices,0)
    if ($answer -eq 0) {
        .\Build-VM-Many.ps1 -SpecDir $SpecDir -Credential_CPR $Credential_CPR -Credential_VDC $Credential_VDC -Credential_Admin $Credential_Admin
    } else {
        Write-Host "Build step aborted, run Build-VM-Many.ps1 manually to continue."
    This script works well.  Now I need to add a section that adds Active Directory groups to the built servers from the spec document.  I found this script which also works well:
    # Create local group on the local or a remote computer 
    Write-Host -foregroundcolor Yellow 'Admin Privileges Required!' 
    $computerName = Read-Host 'Enter computer name or press <Enter> for localhost' 
    $localGroupName = Read-Host 'Enter local group name' 
    $description = Read-Host 'Enter description for new local group' 
    if ($computerName -eq "") {$computerName = "$env:computername"} 
    if([ADSI]::Exists("WinNT://$computerName,computer")) { 
        $computer = [ADSI]"WinNT://$computerName,computer" 
        $localGroup = $computer.Create("group",$localGroupName) 
        $localGroup.SetInfo() 
        $localGroup.description = [string]$description 
        $localGroup.SetInfo() 
    My question is, how do I make one script from the two?  I am very new to PowerShell scripting.

    Here are the instructions on how to use PowerShell:
    http://technet.microsoft.com/en-us/scriptcenter/dd793612.aspx
    Your question is vague and is asking for someone to do this for you.  It is better if you do it yourself and post back with specific questions.
    In the end you have to write and debug the scripts. We will not do this for you but we will answer questions.
    ¯\_(ツ)_/¯

  • Saveas Scripting help request

    I am trying to piece together a maro that will initially resize an image and save it with a different suffix at different size increments. I found within the cs5 scripts folder the macro 'Fit Image.jsx' that would allow me to resize correctly but am lost on how to add in the subsequent save steps and additional resize and saves. I would like to have it save the image with 5 different file sizes and suffixes (400x400 '-2' suffix, 250x250 '-2T', 150x150 '-1', 100x100 '-0', and 50x50 '-2S'). I found some information on the saveas http://forums.adobe.com/message/2652204 but have no experience with javascript. I have some understanding of VBA and believe a loop could be used but haven't the slightest idea how to set this up. Is there anyone out there that could help walk me through this and lend me a hand?
    ---Below contains the 'Fit Image.jsx' file that I found---
    // c2008 Adobe Systems, Inc. All rights reserved.
    // Written by Ed Rose
    // based on the ADM Fit Image by Charles A. McBrian from 1997
    // edited by Mike Hale added option to avoid resize on images already smaller than target size
    @@@BUILDINFO@@@ Fit Image.jsx 1.0.0.21
    /* Special properties for a JavaScript to enable it to behave like an automation plug-in, the variable name must be exactly
       as the following example and the variables must be defined in the top 1000 characters of the file
    // BEGIN__HARVEST_EXCEPTION_ZSTRING
    <javascriptresource>
    <name>$$$/JavaScripts/FitImage/Name=Fit Image...</name>
    <menu>automate</menu>
    <enableinfo>true</enableinfo>
    <eventid>3caa3434-cb67-11d1-bc43-0060b0a13dc4</eventid>
    <terminology><![CDATA[<< /Version 1
                             /Events <<
                              /3caa3434-cb67-11d1-bc43-0060b0a13dc4 [($$$/AdobePlugin/FitImage/Name=Fit Image) /imageReference <<
                               /width [($$$/AdobePlugin/FitImage/Width=width) /pixelsUnit]
                               /height [($$$/AdobePlugin/FitImage/Height=height) /pixelsUnit]
                               /limit [($$$/AdobePlugin/FitImage/limit=Don't Enlarge) /boolean]
                              >>]
                             >>
                          >> ]]></terminology>
    </javascriptresource>
    // END__HARVEST_EXCEPTION_ZSTRING
    // enable double clicking from the Macintosh Finder or the Windows Explorer
    #target photoshop
    // debug level: 0-2 (0:disable, 1:break on error, 2:break at beginning)
    // $.level = 2;
    // debugger; // launch debugger on next line
    // on localized builds we pull the $$$/Strings from a .dat file, see documentation for more details
    $.localize = true;
    var isCancelled = true; // assume cancelled until actual resize occurs
    // the main routine
    // the FitImage object does most of the work
    try {
        // create our default params
        var sizeInfo = new SizeInfo();
        GlobalVariables();
        CheckVersion();
        var gIP = new FitImage();
        if ( DialogModes.ALL == app.playbackDisplayDialogs ) {
            gIP.CreateDialog();
            gIP.RunDialog();
        else {
            gIP.InitVariables();
            ResizeTheImage(sizeInfo.width.value, sizeInfo.height.value);
        if (!isCancelled) {
            SaveOffParameters(sizeInfo);
    // Lot's of things can go wrong
    // Give a generic alert and see if they want the details
    catch( e ) {
        if ( DialogModes.NO != app.playbackDisplayDialogs ) {
            alert( e + " : " + e.line );
    // restore the dialog modes
    app.displayDialogs = gSaveDialogMode;
    isCancelled ? 'cancel' : undefined;
    function ResizeTheImage(width, height) {
        var oldPref = app.preferences.rulerUnits;
        var docWidth;
        var docHeight;
        var docRatio;
        var newWidth;
        var newHeight;
        var resolution = app.activeDocument.resolution;
        var limit = sizeInfo.limit;
        app.preferences.rulerUnits = Units.PIXELS; // save old preferences
        // original width, height
        docWidth = (1.0 * app.activeDocument.width * resolution) / 72.0; // decimal inches assuming 72 dpi (used in docRatio)
        docHeight = (1.0 * app.activeDocument.height * resolution) / 72.0; // ditto
        if (docWidth < 1.0 || docHeight < 1.0)
            return true; // error
        if (width < 1 || height < 1)
            return true; // error
        if ( limit && ( docWidth <= width && docHeight <= height ) ){
            app.preferences.rulerUnits = oldPref; // restore old prefs
            isCancelled = false; // if get here, definitely executed
            return false; // no error
        docRatio = docWidth / docHeight; // decimal ratio of original width/height
        newWidth = width;
        newHeight = ((1.0 * width) / docRatio); // decimal calc
        if (newHeight > height) {
            newWidth = docRatio * height; // decimal calc
            newHeight = height;
        // resize the image using a good conversion method while keeping the pixel resolution
        // and the aspect ratio the same
        app.activeDocument.resizeImage(newWidth, newHeight, resolution, ResampleMethod.BICUBIC);
        app.preferences.rulerUnits = oldPref; // restore old prefs
        isCancelled = false; // if get here, definitely executed
        return false; // no error
    // created in
    function SaveOffParameters(sizeInfo) {
        // save off our last run parameters
        var d = objectToDescriptor(sizeInfo, strMessage);
        app.putCustomOptions("3caa3434-cb67-11d1-bc43-0060b0a13dc4", d);
        app.playbackDisplayDialogs = DialogModes.ALL;
        // save off another copy so Photoshop can track them corectly
        var dd = objectToDescriptor(sizeInfo, strMessage);
        app.playbackParameters = dd;
    function GlobalVariables() {
        // a version for possible expansion issues
        gVersion = 1.1;
        gMaxResize = 300000;
        // remember the dialog modes
        gSaveDialogMode = app.displayDialogs;
        app.displayDialogs = DialogModes.NO;
        gInAlert = false;
        // all the strings that need to be localized
        strTitle = localize( "$$$/JavaScript/FitImage/Title=Fit Image" );
        strConstrainWithin = localize( "$$$/JavaScript/FitImage/ConstrainWithin=Constrain Within" );
        strTextWidth = localize("$$$/JavaScripts/FitImage/Width=&Width:");
        strTextHeight = localize("$$$/JavaScripts/FitImage/Height=&Height:");
        strTextPixels = localize("$$$/JavaScripts/FitImage/Pixels=pixels");
        strButtonOK = localize("$$$/JavaScripts/FitImage/OK=OK");
        strButtonCancel = localize("$$$/JavaScripts/FitImage/Cancel=Cancel");
        strTextSorry = localize("$$$/JavaScripts/FitImage/Sorry=Sorry, Dialog failed");
        strTextInvalidType = localize("$$$/JavaScripts/FitImage/InvalidType=Invalid numeric value");
        strTextInvalidNum = localize("$$$/JavaScripts/FitImage/InvalidNum=A number between 1 and 300000 is required. Closest value inserted.");
        strTextNeedFile = localize("$$$/JavaScripts/FitImage/NeedFile=You must have a file selected before using Fit Image");
        strMessage = localize("$$$/JavaScripts/FitImage/Message=Fit Image action settings");
        strMustUse = localize( "$$$/JavaScripts/ImageProcessor/MustUse=You must use Photoshop CS 2 or later to run this script!" );
        strLimitResize = localize("$$$/JavaScripts/FitImage/Limit=Don^}t Enlarge");
    // the main class
    function FitImage() {
        this.CreateDialog = function() {
            // I will keep most of the important dialog items at the same level
            // and use auto layout
            // use overriding group so OK/Cancel buttons placed to right of panel
            var res =
                "dialog { \
                    pAndB: Group { orientation: 'row', \
                        info: Panel { orientation: 'column', borderStyle: 'sunken', \
                            text: '" + strConstrainWithin +"', \
                            w: Group { orientation: 'row', alignment: 'right',\
                                s: StaticText { text:'" + strTextWidth +"' }, \
                                e: EditText { preferredSize: [70, 20] }, \
                                p: StaticText { text:'" + strTextPixels + "'} \
                            h: Group { orientation: 'row', alignment: 'right', \
                                s: StaticText { text:'" + strTextHeight + "' }, \
                                e: EditText { preferredSize: [70, 20] }, \
                                p: StaticText { text:'" + strTextPixels + "'} \
                            l: Group { orientation: 'row', alignment: 'left', \
                                    c:Checkbox { text: '" + strLimitResize + "', value: false }, \
                        buttons: Group { orientation: 'column', alignment: 'top',  \
                            okBtn: Button { text:'" + strButtonOK +"', properties:{name:'ok'} }, \
                            cancelBtn: Button { text:'" + strButtonCancel + "', properties:{name:'cancel'} } \
            // the following, when placed after e: in w and h doesn't show up
            // this seems to be OK since px is put inside the dialog box
            //p: StaticText { text:'" + strTextPixels + "'}
            // create the main dialog window, this holds all our data
            this.dlgMain = new Window(res,strTitle);
            // create a shortcut for easier typing
            var d = this.dlgMain;
            // match our dialog background color to the host application
            d.graphics.backgroundColor = d.graphics.newBrush (d.graphics.BrushType.THEME_COLOR, "appDialogBackground");
            d.defaultElement = d.pAndB.buttons.okBtn;
            d.cancelElement = d.pAndB.buttons.cancelBtn;
        } // end of CreateDialog
        // initialize variables of dialog
        this.InitVariables = function() {
            var oldPref = app.preferences.rulerUnits;
            app.preferences.rulerUnits = Units.PIXELS;
            // look for last used params via Photoshop registry, getCustomOptions will throw if none exist
            try {
                var desc = app.getCustomOptions("3caa3434-cb67-11d1-bc43-0060b0a13dc4");
                descriptorToObject(sizeInfo, desc, strMessage);
            catch(e) {
                // it's ok if we don't have any options, continue with defaults
            // see if I am getting descriptor parameters
            var fromAction = !!app.playbackParameters.count;
            if( fromAction ){
                // reset sizeInfo to defaults
                SizeInfo = new SizeInfo();
                // set the playback options to sizeInfo
                descriptorToObject(sizeInfo, app.playbackParameters, strMessage);
            // make sure got parameters before this
            if (app.documents.length <= 0) // count of documents viewed
                if ( DialogModes.NO != app.playbackDisplayDialogs ) {
                    alert(strTextNeedFile); // only put up dialog if permitted
                app.preferences.rulerUnits = oldPref;
                return false; // if no docs, always return
            var w = app.activeDocument.width;
            var h = app.activeDocument.height;
            var l = true;
            if (sizeInfo.width.value == 0) {
                sizeInfo.width = w;
            else {
                w = sizeInfo.width;
            if (sizeInfo.height.value == 0) {
                sizeInfo.height = h;
            else {
                h = sizeInfo.height;
            app.preferences.rulerUnits = oldPref;
            if ( DialogModes.ALL == app.playbackDisplayDialogs ) {
                var d = this.dlgMain;
                d.ip = this;
                d.pAndB.info.w.e.text = Number(w);
                d.pAndB.info.h.e.text = Number(h);
                d.pAndB.info.l.c.value = sizeInfo.limit;
            return true;
        // routine for running the dialog and it's interactions
        this.RunDialog = function () {
            var d = this.dlgMain;
            // in case hit cancel button, don't close
            d.pAndB.buttons.cancelBtn.onClick = function() {
                var dToCancel = FindDialog( this );
                dToCancel.close( false );
            // nothing for now
            d.onShow = function() {
            // do not allow anything except for numbers 0-9
            d.pAndB.info.w.e.addEventListener ('keydown', NumericEditKeyboardHandler);
            // do not allow anything except for numbers 0-9
            d.pAndB.info.h.e.addEventListener ('keydown', NumericEditKeyboardHandler);
            // hit OK, do resize
            d.pAndB.buttons.okBtn.onClick = function () {
                if (gInAlert == true) {
                    gInAlert = false;
                    return;
                var wText = d.pAndB.info.w.e.text;
                var hText = d.pAndB.info.h.e.text;
                var lValue = d.pAndB.info.l.c.value;
                var w = Number(wText);
                var h = Number(hText);
                sizeInfo.limit = Boolean(lValue);
                var inputErr = false;
                if ( isNaN( w ) || isNaN( h ) ) {
                    if ( DialogModes.NO != app.playbackDisplayDialogs ) {
                        alert( strTextInvalidType );
                    if (isNaN( w )) {
                        sizeInfo.width = new UnitValue( 1, "px" );
                        d.pAndB.info.w.e.text = 1;
                    } else {
                        sizeInfo.height = new UnitValue( 1, "px" );
                        d.pAndB.info.h.e.text = 1;
                        return false;
                else if (w < 1 || w > gMaxResize || h < 1 || h > gMaxResize) {
                    if ( DialogModes.NO != app.playbackDisplayDialogs ) {
                        gInAlert = true;
                        alert( strTextInvalidNum );
                if ( w < 1) {
                    inputErr = true;
                    sizeInfo.width = new UnitValue( 1, "px" );
                    d.pAndB.info.w.e.text = 1;
                if ( w > gMaxResize) {
                    inputErr = true;
                    sizeInfo.width = new UnitValue( gMaxResize, "px" );
                    d.pAndB.info.w.e.text = gMaxResize;
                if ( h < 1) {
                    inputErr = true;
                    sizeInfo.height = new UnitValue( 1, "px" );
                    d.pAndB.info.h.e.text = 1;
                if ( h > gMaxResize) {
                    inputErr = true;
                    sizeInfo.height = new UnitValue( gMaxResize, "px" );
                    d.pAndB.info.h.e.text = gMaxResize;
                if (inputErr == false)  {
                    sizeInfo.width = new UnitValue( w, "px" );
                    sizeInfo.height = new UnitValue( h, "px" );
                    if (ResizeTheImage(w, h)) { // the whole point
                        // error, input or output size too small
                    d.close(true);
                return;
            if (!this.InitVariables())
                return true; // handled it
            // give the hosting app the focus before showing the dialog
            app.bringToFront();
            this.dlgMain.center();
            return d.show();
    function CheckVersion() {
        var numberArray = version.split(".");
        if ( numberArray[0] < 9 ) {
            if ( DialogModes.NO != app.playbackDisplayDialogs ) {
                alert( strMustUse );
            throw( strMustUse );
    function FindDialog( inItem ) {
        var w = inItem;
        while ( 'dialog' != w.type ) {
            if ( undefined == w.parent ) {
                w = null;
                break;
            w = w.parent;
        return w;
    // Function: objectToDescriptor
    // Usage: create an ActionDescriptor from a JavaScript Object
    // Input: JavaScript Object (o)
    //        object unique string (s)
    //        Pre process converter (f)
    // Return: ActionDescriptor
    // NOTE: Only boolean, string, number and UnitValue are supported, use a pre processor
    //       to convert (f) other types to one of these forms.
    // REUSE: This routine is used in other scripts. Please update those if you
    //        modify. I am not using include or eval statements as I want these
    //        scripts self contained.
    function objectToDescriptor (o, s, f) {
        if (undefined != f) {
            o = f(o);
        var d = new ActionDescriptor;
        var l = o.reflect.properties.length;
        d.putString( app.charIDToTypeID( 'Msge' ), s );
        for (var i = 0; i < l; i++ ) {
            var k = o.reflect.properties[i].toString();
            if (k == "__proto__" || k == "__count__" || k == "__class__" || k == "reflect")
                continue;
            var v = o[ k ];
            k = app.stringIDToTypeID(k);
            switch ( typeof(v) ) {
                case "boolean":
                    d.putBoolean(k, v);
                    break;
                case "string":
                    d.putString(k, v);
                    break;
                case "number":
                    d.putDouble(k, v);
                    break;
                default:
                    if ( v instanceof UnitValue ) {
                        var uc = new Object;
                        uc["px"] = charIDToTypeID("#Pxl"); // pixelsUnit
                        uc["%"] = charIDToTypeID("#Prc"); // unitPercent
                        d.putUnitDouble(k, uc[v.type], v.value);
                    } else {
                        throw( new Error("Unsupported type in objectToDescriptor " + typeof(v) ) );
        return d;
    // Function: descriptorToObject
    // Usage: update a JavaScript Object from an ActionDescriptor
    // Input: JavaScript Object (o), current object to update (output)
    //        Photoshop ActionDescriptor (d), descriptor to pull new params for object from
    //        object unique string (s)
    //        JavaScript Function (f), post process converter utility to convert
    // Return: Nothing, update is applied to passed in JavaScript Object (o)
    // NOTE: Only boolean, string, number and UnitValue are supported, use a post processor
    //       to convert (f) other types to one of these forms.
    // REUSE: This routine is used in other scripts. Please update those if you
    //        modify. I am not using include or eval statements as I want these
    //        scripts self contained.
    function descriptorToObject (o, d, s, f) {
        var l = d.count;
        if (l) {
            var keyMessage = app.charIDToTypeID( 'Msge' );
            if ( d.hasKey(keyMessage) && ( s != d.getString(keyMessage) )) return;
        for (var i = 0; i < l; i++ ) {
            var k = d.getKey(i); // i + 1 ?
            var t = d.getType(k);
            strk = app.typeIDToStringID(k);
            switch (t) {
                case DescValueType.BOOLEANTYPE:
                    o[strk] = d.getBoolean(k);
                    break;
                case DescValueType.STRINGTYPE:
                    o[strk] = d.getString(k);
                    break;
                case DescValueType.DOUBLETYPE:
                    o[strk] = d.getDouble(k);
                    break;
                case DescValueType.UNITDOUBLE:
                    var uc = new Object;
                    uc[charIDToTypeID("#Rlt")] = "px"; // unitDistance
                    uc[charIDToTypeID("#Prc")] = "%"; // unitPercent
                    uc[charIDToTypeID("#Pxl")] = "px"; // unitPixels
                    var ut = d.getUnitDoubleType(k);
                    var uv = d.getUnitDoubleValue(k);
                    o[strk] = new UnitValue( uv, uc[ut] );
                    break;
                case DescValueType.INTEGERTYPE:
                case DescValueType.ALIASTYPE:
                case DescValueType.CLASSTYPE:
                case DescValueType.ENUMERATEDTYPE:
                case DescValueType.LISTTYPE:
                case DescValueType.OBJECTTYPE:
                case DescValueType.RAWTYPE:
                case DescValueType.REFERENCETYPE:
                default:
                    throw( new Error("Unsupported type in descriptorToObject " + t ) );
        if (undefined != f) {
            o = f(o);
    // Function: SizeInfo
    // Usage: object for holding the dialog parameters
    // Input: <none>
    // Return: object holding the size info
    function SizeInfo() {
        this.height = new UnitValue( 0, "px" );
        this.width = new UnitValue( 0, "px" );
        this.limit = false;
    // Function: NumericEditKeyboardHandler
    // Usage: Do not allow anything except for numbers 0-9
    // Input: ScriptUI keydown event
    // Return: <nothing> key is rejected and beep is sounded if invalid
    function NumericEditKeyboardHandler (event) {
        try {
            var keyIsOK = KeyIsNumeric (event) ||
                          KeyIsDelete (event) ||
                          KeyIsLRArrow (event) ||
                          KeyIsTabEnterEscape (event);
            if (! keyIsOK) {
                //    Bad input: tell ScriptUI not to accept the keydown event
                event.preventDefault();
                /*    Notify user of invalid input: make sure NOT
                       to put up an alert dialog or do anything which
                             requires user interaction, because that
                             interferes with preventing the 'default'
                             action for the keydown event */
                app.beep();
        catch (e) {
            ; // alert ("Ack! bug in NumericEditKeyboardHandler: " + e);
    //    key identifier functions
    function KeyHasModifier (event) {
        return event.shiftKey || event.ctrlKey || event.altKey || event.metaKey;
    function KeyIsNumeric (event) {
        return  (event.keyName >= '0') && (event.keyName <= '9') && ! KeyHasModifier (event);
    function KeyIsDelete (event) {
        //    Shift-delete is ok
        return ((event.keyName == 'Backspace') || (event.keyName == 'Delete')) && ! (event.ctrlKey);
    function KeyIsLRArrow (event) {
        return ((event.keyName == 'Left') || (event.keyName == 'Right')) && ! (event.altKey || event.metaKey);
    function KeyIsTabEnterEscape (event) {
        return event.keyName == 'Tab' || event.keyName == 'Enter' || event.keyName == 'Escape';
    // End Fit Image.jsx

    With Photoshop CS5 you can use Image Processor Pro and this should do what you require...
    http://blogs.adobe.com/jnack/2011/05/new-image-processor-pro-script-for-cs5.html

Maybe you are looking for

  • Can I install a DVDRW drive on my Satellite Pro A10?

    I would like to upgrade the DVD ROM/CDRW drive (SD-R2412) on my Satellite Pro A10 to a DVDRW drive so I can burn DVDs. I have purchased a Toshiba DVDRW drive (TS-L632), as it is exactly the same size and shape as the existing DVD ROM drive, the same

  • I have a virus, how can I remove it

    All of the sudden I have all of these pop ups.  I think that this virus has even invaded my campus email?  What is the best way to scan my computer (free) and remove this?

  • Syntax for previous months data

    For some reason I cannot get the syntax of the previou month correct. Here is what I have used. ("Date"."Calendar Month" IN (SELECT case when 1=0 then "Date"."Calendar Month" else timestampadd (sql_tsi_month, -1, current_date) end FROM "RProBIEE")) H

  • Webmail services as alternative to Thunderbird?

    Are there any webmail providers that come to close to the functionality provided by Thunderbird? Here are my requirements: - The ability to display a list of shared accounts/mailboxes, and to be able to very easily access those mailboxes - The abilit

  • Please Help- 2 ipods in need of serious help

    Thanks for taking the time to look and help. I recently updated itunes (is it to 6.01?) Anyhow since doing this my ipod is not recognised and comes up with the following message.... When you open iTunes, this message appears, "The software required f